74 lines
3.3 KiB
Markdown
74 lines
3.3 KiB
Markdown
# AGENTS.md
|
|
|
|
## Project overview
|
|
|
|
This repository builds and publishes a Docker image for [OpenCode](https://opencode.ai), the open source AI coding agent. The image runs OpenCode in headless server mode (`opencode serve`) and is automatically rebuilt and pushed to Docker Hub (`jcabillot/opencode`) every night by a Jenkins pipeline.
|
|
|
|
## Repository structure
|
|
|
|
```
|
|
.
|
|
├── Dockerfile # Image definition
|
|
├── Jenkinsfile # CI/CD pipeline (nightly build + Docker Hub push)
|
|
├── opencode-attach # Helper script for attaching to a running server
|
|
└── README.md # Usage documentation
|
|
```
|
|
|
|
## Dependency management
|
|
|
|
- **Always pin versions** in the Dockerfile `npm install` command (e.g. `opencode-ai@1.16.2 n2-soul@9.0.9`). Never leave packages unpinned.
|
|
- **Update renovate customManagers** when adding, removing, or renaming a dependency tracked in the Dockerfile. Each pinned package must have a corresponding `customManager` entry in `renovate.json` with a regex `matchStrings` pattern that captures the version. If a dependency is added without a renovate entry, Renovatebot will not open automated PRs for it.
|
|
- **apt packages** (apt-get install lines in Dockerfile) and **COPY --from** image references are not currently tracked by Renovate. Pinning these manually is acceptable for now but adding renovate managers for them is encouraged.
|
|
|
|
## Dockerfile conventions
|
|
|
|
- **Base image**: `node:24` — Debian-based Node.js image (not Alpine, needed for apt packages).
|
|
- **Install**: `npm i -g opencode-ai@<version> n2-soul@<version>` — installs OpenCode and Soul globally, both pinned.
|
|
- **Version check**: `RUN opencode --version` after install to validate the build and record the installed version in build logs.
|
|
- **Dedicated user**: a non-root `opencode` user and group are created with `groupadd`/`useradd` (UID/GID 1000). All runtime steps run as this user.
|
|
- **Cluster tooling**: `kubectl` is copied from the official `registry.k8s.io/kubectl` image (multi-stage COPY).
|
|
- **Entrypoint**: `["opencode"]` — arguments are passed at runtime (e.g. `serve`).
|
|
|
|
## Jenkinsfile conventions
|
|
|
|
- The pipeline runs on a `@midnight` cron trigger for nightly rebuilds.
|
|
- Build uses `--no-cache --pull` to always fetch the latest base image and package version.
|
|
- Docker Hub credentials are stored under the `dockerhub_jcabillot` Jenkins credential ID.
|
|
- The image is published as `jcabillot/opencode` (no explicit tag = `latest`).
|
|
|
|
## Useful commands
|
|
|
|
```bash
|
|
# Build the image locally
|
|
docker build -t opencode .
|
|
|
|
# Run the server on all interfaces
|
|
docker run -it -p 4096:4096 opencode --hostname 0.0.0.0
|
|
|
|
# Run with a project mounted
|
|
docker run -it -p 4096:4096 \
|
|
-v $(pwd):/home/opencode/project \
|
|
opencode --hostname 0.0.0.0
|
|
|
|
# Protect with a password
|
|
docker run -it -p 4096:4096 \
|
|
-e OPENCODE_SERVER_PASSWORD=secret \
|
|
opencode --hostname 0.0.0.0
|
|
```
|
|
|
|
## opencode serve options
|
|
|
|
| Flag | Default | Description |
|
|
|------|---------|-------------|
|
|
| `--port` | `4096` | Port to listen on |
|
|
| `--hostname` | `127.0.0.1` | Hostname to bind |
|
|
| `--mdns` | `false` | Enable mDNS discovery |
|
|
| `--cors` | `[]` | Additional allowed browser origins |
|
|
|
|
## Environment variables
|
|
|
|
| Variable | Description |
|
|
|----------|-------------|
|
|
| `OPENCODE_SERVER_PASSWORD` | Enables HTTP basic auth |
|
|
| `OPENCODE_SERVER_USERNAME` | Overrides the default username (`opencode`) |
|