feat: import
Some checks failed
perso/opencode/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
Julien Cabillot
2026-03-27 17:26:11 -04:00
parent 9a303b49e5
commit 59d62367b3
5 changed files with 223 additions and 1 deletions

65
AGENTS.md Normal file
View File

@@ -0,0 +1,65 @@
# 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)
└── README.md # Usage documentation
```
## Dockerfile conventions
- **Base image**: `node:24-alpine` — use the latest Node.js LTS Alpine image.
- **Install**: `npm i -g opencode-ai` — installs OpenCode globally.
- **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 `addgroup`/`adduser`. All runtime steps run as this user.
- **Entrypoint**: `["opencode", "serve"]` — the container always starts the HTTP server.
## 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`) |

19
Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
FROM node:24
RUN apt-get update && apt-get upgrade -y && \
rm -rf /var/lib/apt/lists/*
RUN groupadd -r opencode && useradd -m -r -g opencode opencode
RUN npm update -g && \
npm install -g opencode-ai && \
npm cache clean --force
COPY --chmod=755 opencode-attach /usr/local/bin/opencode-attach
USER opencode
WORKDIR /home/opencode
RUN opencode --version
ENTRYPOINT ["opencode"]

38
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,38 @@
pipeline {
environment {
registry = 'https://registry.hub.docker.com'
registryCredential = 'dockerhub_jcabillot'
dockerImage = 'jcabillot/opencode'
}
agent any
triggers {
cron('@midnight')
}
stages {
stage('Clone repository') {
steps{
checkout scm
}
}
stage('Build image') {
steps{
sh 'docker build --force-rm=true --no-cache=true --pull -t ${dockerImage} .'
}
}
stage('Deploy Image') {
steps{
script {
withCredentials([usernamePassword(credentialsId: 'dockerhub_jcabillot', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh 'docker login --username ${DOCKER_USER} --password ${DOCKER_PASS}'
sh 'docker push ${dockerImage}'
}
}
}
}
}
}

View File

@@ -1,2 +1,95 @@
# opencode
# opencode Docker
Docker image for running [OpenCode](https://opencode.ai) as a headless HTTP server.
## 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.
## Pull
```bash
docker pull jcabillot/opencode
```
The image is rebuilt and pushed to Docker Hub automatically every night via the Jenkins pipeline.
## Build locally
```bash
docker build -t opencode .
```
## Run
```bash
docker run -it -p 4096:4096 jcabillot/opencode
```
By default the server listens on `127.0.0.1:4096`. To expose it on all interfaces:
```bash
docker run -it -p 4096:4096 jcabillot/opencode --hostname 0.0.0.0
```
### Mount a project
```bash
docker run -it -p 4096:4096 \
-v $(pwd):/home/opencode/project \
jcabillot/opencode --hostname 0.0.0.0
```
### Secure with a password
```bash
docker run -it -p 4096:4096 \
-e OPENCODE_SERVER_PASSWORD=your-password \
jcabillot/opencode --hostname 0.0.0.0
```
Authentication uses HTTP basic auth. The default username is `opencode`, override it with `OPENCODE_SERVER_USERNAME`.
## Troubleshooting helper
The image includes an `opencode-attach` wrapper in `PATH` that runs:
```bash
opencode attach -p "${OPENCODE_SERVER_PASSWORD}" "${OPENCODE_API_URL}"
```
Example:
```bash
export OPENCODE_SERVER_PASSWORD=your-password
export OPENCODE_API_URL=http://127.0.0.1:4096
opencode-attach
```
## API
Once running, the server exposes an OpenAPI 3.1 spec at:
```
http://localhost:4096/doc
```
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 |
See the [OpenCode server docs](https://opencode.ai/docs/server/) for the full API reference.
## Image details
- **Base image**: `node:24` (Debian)
- **Install**: `opencode-ai` via npm global install
- **User**: dedicated non-root `opencode` user
- **Entrypoint**: `opencode serve`
- **Default port**: `4096`

7
opencode-attach Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -eu
: "${OPENCODE_SERVER_PASSWORD:?OPENCODE_SERVER_PASSWORD is required}"
: "${OPENCODE_API_URL:?OPENCODE_API_URL is required}"
exec opencode attach -p "${OPENCODE_SERVER_PASSWORD}" "${OPENCODE_API_URL}" "$@"