{"id":46995290,"url":"https://github.com/joostme/opencode-docker","last_synced_at":"2026-04-09T09:06:58.308Z","repository":{"id":343714039,"uuid":"1178827984","full_name":"joostme/opencode-docker","owner":"joostme","description":"Docker image running OpenCode (AI coding agent) and code-server (VS Code) in a single container, with Traefik integration, mise toolchains, and SSH support -- designed for self-hosted NAS/VPS use.","archived":false,"fork":false,"pushed_at":"2026-03-29T01:51:06.000Z","size":106,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-29T04:32:31.179Z","etag":null,"topics":["ai-agents","code-server","docker","mise","opencode"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joostme.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-11T12:10:19.000Z","updated_at":"2026-03-26T10:00:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/joostme/opencode-docker","commit_stats":null,"previous_names":["joostme/opencode-docker"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/joostme/opencode-docker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joostme%2Fopencode-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joostme%2Fopencode-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joostme%2Fopencode-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joostme%2Fopencode-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joostme","download_url":"https://codeload.github.com/joostme/opencode-docker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joostme%2Fopencode-docker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","code-server","docker","mise","opencode"],"created_at":"2026-03-11T15:00:22.487Z","updated_at":"2026-04-09T09:06:58.300Z","avatar_url":"https://github.com/joostme.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# opencode-docker\n\nRun [OpenCode](https://opencode.ai), [code-server](https://github.com/coder/code-server), and a Playwright MCP browser sidecar with a shared filesystem and persistent data.\n\nThis setup is meant for people who want a browser-based AI coding agent and VS Code always available on a VPS or home server.\n\n## What you get\n\n- OpenCode web UI served directly by the bundled `opencode` binary and code-server from one container\n- Playwright MCP sidecar for browser automation from the agent\n- GitHub CLI available in the container for `gh` commands\n- Shared `/repos` workspace between both apps\n- Persistent OpenCode data, toolchains, and VS Code extensions\n- Prewired MCP config for Context7 and Playwright\n- Traefik-ready HTTPS routing for separate subdomains\n- SSH key mounting for private Git access and inbound SSH login via `authorized_keys`\n- Preconfigured safeguards that block OpenCode from reading common secret files\n\n## Before you start\n\nYou need:\n\n- Docker and Docker Compose\n- At least one LLM provider API key such as `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `GEMINI_API_KEY`\n- A server or machine where the container can keep running\n- Traefik with a `proxy` network if you want the included domain-based routing\n- Optional: `GH_TOKEN` or `GITHUB_TOKEN` if you want `gh` pre-authenticated\n\n## Quick start\n\n```bash\ngit clone \u003cyour-repo-url\u003e opencode-docker\ncd opencode-docker\ncp .env.example .env\nmkdir -p repos share agents config/mise config/opencode\ndocker compose up -d\n```\n\nThen edit `.env` and set at least:\n\n- `OPENCODE_SERVER_PASSWORD`\n- `ANTHROPIC_API_KEY` or another supported provider key\n- `OPENCODE_DOMAIN` and `CODE_SERVER_DOMAIN` if you are using Traefik\n- `SSH_KEY_PATH` if your SSH keys are not in `~/.ssh`\n\nThe included OpenCode config points to the Playwright MCP sidecar at `http://playwright-mcp:8931/mcp`, so browser automation is available as soon as the stack starts.\n\nAfter startup:\n\n- OpenCode: `https://\u003cOPENCODE_DOMAIN\u003e`\n- code-server: `https://\u003cCODE_SERVER_DOMAIN\u003e`\n\n## Main settings\n\n| Variable | What it does |\n|---|---|\n| `OPENCODE_SERVER_PASSWORD` | Required password for the OpenCode web UI |\n| `OPENCODE_SERVER_USERNAME` | Username for the OpenCode web UI |\n| `CODE_SERVER_PASSWORD` | Optional separate password for code-server |\n| `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GEMINI_API_KEY` | LLM provider credentials |\n| `PUID` / `PGID` | Match container permissions to your host user |\n| `OPENCODE_DOMAIN` | Domain for OpenCode |\n| `CODE_SERVER_DOMAIN` | Domain for code-server |\n| `CERT_RESOLVER` | Traefik certificate resolver |\n| `SSH_KEY_PATH` | Host path to SSH keys; if `authorized_keys` exists there it is used for inbound SSH login |\n| `GH_TOKEN` / `GITHUB_TOKEN` | Optional token for GitHub CLI and API access |\n\nSee `.env.example` for the full list.\n\n## Persistent data\n\n- `./repos` -\u003e your repositories\n- `./config` -\u003e full `~/.config` persistence including OpenCode config, installed skills, and mise config\n- `./share` -\u003e full `~/.local/share` persistence including OpenCode data, code-server data, and mise installs\n- `./agents` -\u003e compatibility config and skills for tools that use `~/.agents`\n\nGitHub CLI auth also persists under `./config` when you log in with `gh auth login` inside the container.\n\n## Security notes\n\n- This setup is intended for personal use, not multi-tenant hosting\n- OpenCode is configured to deny reads for files such as `.env`, SSH keys, `*.pem`, and `*.key`\n- SSH keys are mounted read-only and copied into the container at startup with the correct permissions\n- If `authorized_keys` exists in the mounted SSH directory, the container uses it for inbound SSH access on port `22`\n- SSH password authentication is disabled and root login is disabled\n- Playwright MCP runs as a separate internal service and is only exposed on the private Compose network by default\n- If both `OPENCODE_SERVER_PASSWORD` and `CODE_SERVER_PASSWORD` are empty, code-server can run without auth\n\n## Browser automation\n\n- The stack includes a `playwright-mcp` service using `mcr.microsoft.com/playwright/mcp`\n- OpenCode is preconfigured to connect to it through MCP at `http://playwright-mcp:8931/mcp`\n- The container runs headless Chromium with `--no-sandbox`\n- If you need a different image tag, set `PLAYWRIGHT_MCP_IMAGE` in `.env`\n\n## Without Traefik\n\nIf you do not use Traefik, remove the `labels` and `networks` sections from `docker-compose.yml` and access the mapped ports directly:\n\n```yaml\nports:\n  - \"4096:4096\"\n  - \"8080:8080\"\n```\n\n`4096` serves both the OpenCode API and the web UI directly from the `opencode` process.\n\n## Troubleshooting\n\n- Permission errors on mounted folders: set `PUID` and `PGID` to match your host user\n- SSH access not working: verify `SSH_KEY_PATH`, confirm an `authorized_keys` file exists there, and make sure the files are readable by that user\n- code-server auth issue: set `OPENCODE_SERVER_PASSWORD` even if you leave `CODE_SERVER_PASSWORD` empty\n- Browser actions failing unexpectedly: check `docker compose logs playwright-mcp` and confirm the sidecar is healthy\n- Toolchains reinstalling or changing: check `config/mise/config.toml` and restart the container\n- GitHub CLI not authenticated: set `GH_TOKEN` or `GITHUB_TOKEN`, or run `gh auth login` in the container\n- OpenCode page still tries to reach the internet: rebuild the image and make sure the current OpenCode release binary is installed\n\n## Upstream updates\n\n- `Dockerfile` pins `GH_VERSION`, `CODE_SERVER_VERSION`, and `OPENCODE_VERSION`, so image builds stay reproducible instead of silently pulling `latest`\n- `renovate.json` teaches Renovate to watch `cli/cli`, `coder/code-server`, and `anomalyco/opencode` releases and open PRs when any pinned version can be bumped\n- Enable the Renovate app or runner for this repository to start receiving update PRs automatically\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoostme%2Fopencode-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoostme%2Fopencode-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoostme%2Fopencode-docker/lists"}