2026-04-11 11:37:48 -04:00
2026-04-11 11:37:48 -04:00
2026-04-11 09:26:46 -04:00

Claude Code — Dockerized

A minimal, guardrailed container for running Claude Code. The home directory and project folder are volumes, keeping your Claude install and credentials separate from any specific project.

Setup

# 1. Build the image
docker compose build

# 2. Export your API key (or put it in a .env file)
export ANTHROPIC_API_KEY=sk-ant-...

# 3. First run — installs Claude Code into the home volume, then drops you
#    into an interactive shell inside the default ./code directory
docker compose run --rm claude-code

On first start the entrypoint runs the native installer and places the binary in the claude-home named volume (under /home/coder/.local/bin). Subsequent starts skip the install and launch immediately.

Switching projects

Point PROJECT_DIR at any directory on your host:

PROJECT_DIR=/path/to/myproject docker compose run --rm claude-code

Or set it in a .env file:

ANTHROPIC_API_KEY=sk-ant-...
PROJECT_DIR=/Users/me/projects/my-app

Then just:

docker compose run --rm claude-code

Starting Claude Code

Once inside the container shell:

claude          # start an interactive session in the current directory
claude --help   # show available options
claude doctor   # diagnose installation issues

Volumes

Volume Purpose
claude-home (named) Persists Claude Code binary, config, and auth credentials
$PROJECT_DIR (bind) Your project code — swap freely between sessions

To wipe the Claude install and start fresh:

docker compose down -v   # removes the claude-home volume

Security notes

  • Runs as a non-root user (coder, uid 1001)
  • All Linux capabilities are dropped except NET_BIND_SERVICE
  • Privilege escalation is disabled (no-new-privileges)
  • The container has no network restrictions beyond what Docker provides — add a custom network or --network none with --add-host if you want to lock that down further

Connecting to a host PostgreSQL database

The container can reach a PostgreSQL server running on the host, but 127.0.0.1 inside the container refers to the container itself, not the host. The solution is to connect via the Docker bridge gateway IP instead, which both the host and the container can see.

1. Find the gateway IP

docker network inspect bridge | grep Gateway

This is typically 172.17.0.1. Use the value specific to your machine in all steps below.

2. Configure PostgreSQL on the host

Edit /etc/postgresql/<version>/main/postgresql.conf:

listen_addresses = 'localhost,172.17.0.1'

Edit /etc/postgresql/<version>/main/pg_hba.conf and add:

host    all    all    172.17.0.0/16    scram-sha-256

Restart PostgreSQL:

sudo systemctl restart postgresql

3. Configure your app

Use the gateway IP as the database host. Since it is reachable from both the host and the container, a single DATABASE_URL works in both contexts:

DATABASE_URL=postgresql://user:password@172.17.0.1:5432/mydb

Set this in your .env file or shell profile on the host, and pass it through in docker-compose.yml:

environment:
  - DATABASE_URL=${DATABASE_URL}

Collation version warning

If you see a warning like:

WARNING: database "mydb" has a collation version mismatch
DETAIL: The database was created using collation version 2.41, but the
operating system provides version 2.42.

This is caused by the container's glibc version differing from the host's. It is a warning only and will not break anything. To silence it, run once on the host:

psql -d mydb -c "ALTER DATABASE mydb REFRESH COLLATION VERSION;"

Note: the warning will reappear inside the container because its glibc version differs from the host. The long-term fix is to rebase the Docker image on the same Ubuntu release as the host so glibc versions match.

Description
No description provided
Readme 83 KiB
Languages
Shell 55%
Dockerfile 45%