Setup
Running Codex CLI on a VPS
Codex runs well on a small Linux server. Most of the friction is at login and with the Linux sandbox. This guide covers install, headless sign-in, keeping sessions alive, and how to reach the server from a phone.
Quick answer
Install with curl -fsSL https://chatgpt.com/codex/install.sh | sh (or npm install -g @openai/codex). Next, turn on device code login in your ChatGPT security settings and run codex login --device-auth on the server. Run Codex inside tmux or a daemon so it outlives your SSH connection. Remote in the ChatGPT app officially supports only macOS and Windows hosts. A Linux VPS can only be reached through one of those: the ChatGPT desktop app on a Mac or PC that stays awake opens it as an SSH project. To reach the VPS from a phone directly, use an SSH app or a client that talks to the server, such as Maude.
A server is a good home for OpenAI's Codex CLI. It keeps working with your laptop shut, it survives a dropped connection, and if a run goes wrong you can rebuild the box. Two things trip people up on a fresh Linux VPS. First, plain codex login waits for a browser redirect that can never reach the server. Second, the sandbox needs a package most minimal images don't ship. This guide fixes both, then covers keeping sessions alive and the ways to reach them from a phone.
Requirements
- A Linux server, x86-64 or arm64. OpenAI publishes binaries for both, and macOS works too. Debian or Ubuntu is the easy path.
- An account. Either a ChatGPT plan or an OpenAI API key. OpenAI's Codex pricing page says Codex is included in ChatGPT Free, Go, Plus, Pro, Business, Edu and Enterprise. Limits differ by plan, and local CLI use shares the allowance with cloud chats. API-key usage is billed at API rates instead.
- Memory. The CLI is a compiled binary and needs little memory itself. Your project's builds and test runs are what use RAM. 2 GB works for light work and 4 GB is comfortable. See the VPS buyer's guide for sizing and current prices.
- A non-root user. Create one before installing anything (
adduser dev, then copy your SSH key across). Our Claude Code VPS guide walks through that and SSH hardening; the steps are the same for Codex.
Install Codex
The standalone installer doesn't need Node.js:
curl -fsSL https://chatgpt.com/codex/install.sh | sh
codex --version
If you already manage tools with npm, this installs the same CLI:
npm install -g @openai/codex
Mind the scope: the package is @openai/codex. An unscoped codex package on npm is unrelated. Install as your normal user, not with sudo. Both methods are listed in the openai/codex README.
The Linux sandbox prerequisite
On Linux, Codex runs the shell commands it generates inside a sandbox built on bwrap (bubblewrap) and seccomp. OpenAI's sandboxing docs say to install bubblewrap first:
sudo apt install bubblewrap # Debian / Ubuntu
sudo dnf install bubblewrap # Fedora
Without bwrap, Codex falls back to a bundled helper, and that helper needs unprivileged user namespaces. Ubuntu 24.04 restricts those through AppArmor. The documented fix loads an extra profile:
sudo apt install apparmor-profiles apparmor-utils
sudo install -m 0644 /usr/share/apparmor/extra-profiles/bwrap-userns-restrict /etc/apparmor.d/bwrap-userns-restrict
sudo apparmor_parser -r /etc/apparmor.d/bwrap-userns-restrict
The docs also give a blunter alternative, sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0, which turns the restriction off for the whole machine. Prefer the profile. If you see every sandboxed command fail with a namespace error, this section is why.
Log in with device code
Run plain codex login on a server and it seems to hang. Here's why: it starts a local callback server on port 1455 and waits for your browser to be redirected to localhost. That's the server's localhost, which your phone or laptop can't reach. Use device code login instead. It has one prerequisite that catches nearly everyone:
- Turn on device code login. Do this in your ChatGPT security settings for a personal account. On a Business, Edu or Enterprise workspace, an admin enables it in the workspace permissions. Until it's on, the device flow won't work for your account.
- Start the flow on the server:
codex login --device-auth - Finish it on any device. Codex prints a link and a one-time code. Open the link on your phone or laptop, sign in to ChatGPT, and enter the code.
- Check it worked:
This prints the active auth mode and exits 0 when you're logged in, which makes it useful in scripts.codex login status
That's from OpenAI's authentication docs. They give two fallbacks for when device code isn't available:
- Forward the callback port. Connect with
ssh -L 1455:localhost:1455 user@your-server, runcodex loginon the server, and open the printed address in your local browser. The redirect then travels back through the tunnel. - Copy the credential. Log in on a machine that has a browser, then
scp ~/.codex/auth.json user@your-server:~/.codex/auth.json.
Using an API key instead
printenv OPENAI_API_KEY | codex login --with-api-key
Piping the key in through stdin keeps it out of your shell history. You pay per token at API prices instead of drawing on a ChatGPT plan. That suits a shared or CI box where you want a hard billing boundary.
By default Codex caches credentials in ~/.codex/auth.json. The cli_auth_credentials_store setting can move them to the OS keyring (file, keyring, auto or ephemeral). Anyone with a shell as your user can use your ChatGPT plan. Don't give others shell access to an agent box.
Keep it running
An interactive codex session lives and dies with the terminal that started it. Close the SSH connection and the session ends. You have three ways around that.
tmux, the classic:
sudo apt install tmux
tmux new -A -s codex # create or re-attach
cd ~/src/my-app && codex
# detach: Ctrl-b then d; later: tmux attach -t codex
If the session does end, codex resume --last picks up the most recent conversation in that directory, and codex resume opens a picker. Our tmux, mosh and Tailscale guide has a phone-friendly tmux config.
Non-interactive runs. codex exec "…" runs one task without the TUI, and codex exec resume --last continues it. That fits cron jobs and CI, but there's nobody there to answer approval prompts, so the sandbox settings below matter more.
A daemon that owns the sessions and survives reboots. That's what the 24/7 guide compares: systemd units, Remote Control servers, and apps like Maude that run their own process on the box.
Approvals and sandbox
Codex has two separate controls: what commands can touch (the sandbox) and when it stops to ask you (the approval policy). The values below come from OpenAI's approvals and security docs and the CLI reference:
| Setting | Values | What it means on a server |
|---|---|---|
--sandbox / -s | read-only, workspace-write, danger-full-access | workspace-write is the default in a git repo. Edits stay inside the project, and network access is off unless you enable it. |
--ask-for-approval / -a | on-request, never | on-request asks when an action needs more than the sandbox allows. never doesn't ask at all. In config.toml, approval_policy also accepts granular; the old untrusted value is retired. |
--yolo | (alias of --dangerously-bypass-approvals-and-sandbox) | No sandbox and no prompts. OpenAI reserves it for environments that are already hardened from the outside. |
--full-auto still appears in older guides. It's now a deprecated compatibility flag, and the reference says to use --sandbox workspace-write instead. To let sandboxed commands reach the network, for example so npm install works, add this to ~/.codex/config.toml:
sandbox_mode = "workspace-write"
approval_policy = "on-request"
[sandbox_workspace_write]
network_access = true
One container note: if your "VPS" is really a Docker or LXC container that blocks namespace operations, the docs suggest --sandbox danger-full-access. Only do that if the container itself is your sandbox. The trade-offs are the same as with Claude's bypass mode, covered in running agents with full permissions, safely.
Phone access options
| Option | Works with a Linux VPS? | Good at | Watch out for |
|---|---|---|---|
| Codex Remote (ChatGPT app) | Not officially. Hosts must run the ChatGPT desktop app on macOS or Windows; that app can reach SSH projects on your VPS. | Official, free with your plan, native UI | The host computer has to stay awake and online |
| SSH app + tmux | Yes | Free, nothing extra on the server | A full-screen TUI on a phone keyboard, no push |
| Maude | Yes (any Linux or macOS over SSH) | Native chat UI, inline approvals, push, also Claude Code and others | Paid app; you still need your own ChatGPT plan or key |
A word on headless Linux and Codex Remote. The CLI reference documents codex remote-control start and codex remote-control pair for the local app-server. The Remote connections guide, though, still says hosts run the desktop app on macOS or Windows. Users have opened issues about the gap: #31183 reports headless Linux hosts can't be re-paired from current mobile clients, and #35928 points out the contradiction. Both were open when we checked. If that path works for you, it's the official one. Just don't build a workflow on it yet.
Run it from your phone with Maude
Maude is one way to drive that VPS from a phone without the TUI. You add the server by address or a pasted ssh command, and the app deploys its own small daemon over SSH. That daemon installs Codex at a tested, pinned version, checksum-verified, so you skip the install step. You sign in to Codex from the phone with the ChatGPT device code or an API key. You still have to turn on device code login in ChatGPT first. Sessions keep running on the server when the app is closed, approval requests show up in an inbox and as push notifications with Allow/Deny, and the same server can run Claude Code, OpenCode, Grok Build and Antigravity next to Codex. Details are on the Codex agent page.
Frequently asked questions
Why does codex login hang on my server?
codex login starts a callback server on localhost:1455 and waits for a browser redirect, which a browser on another device can't deliver to your VPS. Use codex login --device-auth after enabling device code login in your ChatGPT security settings. Alternatively, forward the port with ssh -L 1455:localhost:1455.Do I need Node.js to run Codex?
curl -fsSL https://chatgpt.com/codex/install.sh | sh) and the release binaries don't need Node. You only need Node if you choose the npm route, npm install -g @openai/codex.Can I use an API key instead of my ChatGPT plan?
printenv OPENAI_API_KEY | codex login --with-api-key. Usage is then billed at OpenAI API rates rather than counted against a ChatGPT plan's allowance.Does Codex Remote see my VPS?
codex remote-control) is documented, but open GitHub issues report problems pairing headless Linux hosts, so check the current docs before relying on it.Which sandbox mode should I use on a VPS?
workspace-write plus on-request approvals, and enable network_access if your builds need to download packages. Keep --yolo for throwaway machines or containers whose isolation you trust.What changed
- — First published. Install, auth, sandbox and Remote details checked against OpenAI's docs and the openai/codex README on this date.