Guides · Agents · 23

Run your agents 24/7 on a small server, safely

Rent a small Linux server or use a spare Mac mini, lock it down with SSH keys, a firewall and a private Tailscale network, run your agent in Docker with automatic restarts, and cap what it can spend.

2-3 hoursFrom $6/mo plus API usageAdvanced

An agent on your laptop stops when the lid closes. On a small server it runs all day, but it also holds your API keys on a machine connected to the internet. This guide sets one up the careful way: nothing exposed to the public internet, nothing running as root, and a hard cap on what it can spend.

1Pick where it runs

OptionEntry price (checked October 2026)Good to know
DigitalOcean Basic Droplet$4/mo (512 MiB RAM), $6/mo (1 GiB, 1 vCPU, 25 GiB disk), $12/mo (2 GiB)Billed per second. A powered-off Droplet is still billed: only destroying it stops the charge
Hetzner CloudCX23 at €5.49 ($6.49) a month, excluding VAT and the IPv4 address, in Germany and FinlandPrices changed in June 2026, its Cost-Optimized line showed "Currently not available" when we checked, and in the US the CPX11 plan is $20.49 before VAT
A spare Mac miniNo monthly bill, just power and your home internetIn System Settings > Energy, turn on "Prevent automatic sleeping when the display is off" and "Start up automatically after a power failure"

For most founders, a $6 Droplet is the simple start. OpenClaw's own DigitalOcean guide uses that 1 GB plan, calls it tight, and recommends adding swap and using API-hosted models rather than running a model on the server. If your agent drives a browser or runs several jobs, start at 2 GB. On a Mac mini, skip the Ubuntu commands, keep macOS updates on and install the Tailscale app; the secrets, spend-limit and kill-switch steps still apply.

2Create the server, your own user and key-only logins

Choose the newest Ubuntu LTS image your provider offers and pick SSH key as the login method, never a password. Make the key on your laptop first with ssh-keygen -t ed25519, and paste the contents of ~/.ssh/id_ed25519.pub into the provider when you create the server.

Log in as root once, then create your own user (replace alex)
ssh root@SERVER_IP
adduser alex
adduser alex sudo
mkdir -p /home/alex/.ssh
cp /root/.ssh/authorized_keys /home/alex/.ssh/
chown -R alex:alex /home/alex/.ssh
chmod 700 /home/alex/.ssh
chmod 600 /home/alex/.ssh/authorized_keys

Open a second terminal and run ssh alex@SERVER_IP, then sudo whoami. If it prints root, your user works. From here on, log in as that user, never as root. Don't add yourself to the docker group later: Docker's docs say that group grants root-level access.

Next, turn off password and root logins. Ubuntu reads extra SSH settings from files in /etc/ssh/sshd_config.d/. OpenSSH reads included files in name order and keeps the first value it finds, and recent Ubuntu cloud images can include a 50-cloud-init.conf there. Naming your file 00- puts it first.

Harden SSH (as your new user)
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf <<EOF
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
EOF
sudo sshd -t
sudo sshd -T | grep -Ei 'passwordauthentication|kbdinteractiveauthentication|permitrootlogin'
sudo systemctl restart ssh.service

sshd -t checks the config for errors, and sshd -T prints the settings actually in effect: all three should read no. Keep your current terminal open and test a fresh login in another one before you close it. If you ever lock yourself out, every provider has a web console that works without SSH (DigitalOcean has the Droplet Console and a Recovery Console), so find yours now.

3Turn on automatic security updates

Run sudo apt update, then sudo apt upgrade. On Ubuntu Server, the unattended-upgrades package is installed by default and applies security updates on its own. To confirm, cat /etc/apt/apt.conf.d/20auto-upgrades should show APT::Periodic::Unattended-Upgrade "1";, and each run leaves a log in /var/log/unattended-upgrades. It does not reboot unless you allow it. To allow it, set Unattended-Upgrade::Automatic-Reboot "true"; and Unattended-Upgrade::Automatic-Reboot-Time "04:00"; (server time) in /etc/apt/apt.conf.d/50unattended-upgrades. Docker starts on boot on Ubuntu, and the restart policy in Step 5 brings the agent back.

4Put it on a private network, then close the public door

Tailscale puts your laptop, phone and server on a private network only you can join. Its free Personal plan covers up to 6 users and unlimited user devices. Install it on your laptop from tailscale.com, then on the server:

Join the server to your tailnet
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up            # open the link it prints and sign in
tailscale ip -4              # your server's private 100.x.y.z address

From your laptop, check that ssh alex@100.x.y.z works. In the Tailscale admin console, open Machines, find the server, and choose Disable Key Expiry: by default keys expire after 180 days, and an expired server key cuts you off. Then, from that Tailscale session, make the firewall accept traffic only over Tailscale, so nothing is left on the public internet to attack.

Firewall: allow Tailscale, block everything else inbound (from Tailscale's Ubuntu guide)
sudo ufw allow in on tailscale0
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
sudo ufw delete allow 22/tcp      # only if a public SSH rule exists (see ufw status numbered)
sudo ufw status verbose
# test from your laptop: the public ssh alex@SERVER_IP should now time out, the 100.x one still works

5Run the agent in Docker with restarts and logs

Install Docker Engine with the apt repository steps on Docker's Ubuntu page, copied from the page itself because they change. Check it with sudo docker run hello-world. Then make logs rotate: Docker's default log driver doesn't rotate them, and its docs recommend the local driver.

Two files: rotating logs, and your agent's compose file
# /etc/docker/daemon.json, then run: sudo systemctl restart docker
{ "log-driver": "local" }

# ~/agent/compose.yaml
services:
  agent:
    image: your-agent-image:tag      # from your agent's install docs
    restart: unless-stopped
    env_file: .env
    # no "ports:" section. If it has a dashboard, add only this:
    # ports: ["127.0.0.1:8080:8080"]

Start it with sudo docker compose up -d, check it with sudo docker compose ps, and watch it with sudo docker compose logs -f --tail 100. unless-stopped restarts the agent after crashes and reboots, but not after you stop it yourself. Not using Docker? Many agent tools install their own background service (Hermes Agent has hermes gateway install), or use a systemd service with Restart=on-failure.

6Secrets, spend limits and backups

Keep keys in a locked-down file, never in git
cd ~/agent
nano .env                     # ANTHROPIC_API_KEY=... one key per line
chmod 600 .env                # only your user can read it
echo ".env" >> .gitignore

Docker and systemd both warn that environment variables aren't ideal for secrets, since they can leak into logs. If your agent can read a key from a file, use Docker Compose secrets, mounted at /run/secrets/<name>. Anthropic's own advice: never put keys in code or config files, use separate keys for development and production, and revoke a key immediately if you think it leaked.

Cap the spend in the Claude Console. Standard API tiers come with a monthly spend cap, and you can set your own lower limits:

  1. Settings > Workspaces > Create workspace, named "agents". Create the server's API key inside it.
  2. Select the workspace and click Spend limits to set a monthly cap and alerts. (The Default workspace can't have limits.)
  3. In Settings > Billing, set an organization limit under Spend limits, and check Auto-reload: turn it off if you'd rather top up by hand.

When a limit is hit, API calls fail until next month or until you raise it, so a broken loop costs you your cap, not your runway. Your server bill needs its own alert: DigitalOcean's spend alerts notify you, but they are not a cap. Backups: DigitalOcean backups cost 20% of the Droplet price for weekly or 30% for daily, and snapshots cost $0.06 per GB a month. Turn on weekly backups, and keep a copy of .env in your password manager rather than in a backup.

7Know your kill switch

  1. Revoke the API key. Claude Console, API keys, the three-dot menu next to the key, Delete API Key. Every request with that key then fails. Archiving the whole "agents" workspace also archives every key in it, but it can't be undone.
  2. Stop the agent. sudo docker compose down stops and removes its containers. Named volumes, where agents usually keep data, survive.
  3. Power it off from the provider's dashboard if you can't log in. A powered-off Droplet is still billed, so take a snapshot and destroy it if you're done.
  4. Revoke its other access: its email inbox key, any connectors, and Google access at myaccount.google.com/connections.
Have Claude review your setup
Review my Ubuntu agent server for security problems. Below are the outputs of `sudo ufw status verbose`, `sudo sshd -T` and `sudo docker compose ps`, plus my compose.yaml with secrets removed.
Flag any port open to the public internet, password or root SSH logins, containers without a restart policy, and secrets in files. List them by severity, each with the exact fix command. If you can't judge something from what I pasted, say what else you need.
[paste outputs here]
Before you leave it running0/6

What's next

Give the agent its own email with Agent inbox, then choose what runs on the server: OpenClaw, Hermes Agent, or your own build with the Agent SDK. To give it custom tools, see MCP server.

Get the next lesson in your inbox

Your free AI path in the right order, plus new guides when they come out.

Free. No card. One click to unsubscribe.

Want it done,not just learned?

The AI Skill Pack: 13 ready Claude Skills for your inbox, weekly report, meetings, content, research, proposals and SOPs. Installed in ten minutes. $27, one time.

See the AI Skill PackOr keep going free: everything in one place