From d5d7121180a9a6208bb77da699f53d1b5ac0541a Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Mon, 5 Oct 2026 14:52:03 +0700 Subject: [PATCH] chore: remove the opencode service --- CLAUDE.md | 6 +- README.md | 1 - docs/opencode/known-noise-xdg-open.md | 11 --- opencode/.env.example | 21 ------ opencode/Dockerfile | 10 --- opencode/README.md | 98 --------------------------- opencode/compose.yml | 25 ------- 7 files changed, 3 insertions(+), 169 deletions(-) delete mode 100644 docs/opencode/known-noise-xdg-open.md delete mode 100644 opencode/.env.example delete mode 100644 opencode/Dockerfile delete mode 100644 opencode/README.md delete mode 100644 opencode/compose.yml diff --git a/CLAUDE.md b/CLAUDE.md index 07b50bf..22eb6e1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -91,7 +91,7 @@ directory, one mounted at `/workspace`. The home volume holds settings, credentials and CLI logins; `/workspace` holds the code. Point whatever variable selects the working directory at `/workspace`. -`code-server`, `paseo` and `opencode` all follow this. A service with no +`code-server`, `paseo` and `webtop` all follow this. A service with no human inside it does not — one that spawns a container per session keeps only its own state volume. @@ -101,8 +101,8 @@ your extensions and logins. Check who owns `/workspace` on a fresh volume. Docker creates it `root:root` unless the image ships the directory, and an image that drops to a non-root -user will not be able to write there. `code-server` needs an explicit `chown` -for this reason; `paseo` and `opencode` do not. +user will not be able to write there. `code-server` and `webtop` need an +explicit `chown` for this reason; `paseo` does not. ## Environment variable order diff --git a/README.md b/README.md index 54e6ea5..a8b677f 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,6 @@ Each links to its own README for variables, ports, and storage. | [litellm](litellm/README.md) | LiteLLM proxy in front of many LLM providers, with PostgreSQL and Redis | | [open-webui](open-webui/README.md) | Open WebUI chat interface for OpenAI-compatible and Ollama providers | | [openclaw](openclaw/README.md) | OpenClaw AI agent gateway, with built-in browser automation | -| [opencode](opencode/README.md) | opencode coding agent, served as a browser UI | | [owncloud](owncloud/README.md) | ownCloud file sync and share, with MariaDB and Redis | | [paseo](paseo/README.md) | Paseo coding-agent daemon and web UI | | [traffmonetizer](traffmonetizer/README.md) | TraffMonetizer bandwidth-sharing client | diff --git a/docs/opencode/known-noise-xdg-open.md b/docs/opencode/known-noise-xdg-open.md deleted file mode 100644 index 87d5679..0000000 --- a/docs/opencode/known-noise-xdg-open.md +++ /dev/null @@ -1,11 +0,0 @@ -# Known noise: `xdg-open` stack trace on start - -Applies to `opencode/compose.yml`. - -The container logs a Bun stack trace ending in -`Executable not found in $PATH: "xdg-open"` on every start. `opencode web` -tries to open the UI in a local browser; there isn't one. It is noise — the -server is already listening by then, and the container keeps running. - -Installing `xdg-utils` would silence it at the cost of pulling X11 in and -tripling the image, which is not worth it for a log line. diff --git a/opencode/.env.example b/opencode/.env.example deleted file mode 100644 index c31fc21..0000000 --- a/opencode/.env.example +++ /dev/null @@ -1,21 +0,0 @@ -# Copy to .env and fill in. Never commit .env. -# -# cp .env.example .env - -# Web UI and API login password. MUST NOT be blank -- opencode serves the web -# interface, and with it a shell on this container, to anyone when -# OPENCODE_SERVER_PASSWORD is unset. -# Generate one with: openssl rand -base64 24 -OPENCODE_SERVER_PASSWORD= - -# Username to pair with it. opencode defaults to `opencode` when unset. -OPENCODE_SERVER_USERNAME=opencode - -# OpenCode Go / Zen API key from the OpenCode Console. Leave blank to log in -# with `opencode auth login` instead. -OPENCODE_API_KEY= - -# Git identity for the commits the agent makes, as author and committer. git -# reads these directly, so no `git config` step is needed. -GIT_NAME= -GIT_EMAIL= diff --git a/opencode/Dockerfile b/opencode/Dockerfile deleted file mode 100644 index de22303..0000000 --- a/opencode/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM ghcr.io/anomalyco/opencode:latest - -# Shell, git, HTTP and SSH clients for the commands the agent runs. -RUN apk add --no-cache \ - bash \ - curl \ - git \ - openssh-client - -WORKDIR /workspace diff --git a/opencode/README.md b/opencode/README.md deleted file mode 100644 index 674cdeb..0000000 --- a/opencode/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# opencode - -[opencode](https://opencode.ai) served as a browser UI by `opencode web`, which -starts the headless server and its web interface together. The agent runs in -*this* container — there is no sandbox layer between it and the filesystem. - -Built from a local `Dockerfile`, because the official image is the `opencode` -binary on bare Alpine and nothing else: no shell, no `git`, no `curl`, no -`ssh`. An agent whose main tool is "run a command" has nothing to run, so one -apk layer puts them back. - -## Setup - -For OpenCode Go (or Zen), set `OPENCODE_API_KEY` to the key from the OpenCode -Console and skip the login below. opencode picks the key up from the -environment for both the `opencode-go` and `opencode` providers — models.dev, -where opencode gets its provider list, names `OPENCODE_API_KEY` as their -variable — so no `auth.json` entry or config file is needed. - -Any other provider needs a login, the one step the UI cannot do. After the -first deploy, from a shell: - -```sh -docker compose exec opencode opencode auth login -``` - -It is interactive, which is why it is not an environment variable; `exec` -gives it the TTY it needs. The credentials land on the `opencode-home` volume -and survive a redeploy. - -Then open the domain and sign in with `OPENCODE_SERVER_USERNAME` and -`OPENCODE_SERVER_PASSWORD`. - -## Authentication - -`OPENCODE_SERVER_PASSWORD` is the only thing between the domain and a shell on -this container. opencode's own words: *"If `OPENCODE_SERVER_PASSWORD` is not -set, the server will be unsecured."* Unset, every request is served — and every -request can ask the agent to run a command. Treat a blank value as publishing a -root terminal. - -## Environment - -| Variable | Purpose | -| --- | --- | -| `OPENCODE_SERVER_PASSWORD` | Web UI and API login. Blank means no authentication at all. Generate with `openssl rand -base64 24`. | -| `OPENCODE_SERVER_USERNAME` | Username to go with it. opencode falls back to `opencode`. | -| `OPENCODE_API_KEY` | OpenCode Go / Zen API key. Optional; blank means log in instead. | -| `GIT_NAME` / `GIT_EMAIL` | Git author and committer identity for the agent's commits. | - -Other model provider credentials are not variables — see [Setup](#setup). - -## Storage - -| Volume | Mount | Holds | -| --- | --- | --- | -| `opencode-home` | `/root` | Provider credentials, config, session database, caches | -| `opencode-workspace` | `/workspace` | Code the agent works on | - -The whole home directory is one volume because opencode spreads its state over -four places under it — `.config/opencode`, `.local/share/opencode` (the SQLite -session database), `.local/state/opencode` and `.cache/opencode` — and mounting -them separately would only be three more chances to miss one. Dotfiles and -anything else installed into `$HOME` persist as a side effect. - -The container runs as root, which is what the upstream image does; `$HOME` is -`/root` because of it. - -`WORKDIR /workspace` in the `Dockerfile` is what makes the agent start in the -workspace volume. - -## Networking - -Listens on `4096`; point the domain at it. - -`--hostname 0.0.0.0` in `command:` is what makes the service reachable at all; -both `web` and `serve` bind `127.0.0.1` by default. `--port 4096` is there -because the default is `0`, a random port, which the platform cannot map a -domain to. - -If the UI is loaded from a different origin than it is served from, add -`--cors ` to `command:`. The default setup does not need it. - -## Image - -`FROM ghcr.io/anomalyco/opencode:latest`, the vendor image. The opencode repo -moved out of the `sst` organisation; `ghcr.io/sst/opencode` still exists but no -longer serves anonymous pulls, so it is not the one to use. - -The apk layer adds `bash`, `git`, `curl` and `openssh-client` — the floor for -an agent that clones, commits and fetches. It carries no language toolchain: -none is wanted often enough to justify rebuilding the image for everybody, and -`apk add` from the agent's own terminal covers a one-off — but `/usr` is not on -a volume, so it is gone on the next deploy. Something needed every time belongs -in the `Dockerfile`. - -`ENTRYPOINT` stays the image's own `opencode`, so `command:` in `compose.yml` -is just the subcommand and its flags. diff --git a/opencode/compose.yml b/opencode/compose.yml deleted file mode 100644 index b405eaf..0000000 --- a/opencode/compose.yml +++ /dev/null @@ -1,25 +0,0 @@ -services: - opencode: - build: . - restart: unless-stopped - command: - - web - - '--hostname' - - 0.0.0.0 - - '--port' - - '4096' - environment: - - OPENCODE_SERVER_PASSWORD=${OPENCODE_SERVER_PASSWORD} - - OPENCODE_SERVER_USERNAME=${OPENCODE_SERVER_USERNAME} - - OPENCODE_API_KEY=${OPENCODE_API_KEY} - - TZ=Asia/Ho_Chi_Minh - - GIT_AUTHOR_NAME=${GIT_NAME} - - GIT_AUTHOR_EMAIL=${GIT_EMAIL} - - GIT_COMMITTER_NAME=${GIT_NAME} - - GIT_COMMITTER_EMAIL=${GIT_EMAIL} - volumes: - - 'opencode-home:/root' - - 'opencode-workspace:/workspace' -volumes: - opencode-home: - opencode-workspace: