# Run Agents on a Cloud Server

> **Last verified**: 2026-10-19 · 📄 Per qcode.cc and official docs (tmux / OpenSSH / Ubuntu Server)

> ℹ️ The configuration page and the console for cloud servers currently come **only in Chinese and English**. Product page: <https://qcode.cc/en/cloud>

Running Claude Code or Codex on a machine that **stays on**: a job that takes half an hour or several hours must not die when the SSH connection drops, and you have to be able to come back and look at it. That is what a cloud server is for. Install the tools, set the key, and then two things matter: **letting the task survive a dropped SSH session**, and **moving to key-based login**.

For how to buy the machine see [Cloud Servers: Picking, Buying and Using](/docs/getting-started/cloud-servers); for billing and refunds see [Cloud Server Billing and Rules](/docs/reference/cloud-billing).

## Install Claude Code / Codex on the server

The cloud server page gives exactly these two commands; run them on the server:

```bash
curl -fsSL https://qcode.cc/install/claude-code.sh | bash -s -- --lang en
```

```bash
curl -fsSL https://qcode.cc/install/codex.sh | bash -s -- --lang en
```

The script's messages are in English (`--lang` accepts only `zh` and `en`).

The script benchmarks the access domains, asks for your `cr_` key, writes the configuration, installs Node.js and the CLI if needed, and finishes by sending a minimal request to verify connectivity. All the flags and the rollback steps are in the [One-Click Setup Script](/docs/getting-started/one-click-install).

## Set the QCode key and the endpoint

The one-click script already wrote the configuration for you. If you want to write it by hand — or just want to check what it wrote — these are the two places to look, quoted from [Environment Variables](/docs/getting-started/environment) and [Codex Quick Start](/docs/getting-started/codex-quick-start):

**Claude Code** (Anthropic protocol):

```bash
export ANTHROPIC_BASE_URL="https://api.qcode.cc/api"
export ANTHROPIC_AUTH_TOKEN="cr_your_key"
```

**Codex** (OpenAI Responses protocol) — create the directory first, then write `~/.codex/config.toml`:

```bash
mkdir -p ~/.codex
```

```toml
model_provider = "qcode"
model = "gpt-6.1-sol"
model_reasoning_effort = "high"

[model_providers.qcode]
name = "qcode"
base_url = "https://api.qcode.cc/openai"
wire_api = "responses"
requires_openai_auth = true
```

`~/.codex/auth.json`:

```json
{
  "OPENAI_API_KEY": "cr_your_key"
}
```

Afterwards check that `base_url` is `https://api.qcode.cc/openai`, that `ANTHROPIC_BASE_URL` is `https://api.qcode.cc/api`, and that the key starts with `cr_`. A hand-written `export` only affects the current shell; to have a tmux session that is already running pick it up, run it inside the tmux session or put it in `~/.bashrc`.

## Keep tasks running after SSH drops with tmux

If you run the job over a plain `ssh root@<IP>`, the foreground process dies with the connection. tmux sessions are persistent — the manual says:

> Each session is persistent and will survive accidental disconnection (such as ssh(1) connection timeout) or intentional detaching (with the ‘C-b d’ key strokes).

In other words: the session stays whether SSH drops unexpectedly or you detach yourself with `C-b d`.

Three commands you will use all the time (if tmux is not installed yet, install it with your system's package manager first; on Ubuntu that is `sudo apt install tmux`):

```bash
tmux new -s agent      # create a session named agent and enter it
tmux ls                # list every session on the server
tmux attach -t agent   # attach to that session again
```

To step away, press `Ctrl-b` and then `d` to detach — the manual's default bindings use the `C-b` prefix, and `d` stands for "Detach the current client." (detach the current client). The job keeps running in the session; when you come back, `tmux attach` puts you back in. The manual's own way to reattach is `$ tmux attach`.

## SSH security: switch to key login, verify it works, then turn off passwords

The order matters. The Ubuntu documentation warns about exactly this when it comes to changing the OpenSSH configuration: if SSH is your only way in and you get the configuration wrong, a restart can lock you out of your own server. So **verify first, disable afterwards**.

**The commands below use Ubuntu as the example.** Other distributions use different service names and configuration paths — check that system's own documentation; the order (verify the key, then disable passwords, check before restarting) stays the same.

1. **Generate the key pair on your own machine** (Ubuntu Server documentation, verbatim):

   ```bash
   ssh-keygen -t ed25519
   ```

2. **Put the public key on the server** (run this on macOS / Linux, or in WSL on Windows; the `chmod` command runs on the server, in your home directory after you log in):

   ```bash
   ssh-copy-id root@<IP>
   ```

   The Ubuntu page says to append the content of `id_ed25519.pub` to `~/.ssh/authorized_keys` on the target machine, and to double-check the permissions of that file — only the authenticated user may have write permission; if they are not right, run `chmod go-w .ssh/authorized_keys`.

3. **Verify that the key gets you in.** The page puts it this way: *"You should now be able to SSH to the target_machine without being prompted for a password."* (on the Ubuntu page `target_machine` stands for the address of your server; the sentence means you can log in without being asked for a password). This step **must not be allowed to fall back to a password**, otherwise a key that was not installed correctly still gets in:

   ```bash
   ssh -o PasswordAuthentication=no -o PreferredAuthentications=publickey -i ~/.ssh/id_ed25519 root@<IP>
   ```

   With `-o PasswordAuthentication=no` a wrong key fails straight away with `Permission denied` instead of prompting for a password; if you are refused, **do not carry on** — go back to step 2. At this point **do not close the session you are still logged into with the password**; open a second terminal window.

4. **Only after that works**, turn password login off. First find out which files control the option — on Ubuntu `/etc/ssh/sshd_config` starts with `Include /etc/ssh/sshd_config.d/*.conf`, and settings in `sshd_config.d/` override the main file:

   ```bash
   sudo grep -rEi '^\s*PasswordAuthentication' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/
   ```

   Change **every** line that matches to `PasswordAuthentication no` (including a `yes` in a file under `sshd_config.d/`). Only if nothing matched at all do you add the line `PasswordAuthentication no` to the end of `/etc/ssh/sshd_config`. The reason is in sshd_config(5): "Unless noted otherwise, for each keyword, the first obtained value will be used." (unless stated otherwise, each keyword takes the first value that is read); the files brought in by `Include` are processed in lexical order, so the earlier value wins. The manual describes the two options like this: `PasswordAuthentication` — "Specifies whether password authentication is allowed." (whether password authentication is allowed); `PubkeyAuthentication` — "Specifies whether public key authentication is allowed." (whether public key authentication is allowed).

5. **Check the syntax, look at the effective values, then restart**:

   ```bash
   sudo sshd -t
   sudo sshd -T | grep -Ei '^(passwordauthentication|pubkeyauthentication) '
   ```

   `sshd -T` prints the configuration sshd will actually use (sshd(8)'s "extended test mode": the configuration is written to standard output). Continue to the restart only if you see `passwordauthentication no` and `pubkeyauthentication yes`; if `passwordauthentication` is still `yes`, another file is overriding it — go back to the previous step. If `sshd -t` reports an error, do not restart yet.

   ```bash
   sudo systemctl restart ssh.service
   ```

6. **Check again after the restart, and keep the old session open.** Open a new terminal and log in with the key once more, using the same command as in step 3; then try a password-only login, which should be refused:

   ```bash
   ssh -o PubkeyAuthentication=no root@<IP>
   ```

   Seeing `Permission denied` means password login is off; only when both checks behave as expected do you close the original session.

> 💡 At this point you have a machine that can run agents for the long haul: the tools are installed, the key and endpoint are set, tasks survive a dropped connection, and you log in with a key.

## What it costs: two parts

- **The server**: charged from your balance for the term you pick at order time (1, 3, 6 or 12 months) — longer terms cost less per month. The starting price is in the “Compare lines” table on qcode.cc/en/cloud.
- **The models**: billed per token, with per-model rates listed on [qcode.cc/models](https://qcode.cc/models).

Both come out of the **same account balance**.

## Related pages

- [Cloud Servers: Picking, Buying and Using](/docs/getting-started/cloud-servers) — picking a line, the 1-day trial, ordering and delivery
- [One-Click Setup Script](/docs/getting-started/one-click-install) — install the tools and write the configuration
- [Environment Variables](/docs/getting-started/environment) — which variables each tool reads
- [Codex Quick Start](/docs/getting-started/codex-quick-start) — config.toml and auth.json for Codex
- [Cloud Server Billing and Rules](/docs/reference/cloud-billing) — terms, automatic renewal, refunds and the acceptable use policy