● Server & Claude Code
Run Claude Code Remote Control as a systemd service (survives reboots and outages)
claude remote-control connects a Claude Code session on your machine to claude.ai/code and the Claude mobile app. On a VPS you want it always running: after reboots, after network blips, and without an SSH session keeping it alive. This is the unit this server uses.
Prerequisites
- A non-root user for the agent (here
claude) with Claude Code installed at~/.local/bin/claude. Check withclaude --version; this note was tested with 2.1.282. - You've run
claudeonce interactively as that user and logged in, so credentials exist in its home directory.
The unit
# /etc/systemd/system/claude-remote-control.service
[Unit]
Description=Claude Code Remote Control (claude.ai/code + mobile app)
After=network-online.target docker.service
Wants=network-online.target
# Don't give up after repeated fast failures (e.g. network outage at boot)
StartLimitIntervalSec=0
[Service]
Type=simple
User=claude
Group=claude
WorkingDirectory=/home/claude
Environment=HOME=/home/claude
Environment=PATH=/home/claude/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/home/claude/.local/bin/claude remote-control --name claude --permission-mode auto
StandardInput=null
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemd-analyze verify /etc/systemd/system/claude-remote-control.service # must print nothing
sudo systemctl daemon-reload
sudo systemctl enable --now claude-remote-control
systemctl status claude-remote-control
Why each line is there
| Line | Reason |
|---|---|
StartLimitIntervalSec=0 in [Unit] | Without it, 5 failed starts within 10 s (for example while the network is down at boot) put the unit into failed for good. In [Service] this key is silently ignored. This server had exactly that bug. |
Environment=HOME / PATH | systemd doesn't load your login shell, so without these the CLI and anything it runs (git, docker, node) may not be found. |
StandardInput=null | There's no terminal, so stdin shouldn't wait on one. |
WorkingDirectory | Sessions start in this directory, and CLAUDE.md there becomes the agent's standing rules. |
After=docker.service | Optional. Useful if the agent manages containers as soon as it starts. |
Useful flags (from claude remote-control --help)
--name <name>: the session name shown in claude.ai/code.--permission-mode <mode>: one ofacceptEdits,auto,bypassPermissions,default,dontAsk,plan. This is the most important security decision in the file. Pick the least permissive mode that still lets you work from your phone.--spawn same-dir|worktree|sessionand--capacity Ncontrol how new sessions are created and how many can run at once.
Checking on it
journalctl -u claude-remote-control -f # live logs
systemctl show claude-remote-control -p NRestarts -p StartLimitIntervalUSec
# StartLimitIntervalUSec=0 confirms the restart limit is really off
Before you give it sudo
A remote-controlled agent with passwordless sudo is powerful, and it's reachable from your phone. The guardrails checklist covers what this server does about that: SSH and firewall rules the agent may never touch, backups before overwrites, change logs with undo commands, and treating fetched text as data.
Need a VPS to try this on? Everything here was tested on a DigitalOcean Ubuntu 24.04 droplet: get one on DigitalOcean. Referral link: if you sign up through it and spend $25, the site owner gets $25 in DigitalOcean credit. Your price is the same.