Reading time: about 20 minutes. State of play on 31 October 2026: prices, versions and defaults have changed several times this year, so every figure is dated.
Transparency note. This work was carried out on a personal basis, for learning purposes, with the help of an AI:
- for the code and the technical and methodological review;
- to understand the tools and the mathematical methods;
- for help with writing, translating and correcting the text;
- to generate the cover image of the post.
The choice of topic, the protocol, the checking of the results and the conclusions are mine, and so are any mistakes. How I use AI
In my way of working with Claude Code, the
agent runs in my laptop’s terminal. That’s enough as long as I stay at the keyboard. As soon as a
task runs long, you want to follow it from a phone, or run several agents in parallel, the laptop
becomes the constraint: it goes to sleep, it holds my keys and documents, and a misplaced
rm -rf is expensive there.
This article gathers what I took away from looking into the question: the Claude Code documentation, vendor guides (Doppler, Tailscale), hosting price lists and community write-ups. It targets a data scientist or MLOps engineer based in France, hence European hosting. Sources are at the end.
In short. The setup that emerges combines three machines with distinct roles:
- A European CPU VPS dedicated to the agent, reachable only over a private network (Tailscale), used through tmux, disposable and backed up by snapshots.
- A separate production machine, deployed by CI, never by the agent.
- GPUs rented by the hour, started by a script when training needs one.
Secrets are injected at runtime by a manager (Doppler or equivalent), read-only and time-limited. Expect €25 to €130 a month depending on use, agent subscription included, which makes up 70 to 90% of the bill.
Why run an agent on a VPS#
| Need | What the VPS brings |
|---|---|
| Long, persistent sessions | The agent keeps going when the laptop sleeps; tmux keeps the state |
| Asynchronous work | Start a task, walk away, get a notification |
| Mobile access | SSH (Termius, Blink) over Tailscale, or Remote Control from the Claude app |
| Isolation from the personal machine | An rm -rf or a malicious dependency hits the VPS, not your keys or documents |
| Autonomous mode | A disposable environment, restorable from a snapshot |
| Parallelism | Several agents in tmux windows or worktrees, without overloading your machine |
| Closeness to production | Same Docker images, same architecture |
Two 2026 changes shift the picture:
- Remote Control (February 2026) lets you drive, from the mobile app or claude.ai/code, a Claude Code session running on the VPS. The session only makes outbound HTTPS requests: no port to open. Limits: one remote connection per session, a terminal that must stay open, and expiry after about 10 minutes without network.
- Auto mode by default (14 August 2026) replaces the permission prompt at every step with a
classifier that reviews actions. In an Anthropic test with 1,053 testers, human review caught
13.6% of dangerous commands, auto mode 89%.
permissions.denyandaskrules apply before the classifier. Since v2.1.302, headless runs (claude -p) start in manual mode: you have to pass--permission-mode autoexplicitly.
Auto mode reduces the need to run the agent with no permissions at all (“YOLO mode”), but it remains a probabilistic filter. It doesn’t replace isolation, which is what the rest is about.
The choices that shape the setup#
Twelve ideas come up from one source to the next. I treat them as a coherent whole rather than as rules: each answers a specific risk, and you can relax one knowing what you give up.
- The VPS is a disposable workstation. What matters lives in git, in the secrets manager and in external backups; the machine can be rebuilt in a quarter of an hour.
- The agent’s machine and production are separate. The agent can break its VPS, not production.
- No public port without a reason. Tailscale or WireGuard for access, Cloudflare Tunnel or a reverse proxy for what must be public.
- Autonomy is paid for in isolation.
--dangerously-skip-permissionsonly in a container or VM with no valuable secret; elsewhere, auto mode and sandbox. - Secrets are injected at runtime, scoped, read-only, time-limited. The agent never fills in its own secrets.
- The “lethal trifecta” is broken: private data, untrusted content and external communication are not brought together without a network guard.
- Persistence is handled at the terminal level: tmux or zellij, mosh for unstable networks, Remote Control as an option.
- Parallelise with worktrees, not copies: one agent per branch, a human who reviews the diffs.
- Notifications replace watching: Stop and Notification hooks to ntfy or Telegram.
- CPU runs all the time, GPU on demand. Renting a GPU around the clock to write code isn’t worth it.
- Deployment stays boring: Compose, a self-hosted PaaS or Kamal, with CI. No improvised
docker runby the agent in production. - Everything is dated. Prices, versions and defaults change every quarter.
The overall architecture#
flowchart TD
T["Phone or laptop
Termius · mosh · VS Code Remote-SSH · Remote Control"]
T -->|Tailscale| A
subgraph A["Agent VPS · EU · no public port"]
direction TB
A1["non-root user · tmux · worktrees"]
A2["Claude Code: auto mode + sandbox"]
A3["Doppler: dev_agent config, read-only token"]
A4["Docker · uv · MLflow"]
A5["hooks → private ntfy · snapshots + restic → S3"]
A1 ~~~ A2 ~~~ A3 ~~~ A4 ~~~ A5
end
A -->|"git push (token scoped to the repo)"| G["GitHub + Actions
tests · build · PR review · registry"]
G -->|"deploy via Kamal / Coolify / Compose"| P["Production VPS · separate
Caddy · FastAPI API · database · Uptime Kuma"]
A -.->|"start script"| GPU["Hourly GPU · Scaleway L4/L40S
training → MLflow → automatic shutdown"]
The key point of the diagram: no arrow goes from the agent’s VPS to production. Code goes through git and CI, which alone holds the deployment key.
Choosing a VPS#
2026 was a year of price rises, attributed to the cost of RAM and disks. Hetzner raised its cloud prices twice (1 April and 15 June); OVHcloud took its VPS-1 from €4.49 to €6.49 before launching a “VPS 2027” range; Scaleway and netcup raised prices too.
Entry-level comparison#
| Provider | Plan | Indicative price (Oct. 2026) | Location | Notes |
|---|---|---|---|---|
| Hetzner | CX23: 2 vCPU, 4 GB, 40 GB | €5.49/month excl. VAT (excl. IPv4) | Germany, Finland | Best price per GB of RAM; CX/CAX ranges often out of stock |
| Hetzner | CAX11 (Arm): 2 vCPU, 4 GB | €5.99/month | Germany, Finland | Check Arm support for Python and ML wheels |
| OVHcloud | VPS-1 2027: 2 vCores, 4 GB, 40 GB NVMe | €3.81 to €4.49 excl. VAT depending on commitment | France | Daily backup included |
| OVHcloud | VPS-2: 6 vCores, 12 GB, 100 GB | ≈ €11.99 excl. VAT | France | Good candidate for several agents plus MLflow |
| Scaleway | DEV1-M | ≈ €14.74 excl. VAT, storage extra | Paris, Amsterdam, Warsaw | Hourly GPUs in the same account |
| Hostinger | KVM 1/2, Claude Code template preinstalled | Promotions; renewal ×2 to ×3 | Several, incl. EU | Simplest to start; official MCP server; average performance |
| DigitalOcean, Vultr, Linode | 1 vCPU, 2 GB | ≈ $12/month (DO) | Frankfurt, Amsterdam, Paris | Pricier for the same RAM, excellent API |
| Contabo | Large VPS | Very low | Germany | Lots of RAM; uneven I/O and support according to the community |
| Oracle Free Tier | Arm Ampere | €0 | Frankfurt, Paris, Marseille | Capacity hit-and-miss; ill-suited as a main workstation |
Sources disagree on some prices (CX23, the OVH 2027 range): treat them as orders of magnitude and check the official price list before ordering. The renewal price matters more than the promotional one.
Sizing#
- One agent, web development or light Python: 2 vCPU, 4 GB, 40 GB. Watch Claude Code’s memory
with
htop. - Two to four agents in parallel: 4 to 8 vCPU, 8 to 16 GB, 80 to 160 GB NVMe.
- Data science (pandas, scikit-learn, LightGBM): at least 16 GB. RAM is almost always the limiting factor.
- With a PaaS on the same machine: Coolify or Dokploy need at least 2 GB more.
- Disk: Docker images, uv environments and datasets fill 40 GB in a few weeks. A separate volume or S3 storage avoids running out.
Location and GDPR#
A VPS with a European provider keeps data at rest in the EU, outside US extraterritorial laws. But the code and excerpts the agent reads go to the model’s API (Anthropic, OpenAI, Google), wherever the VPS sits: European hosting doesn’t settle that transfer. For real personal data, the options are to work on pseudonymised or synthetic samples, to check your plan’s data retention (Zero Data Retention options on Team and Enterprise), or to use a self-hosted model.
GPUs on demand#
| Option | Price (Oct. 2026) | Use |
|---|---|---|
| Scaleway L4 24 GB | from €0.79/h | Inference of quantised 7-8B LLMs, vision, light LoRA |
| Scaleway L40S 48 GB | from €1.46/h | Heavier inference, image generation |
| Scaleway H100 PCIe | ≈ €2.73/h | Serious training |
| Modal | per second | One-off GPU jobs from Python |
| GPU rented by the month | L4 around the clock ≈ €577/month | Rarely worth it solo |
Twenty hours of L4 a month cost about €16, against nearly €580 for a permanent instance. The agent’s VPS stays on CPU; the agent writes the scripts that start the GPU instance, run training, log to MLflow, then shut the instance down.
Setup and security#
Basic hardening#
- a non-root user with sudo; the agent runs as that user, never as root;
- key-only SSH:
PasswordAuthentication no,PermitRootLogin no; - UFW denying incoming connections by default; SSH is then only allowed on the
tailscale0interface; - fail2ban while SSH is still exposed, unattended-upgrades for security patches;
- Tailscale or WireGuard for access; Cloudflare Tunnel, Caddy or Traefik on 80/443 for what must be public;
- a snapshot before every big autonomous session, and external backups (restic or borg to S3).
The matching install sequence, for Ubuntu 24.04 (to adapt):
# --- As root, once ---
adduser dev && usermod -aG sudo dev
mkdir -p /home/dev/.ssh && cp ~/.ssh/authorized_keys /home/dev/.ssh/ && chown -R dev:dev /home/dev/.ssh
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/; s/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart ssh
apt update && apt -y upgrade
apt -y install ufw fail2ban unattended-upgrades tmux mosh git curl jq bubblewrap socat
dpkg-reconfigure -plow unattended-upgrades
ufw default deny incoming && ufw default allow outgoing && ufw allow OpenSSH && ufw --force enable
# --- Private network ---
curl -fsSL https://tailscale.com/install.sh | sh && tailscale up --ssh
# Once the connection over the Tailscale IP is confirmed:
ufw allow in on tailscale0 && ufw delete allow OpenSSH
# --- As dev ---
curl -fsSL https://claude.ai/install.sh | bash # Claude Code
curl -LsSf https://astral.sh/uv/install.sh | sh # Python/uv
# Doppler: dev_agent_claude config, read-only expiring token,
# then: doppler configure set token <token> --scope .
# In the project: /sandbox, deny rules (~/.ssh, push --force, infra/prod)
tmux new -s project "doppler run -- claude"The order of the two Tailscale lines matters: public SSH access is only removed once the connection over the private network is confirmed to work, otherwise you lock yourself out.
Authenticating the agent#
Claude Code installs with the official script, then claude and /login. If OAuth fails for lack
of a browser on the server, an ssh -L 15735:localhost:15735 user@vps tunnel from the laptop works.
An API key never goes in .bashrc; without a secrets manager, a chmod 600 file loaded by the
service.
Secrets#
Doppler’s guide for Claude Code spells out a practice that carries over to other managers:
- a configuration reserved for the agent, derived from the development environment (for example
dev_agent_claude), with only the secrets the task needs; - the agent never creates or edits its own secrets;
- a read-only, expiring service token, scoped to the directory (
--scope .); - launching through
doppler run: secrets become environment variables and vanish when the process ends; - Doppler’s MCP server, if used, with that same token and
--read-only; - never live credentials: development and test only.
Alternatives are Infisical (open source), 1Password CLI (op run), sops with age, or the network
secrets of Claude Code on the web.
env). The manager
shortens lifetime, narrows scope and prevents file leaks, but doesn’t stop a compromised agent from
exfiltrating what it sees. Hence network filtering and low-privilege tokens: a GitHub token scoped
to one repository, a test database.Prompt injection and exfiltration#
In June 2025 Simon Willison named the “lethal trifecta”: private data, untrusted content,
external communication. Meta’s “Rule of Two” (October 2025) follows from it: never more than two
of the three in one session. A coding agent combines all three by default: the repository and its
secrets, READMEs, issues and dependencies written by others, and curl or git push to talk to the
outside.
Concrete levers to break at least one branch:
- Claude Code’s native sandbox (Linux:
sudo apt-get install bubblewrap socat, then/sandbox). It isolates files and network through a domain allow-list proxy. Two traps: if the sandbox fails to start, Claude Code carries on without it with a mere warning; and thedangerouslyDisableSandboxescape hatch exists. Check at startup, and forbid it if needed (documentation). @anthropic-ai/sandbox-runtimewraps the whole process, MCP and hooks included, with network and writes denied by default.- A container or devcontainer with a network policy and seccomp; for kernel-level isolation, gVisor or a separate VM.
- Codex CLI:
workspace-writemode cuts the network by default;--yolomeans--dangerously-bypass-approvals-and-sandbox. - MCP hygiene: don’t put an MCP that reads outside content (mail, tickets, web) in the same session as an MCP that holds secrets or write access.
The isolation ladder#
| Level | Implementation | When |
|---|---|---|
| 0 | Agent directly on the VPS, manual mode | Getting started |
| 1 | Auto mode, bubblewrap sandbox, deny rules | Everyday use |
| 2 | Agent in a container with no production secrets, filtered network | Autonomous mode, long tasks |
| 3 | Disposable VM or VPS per project, or microVM (E2B, Firecracker) | Untrusted code, several clients |
| 4 | Managed cloud sandbox (Claude Code on the web, None or Trusted network) | Asynchronous tasks from mobile |
Level 1 covers most everyday use; you move up a notch when you drop permissions or when the code comes from outside.
Day-to-day work#
Persistence and access#
- tmux is the standard: one session per project,
tmux attach -t project. Dedicated configs (for example tmux-claude-code) enableallow-passthrough onand a highhistory-limit. - zellij as a modern alternative, mosh to survive the phone switching networks.
- On mobile: Termius, Blink or Echo on the Tailscale address, or Remote Control
(
claude remote-controlor/rc) for chat access from the Claude app. - VS Code Remote-SSH or remote Cursor to review diffs and open the VPS’s notebooks without exposing JupyterLab.
Parallelising#
git worktree add ../project-feature-x feature-x gives each agent its own directory and branch, in
its own tmux window, with separate dev ports and PRs reviewed by a human. Two agents in the same
working directory trip over each other. Subagents parallelise within a task; worktrees, across
tasks.
Context and automation#
- CLAUDE.md or AGENTS.md: test commands, conventions, prohibitions (“never touch
infra/prod”). In auto mode, this file also feeds the classifier: it is part of the security policy. - Hooks:
PreToolUseto block,StopandNotificationto alert through ntfy (claude-ntfy-hook), on a hard-to-guess topic or a self-hosted ntfy. - MCP: the bare minimum, read-only. A Coolify or Dokploy MCP that drives production from the agent’s VPS cancels the separation.
- Headless:
claude -p "…" --permission-mode autofrom cron or a systemd timer, for a drift report or a dependency update. - Claude Code on the web and routines:
claude --cloudand/schedule, with a None, Trusted, Custom or Full network level (documentation). - GitHub Actions: the Claude Code action or
codex execfor PR review, with minimally scoped tokens.
For a data and MLOps profile#
- Environments: uv and a base Docker image shared by development and production.
- Data: S3 object storage (Scaleway, OVHcloud); DVC or lakeFS if datasets change.
- Experiment tracking: MLflow on the VPS (SQLite or Postgres, artefacts on S3), reachable over Tailscale only. The agent logs its runs there, which leaves an auditable trail.
- Pipelines: Prefect, Dagster, or a Makefile or
just. - Notebooks: the agent writes tested modules; notebooks stay for exploration, as jupytext or Marimo, easier to edit and to review as diffs.
- Light serving: FastAPI or BentoML on CPU (scikit-learn, LightGBM, ONNX Runtime); quantised LLMs on hourly GPUs (vLLM).
Deploying#
Same VPS or a separate one?#
The same VPS is defensible for a prototype or staging. Once there are real users or real data, separating machines costs €5 to €10 a month, little against the risk of an agent restarting containers or reading production secrets.
Self-hosted tools#
| Tool | Licence | Recent version | Model | For whom |
|---|---|---|---|---|
| Docker Compose + Caddy | free | — | Versioned files, automatic HTTPS | Simplest; 1 to 3 ML services |
| Coolify | Apache-2.0 | v4.4.6 (9 Oct. 2026) | Web panel, Traefik, one-click apps | A “Heroku at home” |
| Dokploy | Apache-2.0 + proprietary part | v0.30.8 (29 Sept. 2026) | Web panel, Swarm, Traefik | Compose projects, clustering needs |
| Kamal | MIT | v2.12.0 (18 June 2026) | CLI + YAML, SSH deployment, no panel | Minimal attack surface |
| CapRover, Dokku | Apache-2.0 / MIT | — | Swarm, Heroku-style | Small machines |
A comparison counts, in 2026, 61 GitHub security advisories for Coolify (16 critical) and 56 for Dokploy (33 critical), against none for Kamal and CapRover. An admin panel therefore belongs behind Tailscale, and kept up to date.
The deployment chain#
- The agent pushes a branch.
- CI (GitHub Actions) tests, builds the image and pushes it to a registry.
- CI deploys (Kamal, a Coolify or Dokploy webhook, or
docker compose pull && up -dwith a restricted deploy key); the agent doesn’t deploy from its VPS. - A reverse proxy (Caddy, Traefik or Nginx) serves the application.
- Observability follows: Uptime Kuma, logs (Loki or
docker logs), metrics (Prometheus and Grafana, or Netdata); on the ML side, latency, errors and input drift (Evidently). - Production backups go to S3, and restoring them is tested.
Alternatives to a VPS#
| Option | Strengths | Weaknesses | Indicative cost | When to choose it |
|---|---|---|---|---|
| VPS dedicated to the agent | Control, persistence, fixed price, EU | Admin and security are on you | €5 to €15/month | Daily use, technical profile |
| Local machine | Zero latency, local GPU, free | Sleep, weak isolation, no async | €0 | Interactive exploration, with sandbox |
| Home server, mini-PC | Lots of RAM, consumer GPU | Electricity, residential IP, home network exposed | €300 to €1,000 upfront | Large RAM or GPU needs |
| Claude Code on the web | Nothing to administer, mobile, routines | Depends on GitHub, constrained environment | Included in the subscription | Well-scoped async tasks |
| Codespaces, Gitpod/Ona, Coder | Standardised devcontainers, teams | Hourly billing, long sessions expensive | Variable | Teams, onboarding |
| E2B, Daytona | microVMs, fast start, SDK | Built for products, not a dev workstation | ≈ $0.05/vCPU-h | Building an agent |
| Modal | GPU per second, Python-native | CPU sandbox 3 times pricier than functions | ≈ $0.14/core-h | One-off GPU jobs |
| Fly.io Machines/Sprites | Fast start, pay as you go | Less EU/GDPR-oriented | ≈ $0.04/CPU-h | Ephemeral environments |
For an individual, a VPS remains the most flexible base; managed sandboxes complement it for async work, GPUs or a product.
What it costs#
Claude subscriptions in October 2026: Pro at $20/month, Max 5x at $100, Max 20x at $200, Claude Code included with shared limits (a 5-hour window and a weekly cap). Some sources describe a restructuring into “Max $100 / Ultra $200”: the official price list is the reference.
| Scenario | Agent | Agent VPS | Production | GPU | Indicative total |
|---|---|---|---|---|---|
| Getting started | Pro $20 | ≈ €4 to €5.5 | — | — | ≈ €25/month |
| Regular solo data scientist | Max 5x $100 | 8-12 GB, €10 to €15 | €5 to €6 | 20 h of L4 ≈ €16 | ≈ €120 to €130/month |
| Heavy use, several agents | Max 20x $200 (+ another agent) | 16 GB, €20 to €30 | ≈ €10 | 50 h of L4 ≈ €40 | ≈ €250 to €300/month |
Excluding VAT, with $1 ≈ €0.9. The subscription makes up 70 to 90% of the bill: saving a few euros on the VPS matters little, forgetting a GPU that’s running matters a lot.
Common pitfalls#
- an agent running as root on the production machine, next to the panel, the database and the secrets;
- the production
.envcopied onto the agent’s VPS, or keys in.bashrc; - a sandbox you believe is active when it disabled itself for lack of bubblewrap or socat;
--dangerously-skip-permissionsoutside a disposable container, or blanket “allow” rules (Bash(*));- JupyterLab, MLflow, ttyd or the Coolify panel on the public IP, even behind a password;
- a public ntfy topic carrying code summaries;
- a GPU instance left running, for lack of a
trapor an automatic shutdown timeout; - two agents in the same directory instead of two worktrees;
- backups never tested by restoring them;
- a VPS picked on its promotional price without looking at renewal;
- “external content reader” and “secret holder” MCPs in the same session;
- a
claude -pcron job assumed to run in auto mode, when it has started in manual mode since v2.1.302.
My checklist#
Choices
- European provider, at least 4 GB of RAM (8 to 16 GB for data or several agents), renewal price checked.
- Separate production VPS; GPUs rented by the hour.
Hardening
- Non-root user, key-based SSH, root disabled.
- UFW denying by default, SSH over Tailscale only, fail2ban, unattended-upgrades.
- No admin service on the public IP.
Agent
- bubblewrap and socat installed,
/sandboxactive and checked. - Auto mode (or manual for sensitive work), explicit deny rules, no-permission mode only in a disposable container.
- CLAUDE.md or AGENTS.md with commands, conventions and prohibitions.
- Minimal, read-only MCPs, no trifecta.
- Headless scripts with an explicit
--permission-mode.
Secrets
- Secrets manager, agent-specific config, read-only expiring token.
- No production secret on the agent’s VPS; minimally scoped tokens.
Workflow
- tmux or zellij and mosh, mobile client over Tailscale.
- One worktree per agent, human review of PRs.
- Notifications on a private topic.
- Private MLflow, artefacts on S3, reproducible uv environments.
Deployment and operations
- CI that tests and builds; deployment goes through CI.
- HTTPS reverse proxy, monitoring, logs.
- Snapshots before autonomous sessions; backups tested by restoring them.
- Quarterly review of prices, versions and defaults.
Caveats#
- Dates. State as of 31 October 2026; prices, ranges and defaults changed several times this year.
- Fact or practice. The tmux configs, ntfy tools, Marimo and jupytext, the preference for Kamal and the views on Contabo and Oracle are community practice. The auto mode figures come from Anthropic.
- Secondary sources. Several prices come from aggregators that sometimes contradict each other; the Coolify and Dokploy security advisory counts come from a single comparison.
- Coverage. Codespaces, Gitpod/Ona, Gemini CLI, Cursor, OpenCode and Aider were not examined in detail; the isolation, secrets and network principles apply to them in the same way.
Sources#
- Hostinger: Claude plugin
- Hostinger: installing Claude Code on a VPS
- Doppler: agents and Claude Code
- Claude Code: sandboxing
- Claude Code: sandbox environments
- Claude Code: secure deployment (Agent SDK)
- Claude Code on the web
- Claude Code: cloud environments
- Claude Code: routines
- Anthropic: auto mode
- Help Net Security: auto mode
- VentureBeat: Remote Control
- Hetzner: price adjustment
- stackvaluelab: Hetzner price increase 2026
- zen-cloud: OVH price increase 2026
- Scaleway: choosing the right GPU
- Qovery: GPU pricing comparison 2026
- The lethal trifecta for coding agents
- AI coding CLI sandbox modes compared
- NetworkChuck: remote-claude-code
- Claude Code on a VPS guide (Medium)
- pethost: Coolify vs Dokploy vs CapRover vs Dokku
- haloy: self-hosted deployment tools compared
- Fly.io: AI sandbox pricing
- ssdnodes: Claude plans



