All tutorials
14 min read

How to Install Codex CLI on a Linux Server (Ubuntu 24.04)

Install Codex CLI on a Linux server (Ubuntu 24.04) in 10 steps: a non-root user, the bubblewrap sandbox, device code or API key login, tmux and codex exec.

TL;DR:

  • Install Codex CLI 0.160.1 as an unprivileged coder user with curl -fsSL https://chatgpt.com/codex/install.sh | sh, which places codex in ~/.local/bin.
  • On a server without a browser, sign in with codex login --device-auth after you turn on device code login in ChatGPT, or pipe an OpenAI API key to codex login --with-api-key.
  • Codex's Linux sandbox needs bubblewrap. On Ubuntu 24.04 it may also need the bwrap-userns-restrict AppArmor profile.
  • The workspace-write sandbox with on-request approvals lets Codex edit the repository and asks before network access or writes outside it.
  • OpenAI lists 4 GB RAM as the minimum for Codex CLI and 8 GB as recommended.
  • Run Codex in tmux so sessions survive SSH disconnects, and use codex exec for scripted runs you start on demand.

Applies to: Ubuntu 24.04 LTS · Codex CLI 0.160.1 · bubblewrap 0.9.0 · checked October 2026

Codex CLI is a coding agent from OpenAI, open source under the Apache-2.0 license at github.com/openai/codex, that reads a repository, edits files and runs commands from a terminal interface inside an operating-system sandbox. It is separate from Codex cloud, which runs tasks in OpenAI-managed containers. This tutorial covers the Codex CLI install on a Linux server running Ubuntu 24.04: a non-root user, sign-in without a browser, sandbox and approval settings, an AGENTS.md file, tmux sessions and codex exec. A server keeps a session running after you close your laptop.

Prerequisites

  • A server running Ubuntu 24.04 LTS with root or sudo SSH access and at least 4 GB RAM, the minimum OpenAI lists for Codex CLI (8 GB recommended). On Arct Cloud, a General Purpose vm.micro plan (2 vCPU, 4 GB RAM, 40 GB NVMe) meets that minimum, vm.tiny (4 vCPU, 8 GB RAM, 80 GB NVMe) matches the recommendation, and sustained full-CPU load is not permitted, so start long builds and test runs 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 ChatGPT account on a Plus, Pro, Business, Edu or Enterprise plan, or an OpenAI API key.
  • A Git repository for Codex to work on.

Steps 1 to 3 run as your sudo user, and Steps 4 to 10 run as coder. Replace values written in capitals, such as YOUR_SERVER_IP, with your own.

Step 1: Install bubblewrap and enable the firewall

Codex runs the commands the agent starts inside a sandbox, and on Linux that sandbox uses bubblewrap (bwrap). Install it from Ubuntu's repository together with Git and tmux:

sudo apt update && sudo apt upgrade -y
sudo apt install -y git tmux curl bubblewrap

Without a system bwrap, Codex falls back to a bundled helper and prints a warning when it starts.

The server will hold your Codex sign-in, 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. Codex CLI needs no inbound port for the steps in this tutorial. If your provider runs a network firewall in front of the server, open the same SSH port there.

Step 2: Check that bubblewrap can create user namespaces

Ubuntu 24.04 limits unprivileged user namespaces through AppArmor, and OpenAI's sandbox documentation notes that Codex may still warn on 24.04 after bubblewrap is installed. Run the same check Codex runs when it starts, as your sudo user and without sudo:

bwrap --unshare-user --unshare-net --ro-bind / / /bin/true && echo "bubblewrap OK"

If the output is bubblewrap OK, go to Step 3. If it prints an error instead, such as setting up uid map: Permission denied or loopback: Failed RTM_NEWADDR, load the bwrap-userns-restrict AppArmor profile that OpenAI documents for Ubuntu 24.04:

sudo apt install -y 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

apparmor_parser -r loads the profile without a reboot. Run the check again to confirm it prints bubblewrap OK. The profile lets bwrap create its namespaces while Ubuntu's restriction stays on for other programs.

Step 3: Create an unprivileged user for Codex

Codex runs commands with the access of the user who starts it. The sandbox limits writes to the repository, and an account without sudo limits what a command you approve outside the sandbox can reach. If you followed How to Install OpenCode on Ubuntu 24.04 or the Claude Code tutorial, the coder user already exists: 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

Replace YOUR_SERVER_IP with the server's address, such as 203.0.113.10.

Step 4: Install Codex CLI with the official script

Run OpenAI's standalone installer as coder:

curl -fsSL https://chatgpt.com/codex/install.sh | sh

The script downloads the release for your CPU from releases.openai.com, with GitHub Releases as a fallback, and checks its SHA-256 digest. It installs codex in ~/.local/bin and adds that directory to PATH in ~/.bashrc. Answer N when it asks Start Codex now?. The output looks similar to this:

==> Installing Codex CLI
==> Detected platform: Linux (x64)
==> Resolved version: 0.160.1
==> Downloading Codex CLI
...
==> PATH was added to /home/coder/.bashrc
Codex CLI 0.160.1 installed successfully.
Start Codex now? [y/N]

To pin the version checked here, add -s -- --release 0.160.1 after sh. Reload the shell and check the version:

source ~/.bashrc
codex --version

The output shows codex-cli 0.160.1 or a newer version.

Install with npm instead

If you manage Node.js yourself, the npm package installs the same CLI. It needs Node.js 16 or newer, per the package's engines field, and an npm prefix that coder can write to:

npm install -g @openai/codex

Use one install method. When the script finds an npm-managed codex, it warns that PATH order decides which copy runs.

Step 5: Sign in with device code login or an API key

Plain codex login opens a browser on the same machine, and a server has none. Use one of these two methods instead.

Option A: Device code login with a ChatGPT plan

ChatGPT Plus, Pro, Business, Edu and Enterprise plans include Codex CLI. Device code login is a beta feature that stays off until you turn it on: in your ChatGPT security settings for a personal account, or in workspace permissions, which a workspace admin controls. Then run:

codex login --device-auth

The output looks similar to this:

Welcome to Codex [v0.160.1]
OpenAI's command-line coding agent

Follow these steps to sign in with ChatGPT using device code authorization:

1. Open this link in your browser and sign in to your account
   https://auth.openai.com/codex/device

2. Enter this one-time code (expires in 15 minutes)
   ABCD-EFGH

Continue only if you started this login in Codex. If a website or another person gave you this code, cancel.

Open the link on your own computer, sign in, and enter the code within 15 minutes. The terminal prints Successfully logged in.

Option B: OpenAI API key

Create a key in the OpenAI dashboard. API key usage is billed through your OpenAI Platform account, and some features that depend on a ChatGPT workspace or Codex cloud are limited or unavailable. Read the key without echoing it, pipe it to Codex, and clear the variable:

read -rsp "OpenAI API key: " OPENAI_API_KEY && echo
printf '%s' "$OPENAI_API_KEY" | codex login --with-api-key
unset OPENAI_API_KEY

--with-api-key reads the key only from standard input and exits with an error when nothing is piped to it, so the key stays out of shell history.

If neither method works, forward Codex's browser callback port, 1455, from your computer with ssh -L 1455:localhost:1455 coder@YOUR_SERVER_IP and run codex login in that session. How to Open a Private Dashboard with an SSH Tunnel explains -L.

Check the result:

codex login status

The output reads Logged in using ChatGPT or Logged in using an API key followed by a masked key. Codex caches the sign-in in ~/.codex/auth.json or in the operating system's credential store. Treat auth.json like a password: it holds access tokens.

Step 6: Set the sandbox and approval defaults

Codex reads user settings from ~/.codex/config.toml. This command creates the file:

tee ~/.codex/config.toml > /dev/null <<'EOF'
sandbox_mode = "workspace-write"
approval_policy = "on-request"

[sandbox_workspace_write]
network_access = false

[shell_environment_policy]
ignore_default_excludes = false
EOF

If ~/.codex/config.toml already exists, open it with nano ~/.codex/config.toml instead of running the command. Put sandbox_mode and approval_policy above the first line that starts with [, and add the two tables at the end, or only their keys if the file already has those tables. Save with Ctrl+O and exit with Ctrl+X.

  • workspace-write lets commands write inside the current repository and /tmp. The .git and .codex folders stay read-only, so a commit needs your approval.
  • on-request makes Codex ask before a command leaves the sandbox, such as a write outside the repository or a network request.
  • network_access = false keeps commands offline. It is the default, written out so it stays visible.
  • ignore_default_excludes = false hides environment variables whose names contain KEY, SECRET or TOKEN from the commands Codex starts.

The other sandbox values are read-only and danger-full-access. Inside a session, /permissions switches presets, such as Read Only for planning. OpenAI's docs reserve --dangerously-bypass-approvals-and-sandbox (alias --yolo) for an externally hardened environment, so leave it off a server that holds credentials.

Step 7: Start Codex in a tmux session

For a private repository, add a deploy key for coder first, as Step 6 of the OpenCode tutorial shows. Clone the repository and open a named tmux session in it:

mkdir -p ~/projects
git clone YOUR_REPO_URL ~/projects/YOUR_REPO
tmux new -s codex -c ~/projects/YOUR_REPO

Start Codex inside tmux:

codex

If Codex asks whether to trust the folder, trust only repositories you control: a trusted project can load its own .codex/ configuration. Describe a task, such as Tell me about this project. Create Git commits before and after each task so you can revert changes.

Detach with Ctrl+B, then D. Codex keeps running after SSH closes. Reattach on your next login as coder:

tmux attach -t codex

If you closed Codex, codex resume --last reopens the most recent chat from the current directory.

Open the server from the ChatGPT desktop app (optional)

The ChatGPT desktop app can start Codex on an SSH host and run chats against that host's files. Add the server to ~/.ssh/config on your computer:

Host codex-server
  HostName YOUR_SERVER_IP
  User coder
  IdentityFile ~/.ssh/id_ed25519

The app runs codex through the remote user's login shell. Confirm the command resolves there:

ssh codex-server 'bash -lc "command -v codex"'

The output is /home/coder/.local/bin/codex. In the app, open Settings > Connections, add the SSH host, and choose the project folder.

Step 8: Add an AGENTS.md file

Codex reads AGENTS.md files before it starts work: ~/.codex/AGENTS.md applies to every repository, and an AGENTS.md in the repository applies to that project. In a Codex session, /init writes a starter file in the current directory. To write one by hand, replace the commands below with your project's own:

tee ~/projects/YOUR_REPO/AGENTS.md > /dev/null <<'EOF'
## Repository expectations

- Run `make test` after changing code and report the result.
- Ask before adding a new dependency.
- Do not read or print .env files.
EOF

Codex reads these files once per session and stops adding files once their combined size reaches 32 KiB by default. Quit Codex with /exit and start it again to load changes.

Step 9: Run scripted tasks with codex exec

codex exec runs one task without the interactive interface and exits. It reuses the saved sign-in, streams progress to standard error and prints only the final message to standard output:

cd ~/projects/YOUR_REPO
codex exec --sandbox read-only "Summarize the changes in the last 5 commits" -o ~/codex-summary.md

-o also writes the final message to ~/codex-summary.md. Without a --sandbox flag, codex exec uses the sandbox_mode from ~/.codex/config.toml and does not stop for approvals, so after Step 6 it can edit files in the repository. Pass --sandbox read-only for runs that only read, as above, and --sandbox workspace-write for a run that edits files:

codex exec --sandbox workspace-write "Fix the failing unit tests and run them again"

Start codex exec on demand, when you need a result, not in a continuous loop: each run sends model requests and runs commands on the server until its task finishes. It requires a Git repository; --skip-git-repo-check overrides that for a one-off folder. --json prints newline-delimited JSON events, and codex exec resume --last "YOUR_FOLLOW_UP" continues the previous run.

Step 10: Verify Codex and the sandbox

Check the install, the sign-in and the local setup as coder:

codex --version
codex login status
codex doctor

codex doctor reports on the installation, configuration, authentication, runtime, Git and terminal. In the tmux session, start Codex and confirm it shows no bubblewrap warning at startup. Type /status: it lists the model, the approval policy and the writable folders.

Then test the sandbox on purpose. Ask Codex to run curl -I https://example.com. Network access is off for commands, so Codex asks for your approval before the command can reach the network. Decline it: the request confirms that on-request and the sandbox are active.

Update Codex CLI

Run the install script again as coder:

curl -fsSL https://chatgpt.com/codex/install.sh | sh
codex --version

The script installs the newest release and leaves config.toml and the saved sign-in in place. codex update also applies an update when the installed release supports self-update. For an npm install, run npm install -g @openai/codex again. Exit Codex in tmux with /exit, then run codex resume --last.

If an older config sets approval_policy = "untrusted", remove that line. Current releases no longer support the value, and it can stop Codex from starting.

Troubleshoot common Codex CLI errors

SymptomCauseFix
codex: command not foundThe shell has not reloaded ~/.bashrcRun source ~/.bashrc or log in again as coder
Codex could not find bubblewrap on PATHThe bubblewrap package is missingAs the sudo user, run sudo apt install -y bubblewrap
Codex's Linux sandbox uses bubblewrap and needs access to create user namespacesAppArmor blocks the user namespaces bwrap needsLoad the bwrap-userns-restrict profile from Step 2
--with-api-key expects the API key on stdinThe command ran without a key piped to standard inputUse the read and printf commands from Step 5
device auth timed out after 15 minutesThe code was not entered in time, or device code login is offTurn on device code login in ChatGPT, run codex login --device-auth again, or use an API key
Not logged in from codex login statusThis Linux user has no saved sign-inRepeat Step 5 as coder
Codex exits at startup after an updateapproval_policy = "untrusted" in config.tomlRemove the line or set approval_policy = "on-request"

For other problems, run codex doctor.

FAQ

How do I install Codex CLI on Linux?

Run curl -fsSL https://chatgpt.com/codex/install.sh | sh as a regular user, reload the shell, and run codex --version. The script installs codex in ~/.local/bin and adds that folder to PATH. npm install -g @openai/codex installs the same CLI if you manage Node.js yourself.

How to check if Codex CLI is installed?

Run codex --version. It prints the installed release, such as codex-cli 0.160.1. If the shell reports codex: command not found, run source ~/.bashrc or log in again, because the installer adds ~/.local/bin to PATH for new shells.

How do I use Codex CLI with an API key?

Pipe the key to codex login --with-api-key, for example printenv OPENAI_API_KEY | codex login --with-api-key. The flag reads only from standard input, so the key stays out of shell history. API key usage is billed through your OpenAI Platform account, not a ChatGPT plan.

Why is Codex device code login not working?

Device code login is a beta feature that must be turned on first, in ChatGPT security settings for a personal account or in workspace permissions by an admin. Each code expires after 15 minutes. If your workspace keeps it off, sign in with an API key instead.

Does the Codex app work on Linux?

Yes. OpenAI documents the ChatGPT desktop app, which runs Codex, for macOS, Windows and desktop Linux, where it is in preview on Ubuntu 24.04 and other distributions. On a server without a desktop, use Codex CLI. The app can open projects on that server over SSH when codex is installed and signed in there.

How much RAM does Codex CLI need?

OpenAI lists 4 GB of RAM as the minimum for Codex CLI and 8 GB as recommended, on Ubuntu 20.04 or newer. The model runs on OpenAI's servers, so the server's memory goes to Codex itself and to the builds and tests it runs.

How do I update Codex CLI?

Run the install script again: curl -fsSL https://chatgpt.com/codex/install.sh | sh. It installs the newest release and leaves your config and sign-in in place. For an npm install, run npm install -g @openai/codex. Restart open Codex sessions afterward.

Next steps

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.