VPS Snaps

Agent

The connection goes the other way

Some machines have no inbound route and should not have one. Run a small Docker container on them instead: it dials out to VPS Snaps, holds the line, and does the work locally when told to.

Back up your first server free, forever. No credit card required.

We only use your email to create your account. See our Privacy Policy.

Nothing on your side is listening

Every other way of backing up a server starts with letting something in. This one starts with a process that goes out, which is why it works behind a NAT gateway, inside a VPN, or in a VPC with no route from the internet at all.

Your network

Behind NAT, a VPN or a private VPC. No public IP.

vpssnaps-agent

ghcr.io/wantabit/vpssnaps-agent

Databases
Docker volumes
Files
1Outbound only
wss://vpssnaps.com/agent-wsTLS on 443
2
Run instructions come back down the same socket

VPS Snaps

Agent relay

  • Holds the connection your agent opened
  • Sends one instruction when a schedule fires
  • Records the logs and the result
3

The archive goes straight to your storage. A direct upload from inside your own network to your own S3-compatible bucket. The backup data does not pass through VPS Snaps at any point.

Your bucket

VPS Snaps → your server — the arrow that is missing on purpose. We never initiate a connection to your infrastructure, which means there is no inbound rule to add, no allowlist to maintain, and nothing for anyone to get wrong later.

Register it, then run one container

Name an agent in the dashboard and you get a token, shown once, the way an API key is. Everything after that is a single docker run on the machine you want protected.

docker run

The dashboard hands you this command with your real token already substituted in, so in practice it is a copy and a paste.

docker run -d --name vpssnaps-agent --restart unless-stopped \
  -e VPSSNAPS_AGENT_TOKEN="agt_..." \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/wantabit/vpssnaps-agent:latest

docker compose

The same thing, if the machine already runs a compose stack you would rather keep it beside.

services:
  vpssnaps-agent:
    image: ghcr.io/wantabit/vpssnaps-agent:latest
    restart: unless-stopped
    environment:
      VPSSNAPS_AGENT_TOKEN: "agt_..."
    volumes:
      # Only for Docker volume jobs — skip it otherwise
      - /var/run/docker.sock:/var/run/docker.sock
      # Only for File jobs — mount what you want archived, read-only
      - /var/www:/var/www:ro

Three things worth getting right in that command

The agent is a container, and a container sees a different world than its host does. All three of these follow from that one fact, and all three are cheaper to read now than to debug from a run log later.

The Docker socket is optional

Mount /var/run/docker.sock only if this agent will run Docker volume jobs. The agent uses it to start a throwaway alpine container per volume, which is how the volume gets archived without stopping anything. If you only need database or file backups, leave the flag out — a container that cannot reach the Docker socket cannot do anything with it.

File jobs archive what the container can see

tar runs inside the agent container, so a path only exists if you bind-mounted it. Miss one and the run does not fail silently — it logs Path not found, skipping: /var/www and carries on with whatever it did find. Mount the directories read-only at the same paths the job uses and that mismatch disappears.

Database hosts resolve from inside the container

The job’s database host is dialled by pg_dump or mysqldump running in the container, so localhost means the container itself, not the host. Point it at the host’s bridge address, at a service name on a shared Docker network, or run the container with --network host. Both client binaries are already in the image; there is nothing to install.

Read the full step-by-step guide

What crosses the wire

Five kinds of message travel over that one connection. It is worth knowing exactly which, because a backup tool that reaches into your private network deserves more scrutiny than a feature list.

authagent → us
The first thing sent after the socket opens. We SHA-256 the token and look for a matching hash — the raw token is never stored, so there is nothing on our side to leak. Ten seconds to authenticate or the connection is closed.
runus → agent
One backup instruction: the run ID, the job type, the job's configuration, and the storage credentials it needs to upload. Nothing is queued on the agent — it is told what to do when it is time to do it.
logagent → us
Streamed while the work happens, and written into the run's log as it arrives. You watch a private machine's backup progress in the dashboard without having any access to that machine.
reportagent → us
The outcome: success with the object key, the byte count and an MD5 of what was uploaded, or failure with the error message. This is what flips the run's status and fires your notifications.
ping / pongheartbeat, every 30s
The relay pings; the agent answers. A connection that misses its answer is terminated rather than left in place, which is what catches a half-open socket — the failure mode that would otherwise look like a perfectly healthy agent that never runs anything.

The part most vendors would leave out

A run instruction carries real secrets: the database password for that job, and the access key and secret for your storage destination. It has to — the agent is the thing doing the dump and the thing doing the upload, and it cannot do either without them. They are sealed with AES-256-GCM in our database, decrypted only when a run is dispatched, and travel inside the TLS connection the agent itself opened.

That is the trade, stated plainly: the agent is trusted with the credentials for its own jobs, and in exchange the backup data never touches our infrastructure at all.

The Agent is a connection method, not a feature

It does not add backup types — it is the alternative to SSH for reaching three of them. Two job types have no agent path at all, and neither of those is an oversight.

Job typeOver SSHVia the AgentWhat that means here
Database — PostgreSQL, MySQL, MariaDBAvailableAvailablepg_dump or mysqldump runs in the container and pipes through gzip, exactly as it would over SSH.
Docker — volumes and compose filesAvailableAvailable, with a setup requirementNeeds the Docker socket mounted. Each volume is archived by a temporary alpine container; compose files are copied in beside them.
Files — paths and exclude patternsAvailableAvailable, with a setup requirementNeeds the paths bind-mounted into the container. Exclude patterns become --exclude flags on the same tar invocation.
VPS snapshots — seven cloud providersNot applicableNot availableNothing runs on the server at all. We call your provider's API from our side, so a private machine on a supported provider is already covered without an agent.
Kubernetes — namespace manifestsNot applicableNot availableConnect the cluster directly with a service account token. The agent has no Kubernetes code path and will reject the job type outright.

Yes, once the container has what it needs — the Docker socket for volume jobs, the paths bind-mounted for file jobs. Both are covered above.

Because it is a connection method, everything else about the job is unchanged. The same schedule options, the same retention window, the same storage destinations, the same run history and the same alerts on email, Slack, Microsoft Teams, Google Chat and Discord. Switching an existing job from SSH to Agent is a toggle next to the connection picker, not a rebuild. Agent backups are a plan feature — the plan comparison shows which plans include them.

FAQs

Can’t find the answer you’re looking for? Reach out to our support team.

Do I have to open a port or give the machine a public IP?

No, and that is the entire point. The agent opens one outbound TCP connection to vpssnaps.com on port 443 and holds it. Nothing on your side listens, so there is no inbound rule to write, no port to forward and no address to expose. From your firewall's perspective this is an outbound HTTPS session like any other.

What if our egress goes through an HTTP proxy?

Then it needs a direct route. The agent opens a plain WebSocket to the URL in VPSSNAPS_WS_URL — wss://vpssnaps.com/agent-ws by default — and there is no HTTP CONNECT proxy support in it today. In practice an egress allow-rule for that one hostname on 443 is what people add. If your environment truly cannot make a direct outbound connection, the agent is not the right tool for it, and it is better to know that now than after installing it.

How large a backup can the agent handle?

This is the honest limitation of the agent path. It builds the archive in the container's temp directory, then reads the finished file into memory to upload it in one request. So the container needs disk space for the archive and roughly the same again in RAM. SSH-based jobs work differently — those stream the dump or the tar straight through to your bucket without ever staging a file — so for a very large dataset, an SSH job has no equivalent ceiling. For an agent, give the container headroom or split the job into narrower paths.

What happens if the agent is offline when a backup is due?

The dispatch is retried three times with an exponential backoff starting at five seconds. If the agent still is not connected, the run is marked failed with "Agent is not connected. Check that it's running and start it if not" — a message that tells you what to do — and your failure notifications go out on whichever of the five channels you have configured. Meanwhile the agent is trying to come back on its own: it reconnects with a backoff that doubles from one second up to a thirty-second ceiling, so a brief network blip heals itself long before the next scheduled run.

Can one agent back up several machines?

For databases, yes — the dump connects over the network, so a single agent can back up every database it can reach inside the private network. For file and Docker volume jobs, no: the agent archives what is mounted into its own container and what its host's Docker daemon knows about, so those want one agent per machine. Registering another agent is a name and a docker run away.

What does VPS Snaps see of the backup data?

None of it. The agent uploads the archive directly from your network to your S3-compatible bucket, and we are not in that path — what comes back to us over the WebSocket is the object key, the byte count, the checksum, the log lines and the pass or fail. The trade is stated plainly in the section above: to do the work locally, the agent has to be sent the credentials for the job, so the database password and your storage keys travel down that connection.

How do I rotate or replace an agent token?

We store a SHA-256 hash of the token plus its first twelve characters, which is what the dashboard shows you. The raw token is returned exactly once, on the screen where you create the agent, and cannot be recovered afterwards. To rotate, register a second agent, start the container with the new token, and switch the job over to it — jobs reference the agent, so the switch is a dropdown, not a reconfiguration.

Powerful features to give you peace of mind

Rest easy knowing your data and your reputation are safe.

Bring your own storage
Backups land in your own S3-compatible bucket — Backblaze B2, Wasabi, Cloudflare R2, or plain S3. You hold the keys and the data.
Snapshots stay with your provider
Provider snapshots are created through the provider's own API and never leave your account. We store the snapshot ID, not the image.
Seven providers, one dashboard
DigitalOcean, Hetzner, Vultr, Linode, AWS EC2, Google Compute Engine and Microsoft Azure — scheduled and reviewed from the same place.
Schedules that fit your traffic
Hourly, daily, weekly, monthly, or a fixed interval in minutes — anchored to your timezone, so a 02:00 job stays at 02:00 across a DST change.
Retention that prunes itself
Set how many days to keep. Older snapshots and archives are cleaned up after each successful run, so storage bills stay flat.
Step-by-step run logs
Every run records what it did, in order, with warnings and errors kept in place — so a failure tells you which step broke.
Complete run history
Status, duration, byte size, and what triggered each run, kept per job. Proof the backup ran, long after the night it ran.
Checksummed on upload
Every archive is hashed as it streams to your bucket and the checksum is stored with the run, so you can verify what landed.
Run on demand
Trigger any job by hand before a migration or a risky deploy, without touching its schedule or its retention window.
Alerts on five channels
Email plus Slack, Microsoft Teams, Google Chat, and Discord — on success, on failure, and on a job that missed its schedule entirely.
Encrypted credentials
SSH keys, database passwords, and storage secrets are sealed with AES-256-GCM before they touch the database.
Team access with roles
Invite your team into a shared workspace as owner, admin, or member, so backups outlive whoever set them up.
View all features
Daniel Kim
The biggest advantage for us is that VPS Snaps works with the infrastructure we already have instead of forcing us into a proprietary backup environment. Provider snapshots stay inside our cloud account, while database and file archives can go directly into our own bucket.
Daniel KimCloud Infrastructure Engineer

Back up the machine you cannot reach.

Register an agent, run one container on the private machine, and point a database, Docker or file job at it. If the agent shows as connected within a few seconds, the hard part is already over.

No credit card required. Cancel anytime.