Skip to content

About

Opencode Server Docker Image, fully featured. Supports web desktop, server, cli, and mobile.

Topics

Resources

Stars

11 stars

Watchers

0 watching

Forks

Repository files navigation

Opencode Server

Docker Pulls Docker Image Size Artifact Hub

GitHub Health

Deploy on Railway

A fully featured Ubuntu Docker image for running opencode. Minimal image size with support for agent installable tools and CLIs with mise.

Built for Docker and Kubernetes support.

Published to Docker Hub as sprisa/opencode:<version> where <version> matches the release pinned in version.txt (the v2 line — also tagged :latest and :v2). The v1 line is still supported, pinned in version-v1.txt, and published with a mutable :v1 tag.

What's inside

Layer Details
Base OS ubuntu:26.04
User opencode (uid/gid 1000), passwordless sudo
opencode Pinned in version.txt (v2, default) / version-v1.txt (v1, legacy) as OPENCODE_VERSION build arg
Lazy Installed Tools Node, Python3 (see below)
Homebrew Linux-native Homebrew (/home/linuxbrew/.linuxbrew) — brew on PATH
zerobrew Faster Homebrew alternative (zb on PATH) -- used as mise backend for lazy-installed tools
mise Dev tool manager — tools listed below install on first use via zerobrew backend
CLI utilities git, curl, less, unzip
Init tini as PID 1 (zombie reaping, clean shutdown)

Lazy-installed tools

These tools install on first use (via mise → github/zerobrew):

Tool Command Backend
GitHub CLI gh github
jq jq github
GitLab CLI glab core
Ruby ruby zerobrew
ripgrep rg github
fd fd github
Wget wget zerobrew
Vim vim core
Micro micro github
Nano nano zerobrew
Python 3 python3 core
Node.js node core
Sapling sl github

The image ships with a system config at /etc/mise/config.toml with these pre-approved tools. Users can add or override tools by creating ~/.config/mise/config.toml — mise merges both.

Usage

Quick start

docker run -it -p 4096:4096 -v $(pwd):/home/opencode sprisa/opencode:latest

The server starts on port 4096. Mount your project at /home/opencode to persist the entire home directory (dotfiles, config, and ~/workspace).

Environment variables

Variable Default Description
OPENCODE_PORT 4096 Port the server listens on
OPENCODE_PASSWORD (generated by v2) v2 server password; takes precedence over OPENCODE_SERVER_PASSWORD
OPENCODE_SERVER_PASSWORD (none) v1 server password; also accepted by v2 as a compatibility alias
OPENCODE_SERVER_USERNAME opencode v1 only: override the HTTP Basic auth username. V2 always uses opencode
OPENCODE_CORS_ORIGIN (none) Additional allowed browser origin, passed as --cors
OPENCODE_PRINT_LOGS false Set to true to print OpenCode logs to container stderr
OPENCODE_LOG_LEVEL (OpenCode default) DEBUG, INFO, WARN, or ERROR; v2 also accepts lowercase and its extended levels (trace, fatal, etc.)
OPENCODE_INSTALL_HOME_TOOLS false After a 3-second delay, install tools from ~/.config/mise/config.toml in the background

The Dockerfile selects entrypoint.sh for v2 and entrypoint-v1.sh for v1 based on OPENCODE_VERSION. Both run foreground opencode serve on 0.0.0.0 and share the same home/tool initialization. The v2 entrypoint normalizes log levels to the lowercase values required by its CLI.

Authentication and health checks

V2 always requires a password for API requests. Set OPENCODE_PASSWORD (or the legacy OPENCODE_SERVER_PASSWORD) for a stable password; otherwise v2 generates one and prints it at startup. The web sign-in page is publicly accessible, while the API uses HTTP Basic auth with username opencode or a paired browser session. V1 enables HTTP Basic auth when OPENCODE_SERVER_PASSWORD is set.

V2's authenticated health/info endpoint is /api/info; v1 uses /global/health. The old v1 API paths on v2 can return the HTML web app, so a 200 from one of those paths is not an API health or authentication check.

curl --fail --user opencode:secret http://localhost:4096/api/info

Upgrading from v1

:latest now follows v2. Use :v1 to keep an existing deployment on the v1 line, or :v2 to follow v2 explicitly. V2 reads supported v1 configuration from the same locations and migrates legacy session data, but has a new server API/client contract and plugin API. Existing v1 API integrations and plugins need migration; see the upstream migration guide.

Examples

With authentication:

docker run -it -p 4096:4096 \
  -e OPENCODE_PASSWORD=secret \
  -v myproject:/home/opencode \
  sprisa/opencode:latest

With CORS enabled for a specific origin:

docker run -it -p 4096:4096 \
  -e OPENCODE_CORS_ORIGIN=https://myapp.example.com \
  sprisa/opencode:latest

Custom port:

docker run -it -p 8080:8080 \
  -e OPENCODE_PORT=8080 \
  sprisa/opencode:latest

Building & pushing

All docker commands go through task which reads the pinned version from version.txt:

task docker:build                          # Build locally as sprisa/opencode:<version> (v2)
task docker:login                          # Docker Hub login (needs $DOCKER_USER / $DOCKER_PASS)
task docker:push                           # Push v2 as +latest, +v2, +<version> (amd64/arm64)
task publish                               # Push both tracks and create missing GitHub Releases
task docker:build:v1                       # Build the v1 image locally
task docker:push:v1                        # Push v1 as +<version> and +v1

task publish refreshes the versioned images and mutable tags for both tracks, retains existing GitHub releases, and creates missing releases tagged at the checked-out commit. Only v2 releases are marked GitHub's Latest release.

Manual GitHub Actions publishing

Run Actions → Publish → Run workflow to publish both pinned versions from main. Add these repository Actions secrets first:

  • DOCKERHUB_USERNAME: Docker Hub account with push access to sprisa/opencode.
  • DOCKERHUB_TOKEN: Docker Hub access token with Read & Write permissions.

The workflow checks out main with full tag history, sets up multi-architecture builds, logs in to Docker Hub, and runs task publish. GitHub releases use the automatically provided GITHUB_TOKEN with contents: write permission.

Updating the opencode version

task update

Uses the authenticated GitHub CLI (gh) and jq to fetch all upstream release pages and select the highest stable v2 and v1 releases. Updates version.txt (v2) and version-v1.txt (v1) without downgrading either pin. Drafts, prereleases, and component releases are excluded. The scheduled opencode release checker workflow uses the same discovery script and opens a bump PR per track.

Runtime notes

  • The opencode user has passwordless sudo, so you can su - opencode -c 'apt install <pkg>' inside the container.
  • The root filesystem is ephemeral; mount /home/opencode as the persistent volume for all user data (dotfiles, config, projects). The ~/workspace subdirectory is the default workdir.
  • ~/.local/bin is on PATH and user-writable, useful for dropping custom tools at runtime.
  • Node version can be switched at runtime with n <version> (e.g. n lts).
  • Homebrew is installed under /home/linuxbrew/.linuxbrew (outside the persistent volume). It uses its bundled portable Ruby — no system Ruby needed.
  • Zerobrew (zb) is installed at /usr/local/bin/zb with its prefix at ~/.local/share/zerobrew/prefix on PATH for accessing formula binaries.
  • Lazy-installed tools (see table above): run any listed tool and mise auto-installs it via zerobrew or github backend on first use. The image ships defaults in /etc/mise/config.toml; create ~/.config/mise/config.toml to add your own — mise merges both.
  • OpenCode includes a managed instruction at /etc/opencode/mise-instructions.md reminding agents to prefer mise over apt for development tools.

Use in production at www.codeplace.app

About

Opencode Server Docker Image, fully featured. Supports web desktop, server, cli, and mobile.

Topics

Resources

Stars

11 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages