TL;DR:
- Install Claude Code 2.1.291 as an unprivileged
coderuser withcurl -fsSL https://claude.ai/install.sh | bash. It updates itself in the background. - Anthropic lists Ubuntu 20.04 or newer, 4 GB of RAM or more, an x64 or ARM64 processor and a location in a supported country as the requirements.
- On a server without a browser,
claude auth loginprints a sign-in link to open on your computer. Remote Control needs this claude.ai login on a Pro, Max, Team or Enterprise plan, not an API key. - Run Claude Code in a named tmux session so it survives SSH disconnects, then type
/remote-controlto steer it from the Claude app on iOS or Android. - A Claude Code VPS needs only SSH (22/tcp) open: Remote Control makes outbound HTTPS requests and opens no inbound port.
Applies to: Ubuntu 24.04 LTS · Claude Code 2.1.291 · tmux 3.4 · checked October 2026
Claude Code is Anthropic's agentic coding tool: a terminal program that reads a codebase, edits files and runs commands, and sends model requests to the Anthropic API. This tutorial runs Claude Code on an Ubuntu 24.04 VPS under a non-root user, signs in without a browser, adds a deploy key for one repository, keeps the session in tmux, and connects it to your phone with Remote Control. A server keeps the session working while your laptop is closed.
Prerequisites
- A VPS running Ubuntu 24.04 LTS with root or sudo SSH access and at least 4 GB RAM, the requirement in Anthropic's Claude Code setup guide. On Arct Cloud, Linux images give root SSH access, the Cost Optimized
cvm.microand General Purposevm.microplans (2 vCPU, 4 GB RAM, 40 GB NVMe each) meet that figure, and sustained full-CPU load is not permitted, so start long builds and test suites on demand. See Linux VPS plans. - A non-root user with sudo privileges and SSH key login. How to Generate an SSH Key covers creating the key and giving a sudo user access.
- A Claude Pro, Max, Team or Enterprise plan, or a Claude Console account, used from one of Anthropic's supported countries.
- A GitHub repository for Claude Code to work on, and the Claude app on your phone.
Steps 1 and 2 run as your sudo user, and Steps 3 to 9 run as coder. Replace values written in capitals, such as YOUR_SERVER_IP (for example 203.0.113.10), with your own.
Step 1: Update the server and keep only SSH open
Update the packages and install Git and tmux:
sudo apt update && sudo apt upgrade -y
sudo apt install -y git tmux curl
The server will hold your Claude sign-in and a repository key, so confirm SSH accepts keys only:
sudo sshd -T | grep -i '^passwordauthentication'
The output should read passwordauthentication no. If it reads yes, turn off password login as Step 7 of How to Generate an SSH Key shows, before you continue.
Allow SSH before you enable the Uncomplicated Firewall (UFW), or the current session drops:
sudo ufw allow OpenSSH
sudo ufw enable
Type y to confirm. Claude Code needs no inbound port: Remote Control makes outbound HTTPS requests only. If your provider runs a network firewall in front of the server, open the same SSH port there.
Step 2: Create an unprivileged user for Claude Code
Commands that Claude Code runs on the server run as the Linux user who started it. A user without sudo limits what an approved command can reach, and Anthropic's installer installs into that user's home directory and refuses sudo. If the coder user already exists from How to Install OpenCode on Ubuntu 24.04 or the Codex CLI tutorial, skip to the login command below. Otherwise, create a coder user and copy your SSH key to it:
sudo useradd --create-home --shell /bin/bash coder
sudo install -d -m 700 -o coder -g coder /home/coder/.ssh
sudo install -m 600 -o coder -g coder ~/.ssh/authorized_keys /home/coder/.ssh/authorized_keys
Log in as coder from a new terminal on your computer:
ssh coder@YOUR_SERVER_IP
Step 3: Install Claude Code with the native installer
Run Anthropic's native installer as coder, without sudo:
curl -fsSL https://claude.ai/install.sh | bash
The script downloads the release for your processor from downloads.claude.ai, checks its SHA-256 checksum against the release manifest, and installs the launcher at ~/.local/bin/claude. It ends with Installation complete!. Check the version:
claude --version
The output looks similar to this:
2.1.291 (Claude Code)
Your output may show a newer version. If the shell reports claude: command not found, add ~/.local/bin to your PATH, as Anthropic's troubleshooting page shows:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
To follow the stable channel, which runs about a week behind and skips releases with major regressions, run the installer with bash -s stable in place of bash.
Step 4: Sign in without a browser
The default login opens a browser on the same machine, and the VPS has none. Remote Control in Step 8 works only with Option A.
Option A: claude.ai login for Pro, Max, Team or Enterprise
claude auth login
Choose the claude.ai option if asked, open the printed URL in the browser on your own computer, and sign in with your claude.ai account. The browser cannot reach Claude Code's callback server on the VPS, so it shows a login code instead of redirecting. Paste the code into the SSH terminal and press Enter.
Option B: Claude Console account with API billing
claude auth login --console
Sign in as in Option A; usage is billed to the Console organization instead of a subscription. To use an existing Console API key instead, set ANTHROPIC_API_KEY before you start claude; Claude Code asks once to approve it.
Check the result:
claude auth status
The JSON authMethod field reads claude.ai after Option A. Claude Code stores the login in ~/.claude/.credentials.json with file mode 0600; treat that file like a password. Skip claude setup-token here: its one-year token can only make model requests and cannot start Remote Control.
Step 5: Add a deploy key for one repository
A GitHub deploy key grants SSH access to a single repository, read-only unless you allow write access, so a leaked key reaches that repository only. Create one, replacing YOUR_REPO with the repository name:
ssh-keygen -t ed25519 -N "" -C "coder deploy key YOUR_REPO" -f ~/.ssh/YOUR_REPO_deploy_key
cat ~/.ssh/YOUR_REPO_deploy_key.pub
On GitHub, open the repository, then Settings > Deploy keys > Add deploy key. Enter a Title, such as coder on YOUR_SERVER_IP, paste the public key into Key, leave Allow write access cleared unless Claude Code should push, and click Add key.
Add the host alias GitHub documents for deploy keys, so Git uses this key for this repository. Replace YOUR_REPO in both places first:
tee -a ~/.ssh/config > /dev/null <<'EOF'
Host github.com-YOUR_REPO
HostName github.com
User git
IdentityFile ~/.ssh/YOUR_REPO_deploy_key
IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
Clone through the alias, with YOUR_GITHUB_USER set to the repository owner:
mkdir -p ~/projects
git clone [email protected]_REPO:YOUR_GITHUB_USER/YOUR_REPO.git ~/projects/YOUR_REPO
Compare the host key with GitHub's SSH key fingerprints before you type yes. A second repository needs its own key and alias.
Step 6: Set Manual mode and deny rules
Claude Code 2.1.283 and later start interactive sessions in auto mode, where a classifier model reviews actions instead of you. On a server that holds your sign-in and a deploy key, start in Manual mode and change modes per task. Check for an existing settings file first:
cat ~/.claude/settings.json
If the file exists, open it with nano ~/.claude/settings.json and add the permissions block below inside its outer braces, after a comma, instead of replacing the file. An install with bash -s stable in Step 3 saves "autoUpdatesChannel": "stable" there. If cat reports No such file or directory, create the file:
mkdir -p ~/.claude
tee ~/.claude/settings.json > /dev/null <<'EOF'
{
"permissions": {
"defaultMode": "default",
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(~/.ssh/**)"
],
"ask": [
"Bash(git push *)"
]
}
}
EOF
"defaultMode": "default"is Manual mode: Claude Code runs reads without asking and asks before most file edits, shell commands and network requests.- The
denyrules stop Claude's file tools and recognized file commands, such ascat, from reading.envfiles and~/.ssh. They do not cover a command that reads files without naming them, such asgrep -r, so keep secrets out of the repository. - The
askrule forces a prompt beforegit pushin every mode, auto mode included.
Shift+Tab cycles from Manual to Accept edits (file edits without asking), Plan (proposes changes without editing) and Auto. Leave --dangerously-skip-permissions off this server: Anthropic reserves that mode for isolated containers and VMs without internet access.
Step 7: Start Claude Code in a tmux session
Open a named tmux session in the repository:
tmux new -s claude -c ~/projects/YOUR_REPO
Start Claude Code inside tmux:
claude
On the first start in a folder, Claude Code shows the workspace trust dialog. Trusting a folder lets its .claude/settings.json pre-approve tools, so accept it only for repositories you control. Start in a project folder, not your home directory, where trust is never saved.
If Claude Code asks whether to change your default permission mode to auto mode, decline so the Step 6 setting stays in place. The status bar shows manual mode on. Describe a task, such as Explain the structure of this repository, and commit before large tasks so git diff shows what Claude Code changed.
Detach with Ctrl+B, then D. Claude Code keeps running after SSH closes. Reattach on your next login as coder:
tmux attach -t claude
A reboot ends the tmux session: open a new one in the repository and run claude --continue to load the most recent conversation. How to Install Codex CLI on a Linux Server uses the same pattern, so both agents can run in separate tmux sessions. Agent tasks run builds and tests on the server's vCPU, so start them when you need a result, not in a continuous loop.
Step 8: Use Claude Code Remote Control from your phone
Remote Control connects the Claude app on iOS or Android, or claude.ai/code in a browser, to the session on the VPS, while files and commands stay on the server. In the Claude Code session inside tmux, run:
/remote-control YOUR_REPO
The first time, select Enable Remote Control to confirm. YOUR_REPO becomes the session title, and the status bar shows /rc active while connected. Run /remote-control again for a status panel with the session URL and a QR code.
On your phone, sign in to the Claude app with the same account and tap Code, or scan the QR code. An online session shows a computer icon with a green dot. Permission prompts appear in the app, where you can switch between Manual, Accept edits and Plan; Auto is not available there. For a push notification when Claude Code waits for approval, run /config and turn on Push when actions required.
Claude Code makes outbound HTTPS requests to the Anthropic API, which relays messages between the app and the server, and opens no inbound port. While Remote Control is connected, Anthropic stores the session transcript on its servers to keep devices in sync.
To start later sessions with Remote Control on, run claude --remote-control "YOUR_REPO" in tmux, or set Enable Remote Control for all sessions to true in /config. Server mode, claude remote-control, serves several sessions but exits after about 10 minutes without network, while an interactive session keeps retrying.
Step 9: Verify Claude Code and Remote Control
In a second SSH session as coder, run:
claude --version
claude auth status
claude doctor
claude doctor reports installation health, settings errors and Remote Control eligibility. Then test the whole path:
- Detach from tmux with Ctrl+B, then D, and close every SSH connection.
- In the Claude app, open the session and ask Claude to create a file named
remote-test.txt. - In Manual mode, the edit waits for approval and the prompt appears in the app. Reject it.
A prompt on your phone after SSH closed confirms that tmux, Remote Control and Manual mode all work.
Update Claude Code
Native installs update in the background, and a new version applies at the next start. To update now:
claude update
Then type /exit in tmux and run claude --continue; Remote Control reconnects to the resumed conversation. To stay on the stable channel, add "autoUpdatesChannel": "stable" to ~/.claude/settings.json.
When Claude Code starts within three days of the claude.ai login expiring, it shows Your login expires in 3 days · run /login to renew. A session that stays open in tmux shows this warning only when it starts, and Remote Control stops once the login expires. If the transcript shows Remote Control disconnected with an expired login, run /login, then /remote-control.
Troubleshoot common Claude Code errors
| Symptom | Cause | Fix |
|---|---|---|
bash: claude: command not found | ~/.local/bin is not on PATH | Add the Step 3 export PATH line to ~/.bashrc |
Installation was killed before it could finish (exit code 137) | Out of memory; the install needs roughly 512 MB free | Add a swap file or free memory |
Failed to get a valid version from downloads.claude.ai | The download service is unreachable or not offered in the server's region | Check outbound HTTPS and the supported countries list |
Remote Control requires claude.ai subscription auth. | An API key, apiKeyHelper or token overrides the login | Remove it, then run claude auth login |
Remote Control requires a full-scope login token | A claude setup-token token is in CLAUDE_CODE_OAUTH_TOKEN | Unset it and run claude auth login |
Remote Control is only available when using Claude via api.anthropic.com | ANTHROPIC_BASE_URL points at a gateway | Unset it and restart the session |
Remote Control requires feature-flag evaluation | CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC or DISABLE_GROWTHBOOK is set | Unset the variable the message names |
Remote Control isn't enabled for this account | Stale account data after a plan change | Run claude auth logout, then claude auth login |
Remote Control is disabled by your organization's policy | A Team or Enterprise Owner has it off, or the login still belongs to an earlier Team or Enterprise organization | Ask an Owner to turn on the Remote Control toggle; on a Pro or Max plan, run claude auth logout, then claude auth login |
Your organization has disabled Claude subscription access for Claude Code | The organization blocks subscription login | Use Step 4, Option B, or ask your admin |
Remote Control disconnected with an expired login | The claude.ai login expired | Run /login, then /remote-control |
| Session offline in the app after SSH closed | Claude Code ran outside tmux | Start it in tmux and run claude --continue |
For other problems, run claude doctor.
FAQ
Can I run Claude Code on my server?
Yes. Claude Code runs on Ubuntu 20.04 or newer with 4 GB of RAM or more and an x64 or ARM64 processor, and Anthropic lists a supported country as a requirement. Install it as an unprivileged user with the native installer, sign in with claude auth login, and run it in tmux.
How much RAM does Claude Code need?
Anthropic lists 4 GB of RAM or more. The installer needs about 512 MB of free memory and stops with exit code 137 when the server runs out. The model runs on Anthropic's servers, so the VPS memory goes to Claude Code and the builds and tests it starts.
Is Claude Code free?
No. Claude Code needs a Claude Pro, Max, Team or Enterprise plan, or a Claude Console account billed for API usage. The free claude.ai plan does not include Claude Code access.
Can I use Claude Code Remote Control without a subscription?
No. Remote Control needs a claude.ai login on a Pro, Max, Team or Enterprise plan; API keys, setup-token tokens, LLM gateways and providers such as Amazon Bedrock are not supported. On Team and Enterprise plans, an Owner must turn it on first.
Why is Claude Code Remote Control not available?
Remote Control is unavailable when an API key or token takes precedence over your claude.ai login, ANTHROPIC_BASE_URL points at a gateway, your organization has it off, or your account data is stale. Run claude doctor to see which eligibility check failed.
Why does Claude Code Remote Control keep disconnecting?
The claude process has to keep running, so start it inside tmux, where closing SSH does not end it. An expired claude.ai login also stops Remote Control: run /login, then /remote-control. In server mode, the process exits after about 10 minutes without network.
How does Claude Code Remote Control work?
Claude Code keeps running on your server and makes outbound HTTPS requests to the Anthropic API, which relays messages from claude.ai or the Claude app. It opens no inbound port. Anthropic stores the session transcript while Remote Control is connected.
Next steps
- Route Claude Code through a self-hosted LiteLLM Proxy gateway. A custom
ANTHROPIC_BASE_URLturns Remote Control off for that session. - Compare two self-hosted agents that run on the same kind of server in Hermes Agent vs OpenClaw: Key Differences for Self-Hosting.
- Read Anthropic's Remote Control documentation for server mode and the full error list.
- Review Claude Code permission modes before you switch the server to Accept edits or Auto.
Arct Cloud General Purpose plans run on AMD EPYC Milan 7003 Series processors up to 3.7 GHz with NVMe storage. Compare plans.
This work is licensed under CC BY-NC-SA 4.0.