UnattendedClaude Code Guides

Claude Code on VPS: systemd Setup That Survives Reboots

By Aoba Works · Published · Sources checked · 18 min read

How this guide was made: drafted with AI assistance from the official sources linked below, then passed an automated editorial check before publishing. Our process

Yes, Claude Code runs well on a VPS. Install it with Anthropic's native Linux installer, sign in once over SSH, and run your jobs headless with claude -p from a systemd timer. Your agent keeps working with the laptop closed and comes back by itself after a reboot. The parts that usually break are persistence (keeping it alive after reboots), auth tokens stored on the server, and security (SSH and firewall), so most of this guide covers those three.

Which option is right for you?

The right setup depends on how comfortable you are with Linux and whether the work needs files that live on your server.

Which option is right for you?
Your situationWhat to pick firstFirst page to open
Beginner, never managed a Linux serverHostinger's "Ubuntu 24.04 with Claude Code" template on a 4 GB+ plan, because Claude Code comes preinstalledHostinger: How to use the Claude Code VPS template
You already have an Ubuntu or Debian VPSNative installer plus a systemd timer, because it auto-updates and survives rebootsClaude Code advanced setup
Daily recurring work on GitHub repos, no server wantedAnthropic's cloud scheduled tasks, because no server is neededAutomate work with scheduled tasks
Tight budgetSmallest 4 GB KVM plan plus Claude Pro, because 4 GB is the documented minimumClaude pricing
Interactive coding from your phonetmux on the VPS plus Remote Control, because the session stays open between visitsRemote Control docs
You're building a product others will useA Claude Console API key, because Anthropic's terms require it for that useLegal and compliance

Can Claude Code run on a VPS?

Yes. Claude Code is a terminal program, so it runs on any supported Linux VPS over SSH, and claude -p runs it with no interactive terminal.

Anthropic lists the system requirements as Ubuntu 20.04+, Debian 10+ or Alpine Linux 3.19+, "4 GB+ RAM", an x64 or ARM64 processor, and an internet connection (as of October 2026). The model runs on Anthropic's servers, so the VPS only needs room for the Claude Code process, your repository and your test tooling. It doesn't need a GPU or a desktop environment.

Headless mode is what makes unattended work possible. According to the headless docs, adding -p (or --print) to any claude command runs it non-interactively. Claude Code exits with code 0 on success and a non-zero code on failure, so systemd and cron can tell whether a run worked. For example:

claude -p "Run the test suite and summarize failures" --allowedTools "Bash,Read"

Before you put a subscription on a server, read the usage rules. Anthropic's legal and compliance page says "Advertised usage limits for Pro and Max plans assume ordinary, individual usage of Claude Code and the Agent SDK." Your own agent working on your own repos fits that description. Running a service for other users on your Pro or Max login does not. Those users need their own credentials, and Anthropic says products should use Console API keys. The flag reference is in Claude Code Headless Mode: Flags, Auth and Cost (2026).

How do you install Claude Code on a VPS?

Run Anthropic's native installer as a non-root user, then confirm with claude --version.

The command is curl -fsSL https://claude.ai/install.sh | bash, the recommended method in the official setup page. One thing changed from older guides: you no longer need Node.js. Most articles from 2025 tell you to install Node 18 and use npm. According to the setup page, the npm package now requires Node.js 22 or later, and even then it just downloads the same native binary.

  1. SSH into the server: ssh you@203.0.113.10 (example IP).
  2. Create a dedicated user for the agent so it doesn't run as root: sudo adduser --disabled-password --gecos "" agent.
  3. Switch to that user: sudo -iu agent.
  4. Install: curl -fsSL https://claude.ai/install.sh | bash.
  5. Open a new shell (or run exec bash), then check the install: claude --version. A working install prints something like 2.1.211 (Claude Code).
  6. Run claude doctor. It checks the install and your settings without starting a session.
  7. Sign in (see the auth section below).

The native installer puts a launcher at ~/.local/bin/claude and updates itself in the background. On a server you won't watch, consider the stable channel, which runs about a week behind and skips releases with major regressions. Install it with curl -fsSL https://claude.ai/install.sh | bash -s stable, or put "autoUpdatesChannel": "stable" in ~/.claude/settings.json.

Common mistakes:

How do you install Claude Code on an Ubuntu VPS?

On Ubuntu 20.04 or newer, use the native installer. If you'd rather update through apt, use Anthropic's signed apt repository instead. Use npm only if your tooling needs it.

How do you install Claude Code on an Ubuntu VPS?
MethodCommandAuto-updatesPick it if
Native installer`curl -fsSL https://claude.ai/install.sh \bash`Yes, in the backgroundYou want the simplest setup that stays current
apt repositorysudo apt install claude-code (after adding the repo)No, you update with apt upgradeYou want version changes only when you run apt
npmnpm install -g @anthropic-ai/claude-codeOnly if the npm global folder is writableYour existing tooling already manages Node

All three are documented on the Claude Code setup page (as of October 2026).

apt route, step by step (from the official page):

  1. sudo apt install curl gnupg
  2. sudo install -d -m 0755 /etc/apt/keyrings
  3. sudo curl -fsSL https://downloads.claude.ai/keys/claude-code.asc -o /etc/apt/keyrings/claude-code.asc
  4. Check the key: gpg --show-keys /etc/apt/keyrings/claude-code.asc. The fingerprint should be 31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE.
  5. Add the stable repo: echo "deb [signed-by=/etc/apt/keyrings/claude-code.asc] https://downloads.claude.ai/claude-code/apt/stable stable main" | sudo tee /etc/apt/sources.list.d/claude-code.list
  6. sudo apt update && sudo apt install claude-code

Ubuntu pitfalls and fixes:

How do you install Claude Code on a Hostinger VPS?

On Hostinger, the easiest route is to pick the "Ubuntu 24.04 with Claude Code" template, which comes with Claude Code installed. Then sign in over SSH or with the browser terminal.

Hostinger's template guide says you can reach the server with ssh root@[your-vps-ip] or from the Web Console in the Hostinger dashboard, then sign in with claude /login. If you'd rather start from plain Ubuntu, follow the Ubuntu steps above. Nothing about Hostinger changes them.

Plans (from Hostinger's Claude Code hosting page, as of October 2026; check the official page for current prices):

How do you install Claude Code on a Hostinger VPS?
PlanvCPU / RAMIntro priceRenews at
KVM 11 / 4 GB$6.49/mo (24-month term)$11.99/mo
KVM 22 / 8 GB$8.79/mo (24-month term)$14.99/mo
KVM 44 / 16 GB$12.99/mo (24-month term)$28.99/mo

Hostinger's hosting page notes that "All plans are paid upfront", so the monthly figure is the total price divided across the term. KVM 1 meets Anthropic's 4 GB minimum exactly. KVM 2 leaves room for builds and test runners. Hostinger suits beginners who want a preinstalled template and a browser terminal. If you need month-to-month billing at the advertised price, or a data center close to a particular region, compare other providers first.

Steps after the server is ready:

  1. Connect with SSH or the dashboard's Web Console.
  2. The template logs you in as root. Create the agent user (adduser --disabled-password --gecos "" agent) and copy your SSH key into /home/agent/.ssh/authorized_keys.
  3. Run sudo -iu agent, then claude --version. If the command isn't found for this user, run the native installer as agent. The template's copy may only be on root's PATH.
  4. Sign in as agent, not as root.

Hostinger firewall pitfall: the managed firewall lives under Security → Firewall. Click Add Firewall, name it, click Create, then the ⋯ button → Edit, and add rules with Add rule. Hostinger's firewall article warns that "An empty ruleset will block all traffic when applied to a server." Add an accept rule for SSH before you activate the group, or you'll lock yourself out. Hostinger says changes take effect in two minutes or less.

How do you set up Claude Code to run unattended on a VPS?

Use a systemd timer that triggers a service running claude -p.

Keep the auth token in a root-only environment file. This setup survives SSH disconnects (systemd owns the process, not your shell) and reboots (the timer is enabled at boot, and Persistent=true catches up on missed runs). tmux is good for interactive sessions you check on later, but a tmux session doesn't come back after a reboot.

Step 1: Create a long-lived token

On any machine with a browser (your laptop is easiest), run:

claude setup-token

The authentication docs describe this as the method "For CI pipelines, scripts, or other environments where interactive browser login isn't available." The token lasts one year. It prints to the terminal once and isn't saved anywhere, so copy it right away. It requires Pro, Max, Team or Enterprise, and it can only make model requests. It can't start Remote Control sessions.

Alternatives: a Console ANTHROPIC_API_KEY (billed per token through the API). Or run claude interactively on the VPS. Over SSH, the browser can't reach the local callback, so paste the code at the Paste code here if prompted prompt. That login is saved to ~/.claude/.credentials.json with file mode 0600.

Step 2: Store it in a root-only environment file

sudo install -m 600 -o root -g root /dev/null /etc/claude-agent.env
sudo nano /etc/claude-agent.env

Contents (example):

CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-REPLACE_ME

systemd reads EnvironmentFile= before it switches to the agent user. So the agent's processes get the token, but the file stays unreadable to that user's shell and to anything Claude runs as a file read.

Two documented traps:

Step 3: Write the job script

/home/agent/jobs/nightly.sh (example; adjust the paths, prompt and tools):

#!/usr/bin/env bash
set -euo pipefail
cd /home/agent/repos/myapp
git pull --ff-only
claude -p "$(cat /home/agent/jobs/nightly-prompt.md)" \
  --permission-mode acceptEdits \
  --allowedTools "Read,Edit,Bash(npm test *),Bash(git diff *)" \
  --permission-prompts none \
  --max-budget-usd 3 \
  --output-format json > "/home/agent/logs/nightly-$(date +%F).json"

Make it executable with chmod +x. According to the CLI reference, --permission-prompts none needs v2.1.259 or later. It denies anything that would otherwise wait for a person, so the run never hangs on a prompt. The JSON output includes total_cost_usd, which the headless docs describe as a client-side estimate. For safe allow-lists, see Claude Code Permissions Best Practices: Headless Template.

Step 4: Create the service and timer

/etc/systemd/system/claude-nightly.service:

[Unit]
Description=Nightly Claude Code job
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
User=agent
WorkingDirectory=/home/agent/repos/myapp
EnvironmentFile=/etc/claude-agent.env
Environment=PATH=/home/agent/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/home/agent/jobs/nightly.sh
TimeoutStartSec=45min

/etc/systemd/system/claude-nightly.timer:

[Unit]
Description=Run Claude nightly job at 02:30

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=5min

[Install]
WantedBy=timers.target

Then:

  1. sudo systemctl daemon-reload
  2. sudo systemctl start claude-nightly.service (one test run right now)
  3. journalctl -u claude-nightly.service -n 50 (read the result)
  4. sudo systemctl enable --now claude-nightly.timer
  5. systemctl list-timers | grep claude (confirm the next run time)

With Persistent=true, systemd records the last run time on disk. If the server was down when the job was due, the job runs right after boot.

When to use Restart=always instead

Use Restart=always only for a process that should never exit, such as your own chat-bot wrapper that calls Claude Code. systemd restarts it however it exits, and RestartSec defaults to 100ms. If a long-running agent hits a rate limit or an auth error, that default can create a tight restart loop that burns through your usage. Set RestartSec=60 or more. For retry logic around limits, see Claude Code Rate Limit Reached: Retry Setup for Cron Jobs.

Stopping a run: systemctl stop sends SIGTERM, and the headless docs say Claude Code then exits with code 143 and leaves the current turn unfinished. That's fine for a nightly job, but don't read code 143 in your logs as a crash.

How do you connect Claude Code to a VPS?

You connect to the VPS over SSH with a key, then run Claude Code in that remote shell. Claude Code doesn't attach to a server by itself.

  1. On your laptop, create a key if you don't have one: ssh-keygen -t ed25519.
  2. Copy it to the server: ssh-copy-id agent@203.0.113.10 (or paste the .pub file into the provider's SSH key field).
  3. Add a shortcut to ~/.ssh/config (example):

``text Host agentbox HostName 203.0.113.10 User agent IdentityFile ~/.ssh/id_ed25519 ``

  1. Connect with ssh agentbox.

Pick how you work once you're connected:

How do you connect Claude Code to a VPS?
Way of workingHowGood forLimitation
tmux sessiontmux new -s agent, run claude, detach with Ctrl-b then d, come back with tmux attach -t agentLong interactive sessions you check laterLost on reboot
VS Code Remote-SSHConnect to agentbox and use the integrated terminalEditing files next to the agentNeeds a laptop session open
Remote ControlStart from a session signed in with your claude.ai accountChecking in from your phoneDoesn't work with a setup-token token
systemd timerThe setup in the previous sectionRecurring jobs with no one watchingNot interactive

Remote Control keeps running on the machine you started it from and reconnects when that machine is back online. On a VPS that machine never sleeps, which is why people pair it with tmux. To read the output of timer runs, journalctl -u claude-nightly.service and the JSON files in ~/logs cover most needs.

How do you secure a VPS running Claude Code?

Use key-only SSH, a firewall that opens only SSH, and a non-sudo agent user.

Also block root login. An always-on box that can push to your repos and holds a one-year token is a better target than your laptop. Claude Code connects out to Anthropic, so it needs no open inbound port of its own.

SSH hardening

OpenSSH's defaults are PasswordAuthentication yes and PermitRootLogin prohibit-password, so password logins are allowed unless you turn them off.

  1. Make sure your key login works for your sudo user first.
  2. Create /etc/ssh/sshd_config.d/99-hardening.conf:

``text PasswordAuthentication no KbdInteractiveAuthentication no PermitRootLogin no ``

  1. Check the config: sudo sshd -t. Then reload: sudo systemctl reload ssh.
  2. Keep your current session open, and log in from a second terminal before you close it.

Moving SSH to a non-default port cuts down log noise, but it doesn't replace key-only login. On Hostinger, any port change also needs a matching firewall rule.

Firewall

Ubuntu's firewall guide says "ufw by default is initially disabled." Turn it on in this order:

  1. sudo ufw allow OpenSSH
  2. sudo ufw enable
  3. sudo ufw status verbose

If you also use a provider firewall (Hostinger's, for example), both have to allow SSH. If either blocks it, you're locked out.

Agent-level hardening

Copy-paste rule sets are in AI Agent Guardrails Example: Copy-Paste Claude Code Rules.

How do you use Claude Code on a VPS for recurring tasks?

Give each recurring task its own prompt file, script and systemd timer. Then read the JSON output to check whether it worked.

Good jobs for a VPS (examples, not results):

Each prompt should say what "done" looks like and what the agent must not touch. Name the branch it may push to and say which files are off-limits. One timer per job keeps logs separate and lets you pause a job with systemctl disable --now name.timer.

Which scheduler fits?

How do you use Claude Code on a VPS for recurring tasks?
SchedulerSurvives rebootCatches missed runsLocal files on VPSNote
systemd timerYesYes, with Persistent=trueYesMost robust on a VPS
cronYesNoYesSimpler syntax. See Claude Code Cron Job Setup
Anthropic cloud scheduled tasksNot your servern/aNo, it clones GitHub reposResearch preview, runs no more than hourly

Anthropic's scheduled tasks (formerly routines) run on Anthropic's cloud and are available on Pro, Max, Team and Enterprise. They reject cron expressions that run more often than once per hour and cap scheduled runs at 100 per hour per account (as of October 2026). Pick them when the work is only about GitHub repos. Pick the VPS when the work needs a database, local files or tools that only live on your server.

Catch silent failures. An exit code of 0 only means the process finished. Parse the JSON result field and fail the job if the expected output file is missing. Watch for the login-expiry warning, which the auth docs show three days before an interactive login expires. A monitoring setup is in AI Agent Monitoring in Claude Code: Catch Silent Failures.

Usage. Every run draws from the same plan limits as your interactive sessions. Claude Pro is $20/month billed monthly ($17/month on annual billing), and Max starts at $100/month, according to Claude's pricing page (as of October 2026; check the official page). If nightly jobs keep reaching the limit, cut the prompt's scope before you upgrade.

Next steps

Three things you can do today:

  1. Install Claude Code as a non-root agent user on your VPS, then run claude --version and claude doctor.
  2. Generate a token with claude setup-token, put it in /etc/claude-agent.env with mode 600, and turn on key-only SSH plus ufw.
  3. Write one small job (a read-only daily summary is a safe first choice). Wire it to a systemd timer, run it once with systemctl start, and read the journal.

If you'd rather not run a server: Anthropic's cloud scheduled tasks come with Pro ($20/month) and Max (from $100/month) as of October 2026 (check the pricing page). You create them at claude.ai/code/routines or with /schedule. They suit GitHub-centered work like PR reviews, issue triage and docs updates. They don't suit work that needs files or services that live only on your VPS, runs more often than hourly, or an API-key-only login. The feature is also still in research preview, so its limits may change. If you want a VPS but not the setup work, Hostinger's Claude Code template removes the install step. Hardening and scheduling are still up to you.

Related guides on this site:

FAQ

Can I install Claude Code on my own VPS without a dedicated dev machine?

Yes. You can do the whole setup from the VPS terminal or a provider's browser console. The one step that needs a browser is signing in. Over SSH, Claude Code shows a URL you open on any device (your phone works), and you paste the code back at the Paste code here if prompted prompt.

Does Claude Code on a VPS require a GUI or desktop environment?

No. The CLI needs a supported Linux (for example Ubuntu 20.04+ or Debian 10+), 4 GB+ RAM and an internet connection. Headless -p runs don't need an interactive terminal at all. A desktop app exists, but a server doesn't need it.

What do Reddit users say about running Claude Code on a VPS long-term?

Forum threads are individual reports, so this guide doesn't repeat them as fact. The long-term issues that are documented are logins that expire (setup tokens last one year), usage limits shared with your interactive sessions, background auto-updates, and processes that don't come back after a reboot. If you plan for those four, the most common long-term failures are covered.

Is a VPS or a local machine better for running Claude Code 24/7?

For around-the-clock jobs, a VPS is the better choice. It doesn't sleep, it has a fixed IP for SSH, and systemd brings jobs back after a reboot. A local machine is better for interactive work on private files you don't want on a server. If your recurring work is all on GitHub, Anthropic's cloud scheduled tasks let you skip owning a machine.

Sources

Spotted something out of date or wrong? Tell us at shigoto.ai.note@gmail.com. Guides are re-checked against official sources on a rolling schedule.