Featured image of post Dockerized OpenCode

Dockerized OpenCode

How to run OpenCode in Docker with both web and TUI modes

This is a guide on how I run OpenCode inside Docker for both web and terminal interfaces. If you want an isolated, reproducible environment for AI-assisted coding, this guide might be useful.

OpenCode is an AI-powered coding assistant that can run in the browser or directly in your terminal. The opencoded project wraps it in a Docker container so you can use it without installing anything locally beyond Docker.

This container supports:

  • Web mode — Access the assistant through your browser on a local port.
  • TUI mode — Run it directly inside your terminal.
  • Multiple instances — Spin up separate containers for different projects on different ports.
  • Persistent config — Keep your settings and authentication intact across restarts.
  • Git integration — Mount SSH keys for seamless commits and pushes.

Available Images

The project provides two pre-built images hosted on GitHub Container Registry:

  • Standard (latest) — Based on Debian (debian:bookworm-slim). It comes pre-packaged with a complete set of utilities (git, gh, curl, jq, ripgrep, etc.) for daily coding.
  • Slim (slim) — Based on Alpine (alpine:latest). It is extremely lightweight and fast, but it is minimal, meaning it might not contain all the libraries or packages you need for complex development tasks.

Prerequisites

Before getting started, make sure you have:

  • Docker installed and running
  • Your SSH key at ~/.ssh/id_ed25519 (for git operations inside the container)
  • OpenCode authentication configured (see the Configuration section below)

Quick Start

Clone the repository

1
2
git clone https://github.com/brockar/opencoded.git ~/opencoded
cd ~/opencoded
1
docker compose up -d

The web interface will be available at: http://localhost:4096

Use the helper script

1
~/opencoded/run.sh

To run on a specific project directory:

1
PROJECT_PATH=/path/to/project ~/opencoded/run.sh

Docker Run Examples

Web Server

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
docker run -d \
  --name opencoded \
  --rm \
  --user "$(id -u):$(id -g)" \
  -p 4096:4096 \
  -v $(pwd):/workspace \
  -v ~/.ssh/id_ed25519:/home/opencoded/.ssh/id_ed25519:ro \
  -v ~/.config/opencode:/home/opencoded/.config/opencode \
  -v ~/.local/share/opencode/auth.json:/home/opencoded/.local/share/opencode/auth.json \
  -e GH_TOKEN=${GH_TOKEN:-} \
  -e OPENCODE_SERVER_USERNAME=${OPENCODE_SERVER_USERNAME:-opencode} \
  -e OPENCODE_SERVER_PASSWORD=${OPENCODE_SERVER_PASSWORD:-} \
  ghcr.io/brockar/opencoded:latest web --hostname 0.0.0.0 --port 4096

Then, access the web interface at: http://localhost:4096

TUI Mode

Run OpenCode directly in your terminal:

1
2
3
4
5
6
7
8
9
docker run -it \
  --rm \
  --user "$(id -u):$(id -g)" \
  -v $(pwd):/workspace \
  -v ~/.ssh/id_ed25519:/home/opencoded/.ssh/id_ed25519:ro \
  -v ~/.config/opencode:/home/opencoded/.config/opencode \
  -v ~/.local/share/opencode/auth.json:/home/opencoded/.local/share/opencode/auth.json \
  -e GH_TOKEN=${GH_TOKEN:-} \
  ghcr.io/brockar/opencoded:latest

Exit with Ctrl+C or type /exit.

Configuration

Helper Script Environment Variables

Variable Description Default
PROJECT_PATH Path to project directory $(pwd)
OPENCODE_PORT Host port to expose 4096
UID User ID for file permissions $(id -u)
GID Group ID for file permissions $(id -g)

Volume Mounts

The container expects these mounts:

  • Project directory/workspace (your project files)
  • ~/.ssh/id_ed25519 → SSH key for git operations
  • ~/.config/opencode → OpenCode configuration
  • ~/.local/share/opencode/auth.json → OpenCode authentication

Persist sessions

To keep your conversation history across restarts, mount the full share directory instead of just auth.json:

1
2
3
4
# replace this:
-v ~/.local/share/opencode/auth.json:/home/opencoded/.local/share/opencode/auth.json
# with:
-v ~/.local/share/opencode:/home/opencoded/.local/share/opencode

Mount your entire code directory

Instead of mounting a single project, you can mount your whole ~/code directory as the workspace. This lets you open any project from the web UI without restarting the container:

1
-v ~/code:/workspace

Then, navigate inside the UI to the specific project (e.g., /workspace/my-project).

Environment Variables

Variable Description Default
GH_TOKEN GitHub token (optional) -
OPENCODE_SERVER_USERNAME Username for HTTP Basic Auth (web mode) opencode
OPENCODE_SERVER_PASSWORD Password for securing the web interface -

Option 1: Setup Script

Run the included script — it auto-detects your shell (zsh or bash) and configures everything for you:

1
~/opencoded/setup_shell.sh

Then reload your shell:

1
source ~/.zshrc   # or ~/.bashrc

Option 2: Manual Setup

Add these functions to your ~/.zshrc or ~/.bashrc:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
opencoded() {
  docker run -d \
    --name opencoded \
    --rm \
    --user "$(id -u):$(id -g)" \
    -p "${OPENCODE_PORT:-4096}:4096" \
    -v "${OPENCODE_PATH:-$(pwd)}:/workspace" \
    -v "$HOME/.ssh/id_ed25519:/home/opencoded/.ssh/id_ed25519:ro" \
    -v "$HOME/.config/opencode:/home/opencoded/.config/opencode" \
    -v "$HOME/.local/share/opencode/auth.json:/home/opencoded/.local/share/opencode/auth.json" \
    -e "GH_TOKEN=${GH_TOKEN:-}" \
    -e "OPENCODE_SERVER_USERNAME=${OPENCODE_SERVER_USERNAME:-opencode}" \
    -e "OPENCODE_SERVER_PASSWORD=${OPENCODE_SERVER_PASSWORD:-}" \
    ghcr.io/brockar/opencoded:latest web --hostname 0.0.0.0 --port 4096
}

opencodedt() {
  docker run -it \
    --rm \
    --name opencoded-tui \
    --user "$(id -u):$(id -g)" \
    -v "${OPENCODE_PATH:-$(pwd)}:/workspace" \
    -v "$HOME/.ssh/id_ed25519:/home/opencoded/.ssh/id_ed25519:ro" \
    -v "$HOME/.config/opencode:/home/opencoded/.config/opencode" \
    -v "$HOME/.local/share/opencode/auth.json:/home/opencoded/.local/share/opencode/auth.json" \
    -e "GH_TOKEN=${GH_TOKEN:-}" \
    ghcr.io/brockar/opencoded:latest
}

Then reload: source ~/.zshrc or source ~/.bashrc.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Start web mode (detached)
opencoded

# Start TUI mode (interactive)
opencodedt

# Custom port
OPENCODE_PORT=5000 opencoded

# Custom project path
OPENCODE_PATH=/path/to/project opencoded

# Stop
docker stop opencoded

Running Multiple Instances

You can run several containers simultaneously on different ports for different projects or accounts.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Instance 1: Project A on port 4096
docker run -d \
  --name opencoded-project-a \
  --rm \
  --user "$(id -u):$(id -g)" \
  -p 4096:4096 \
  -v /path/to/project-a:/workspace \
  -v ~/.ssh/id_ed25519:/home/opencoded/.ssh/id_ed25519:ro \
  -v ~/.config/opencode:/home/opencoded/.config/opencode \
  -v ~/.local/share/opencode/auth.json:/home/opencoded/.local/share/opencode/auth.json \
  -e GH_TOKEN=${GH_TOKEN:-} \
  -e OPENCODE_SERVER_PASSWORD=${OPENCODE_SERVER_PASSWORD:-} \
  ghcr.io/brockar/opencoded:latest web --hostname 0.0.0.0 --port 4096

# Instance 2: Project B on port 4097
docker run -d \
  --name opencoded-project-b \
  --rm \
  --user "$(id -u):$(id -g)" \
  -p 4097:4096 \
  -v /path/to/project-b:/workspace \
  -v ~/.ssh/id_ed25519:/home/opencoded/.ssh/id_ed25519:ro \
  -v ~/.config/opencode:/home/opencoded/.config/opencode \
  -v ~/.local/share/opencode/auth.json:/home/opencoded/.local/share/opencode/auth.json \
  -e GH_TOKEN=${GH_TOKEN:-} \
  -e OPENCODE_SERVER_PASSWORD=${OPENCODE_SERVER_PASSWORD:-} \
  ghcr.io/brockar/opencoded:latest web --hostname 0.0.0.0 --port 4096

Access them separately:

Customizing the Image

If you need additional packages inside the container, edit the Dockerfile and rebuild locally.

Standard image (Debian)

1
2
3
RUN apt-get update && apt-get install -y --no-install-recommends \
  your-package-here \
  && rm -rf /var/lib/apt/lists/*

Slim image (Alpine)

For the slim image, edit Dockerfile.slim and use apk:

1
RUN apk add --no-cache your-package-here

Then rebuild:

1
2
3
4
# Standard
docker build -t ghcr.io/brockar/opencoded:latest .
# Slim
docker build -f Dockerfile.slim -t ghcr.io/brockar/opencoded:slim .

Note: Always pair apt-get install with rm -rf /var/lib/apt/lists/* in the same RUN layer to keep the image size small.

Check out the repository on GitHub to get started: brockar/opencoded. Contributions and feedback are always welcome!

Built with Hugo
Theme Stack designed by Jimmy