feat: migrate to OpenCode 2
PR Checks / hadolint (pull_request) Successful in 12s
PR Checks / build-test (pull_request) Successful in 3m14s

OpenCode 2 publishes its CLI as @opencode/cli (opencode-ai stops at
1.19.x), so install that package and pin it to 2.0.32.

Also fix what the v2 migration invalidates:
- renovate.json: track @opencode/cli instead of opencode-ai, otherwise
  the pin is never bumped.
- opencode-attach: `opencode attach` no longer exists in v2. Point the
  client at the server with `--server <url>` instead (appended after a
  subcommand when one is given); auth still comes from
  OPENCODE_SERVER_PASSWORD / OPENCODE_PASSWORD.
- README/AGENTS: v2 package name, entrypoint, serve defaults, API
  surface (/global/health is gone, everything lives under authenticated
  /api/*), and removal of OPENCODE_SERVER_USERNAME (the username is
  always `opencode` in v2).

The entrypoint stays ["opencode"] on purpose: existing deployments pass
`serve ...` at runtime, and OpenCode 2 is invoked the same way.
This commit is contained in:
OpenCode Cabillot committed 2026-10-17 19:28:14 +00:00
1 parent 82cfa4af95
commit c2c0a81547
5 files changed
+65 -37

No files matched your search

+29 -19
View File
@@ -4,7 +4,7 @@ Docker image for running [OpenCode](https://opencode.ai) as a headless HTTP serv
## What is OpenCode?
OpenCode is an open source AI coding agent available as a terminal interface, desktop app, or IDE extension. This image runs it in server mode (`opencode serve`), exposing an HTTP API that clients can connect to.
OpenCode is an open source AI coding agent available as a terminal interface, desktop app, or IDE extension. This image ships OpenCode 2 and runs it in server mode (`opencode serve`), exposing an HTTP API and web UI that clients can connect to.
## Pull
@@ -12,7 +12,7 @@ OpenCode is an open source AI coding agent available as a terminal interface, de
docker pull jcabillot/opencode
```
The image is rebuilt and pushed to Docker Hub automatically every night via the Jenkins pipeline.
The image is rebuilt and pushed to Docker Hub automatically every night by the Gitea Actions pipeline.
## Build locally
@@ -22,14 +22,16 @@ docker build -t opencode .
## Run
The entrypoint is the `opencode` binary; pass `serve` to start the headless server:
```bash
docker run -it -p 4096:4096 jcabillot/opencode
docker run -it -p 4096:4096 jcabillot/opencode serve
```
By default the server listens on `127.0.0.1:4096`. To expose it on all interfaces:
The server listens on `127.0.0.1:4096` by default. To expose it on all interfaces:
```bash
docker run -it -p 4096:4096 jcabillot/opencode --hostname 0.0.0.0
docker run -it -p 4096:4096 jcabillot/opencode serve --hostname 0.0.0.0
```
### Mount a project
@@ -37,7 +39,7 @@ docker run -it -p 4096:4096 jcabillot/opencode --hostname 0.0.0.0
```bash
docker run -it -p 4096:4096 \
-v $(pwd):/home/opencode/project \
jcabillot/opencode --hostname 0.0.0.0
jcabillot/opencode serve --hostname 0.0.0.0
```
### Secure with a password
@@ -45,17 +47,17 @@ docker run -it -p 4096:4096 \
```bash
docker run -it -p 4096:4096 \
-e OPENCODE_SERVER_PASSWORD=your-password \
jcabillot/opencode --hostname 0.0.0.0
jcabillot/opencode serve --hostname 0.0.0.0
```
Authentication uses HTTP basic auth. The default username is `opencode`, override it with `OPENCODE_SERVER_USERNAME`.
Authentication uses HTTP basic auth. The username is always `opencode`; the password is read from `OPENCODE_SERVER_PASSWORD` (or `OPENCODE_PASSWORD`). When neither is set, OpenCode 2 generates a random password and prints it to the log at startup — the server is never left unauthenticated.
## Troubleshooting helper
The image includes an `opencode-attach` wrapper in `PATH` that runs:
```bash
opencode attach -p "${OPENCODE_SERVER_PASSWORD}" "${OPENCODE_API_URL}"
opencode --server "${OPENCODE_API_URL}"
```
Example:
@@ -66,31 +68,39 @@ export OPENCODE_API_URL=http://127.0.0.1:4096
opencode-attach
```
Extra arguments are forwarded to the client, with `--server` appended to the subcommand:
```bash
opencode-attach session list --format json
```
## API
Once running, the server exposes an OpenAPI 3.1 spec at:
```
http://localhost:4096/doc
http://localhost:4096/openapi.json
```
The web UI is served at `/` and is reachable without credentials; every `/api/*` route requires basic auth.
Key endpoints:
| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/global/health` | Health check and version |
| `GET` | `/session` | List sessions |
| `POST` | `/session` | Create a session |
| `POST` | `/session/:id/message` | Send a message |
| `GET` | `/event` | Server-sent events stream |
| `GET` | `/api/info` | Health check and version |
| `GET` | `/api/session` | List sessions |
| `POST` | `/api/session` | Create a session |
| `POST` | `/api/session/:id/prompt` | Send a message |
| `GET` | `/api/event` | Server-sent events stream |
See the [OpenCode server docs](https://opencode.ai/docs/server/) for the full API reference.
See the [OpenCode v2 API reference](https://opencode.ai/v2/docs/api/) for the full API surface.
## Image details
- **Base image**: `node:24` (Debian)
- **Install**: `opencode-ai` via npm global install
- **Base image**: `node:26-trixie` (Debian)
- **Install**: `@opencode/cli` (OpenCode 2) via npm global install
- **User**: dedicated non-root `opencode` user
- **Cluster tooling**: `kubectl` (copied from official registry image)
- **Entrypoint**: `opencode serve`
- **Entrypoint**: `opencode`
- **Default port**: `4096`