Security and Connectivity

Outbound Agent model, NAT compatibility, and control-plane reliability.

tug.sh is designed for secure remote operations without exposing your VPS management surface to inbound internet traffic.

Outbound-only Agent connection

  • The Agent can run behind NAT and with no inbound open ports.
  • Communication is outbound-only from Agent to api.tug.sh over TLS (wss).
  • The UI never connects directly to servers or Agents.
  • The Agent initiates and maintains the control channel; API and UI use that channel.

Workload and tenant isolation

  • Filesystem operations are sandboxed to /var/lib/tug/apps with traversal protection.
  • Account-scoped routing ensures events and commands are isolated per account.
  • API enforces authentication and role-based permissions before command dispatch.

Reliability context vs classic self-hosting

In classic self-hosted setups, the control panel often runs on the same VPS as workloads. If that VPS fails, the panel and alerts fail with it.

In tug.sh, control plane and managed VPS are separated, so incident visibility and notifications can remain available when one managed VPS is down.

Migrating containers between servers

Container migration copies a container from a source VPS to a target VPS. Both agents talk to the control plane over their normal outbound connection, but the actual image transfer is a direct SSH connection from the source machine to the target machine over port 22. The target must therefore be reachable and must accept the one-time key that tug installs for the migration.

Before the transfer starts, tug runs a preflight that logs in over SSH exactly as the migration will. If that login is refused, the migration is stopped with a clear reason instead of failing halfway.

Requirements on the target VPS

  • Reachable on port 22 from the source machine's public IP. A machine behind NAT with no forwarded SSH port cannot be a migration target.
  • sshd accepts key authentication: PubkeyAuthentication yes (the default).
  • The agent user can log in with a key. tug installs the one-time public key into the authorized_keys of the account the target agent runs as. If that account is root, then PermitRootLogin must allow key login — use prohibit-password (or yes), not no.
  • docker is installed and on PATH for the agent user.

"Permission denied (publickey)" during migration

This means the target reached the SSH stage but rejected the one-time key. On the target VPS:

  1. Confirm PubkeyAuthentication yes in /etc/ssh/sshd_config (or a drop-in in /etc/ssh/sshd_config.d/).
  2. If the target agent runs as root, set PermitRootLogin prohibit-password. If it runs as a non-root user, that user's login must not be locked.
  3. Make sure the agent user's ~/.ssh is 0700 and ~/.ssh/authorized_keys is 0600, owned by that user.
  4. Apply changes with sudo systemctl reload sshd (or sudo systemctl restart ssh).

After adjusting sshd, retry the migration.

Works with fresh and existing servers

tug.sh works both on:

  • brand-new, empty VPS instances,
  • already used production VPS instances with running services.

Existing containers can be discovered and managed after Agent connection, so migration can be incremental.