Compare commits
1
Commits
main
..
7d02622321
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d02622321 |
No files matched your search
@@ -9,27 +9,27 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387 # v3.5.0
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
with:
|
with:
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- run: docker build -t ci-image:${{ github.sha }} .
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
|
|
||||||
build-push:
|
build-push:
|
||||||
needs: [test]
|
needs: [test]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
|
- uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
images: jcabillot/opencode
|
images: jcabillot/opencode
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=${{ steps.get-latest-tag.outputs.tag }}-latest,enable=${{ steps.get-latest-tag.outputs.tag != '' }}
|
type=raw,value=${{ steps.get-latest-tag.outputs.tag }}-latest,enable=${{ steps.get-latest-tag.outputs.tag != '' }}
|
||||||
- uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
- uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
|
|||||||
@@ -7,28 +7,28 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387 # v3.5.0
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
with:
|
with:
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- run: docker build -t ci-image:${{ github.sha }} .
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
build:
|
build:
|
||||||
needs: [test]
|
needs: [test]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- run: docker build -t jcabillot/opencode:${{ github.sha }} .
|
- run: docker build -t jcabillot/opencode:${{ github.sha }} .
|
||||||
tag:
|
tag:
|
||||||
needs: [build]
|
needs: [build]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Configure git auth
|
- name: Configure git auth
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ jobs:
|
|||||||
hadolint:
|
hadolint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387 # v3.5.0
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
with:
|
with:
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
build-test:
|
build-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- run: docker build -t ci-image:${{ github.sha }} .
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
name: Renovate
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
renovate:
|
|
||||||
uses: perso/gitea-pipelines/.gitea/workflows/renovate.yaml@main
|
|
||||||
secrets: inherit
|
|
||||||
@@ -9,25 +9,25 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: hadolint/hadolint-action@06be81baf89a55ffd0e24b8f04a4185738dd3387 # v3.5.0
|
- uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
with:
|
with:
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- run: docker build -t ci-image:${{ github.sha }} .
|
- run: docker build -t ci-image:${{ github.sha }} .
|
||||||
|
|
||||||
build-push:
|
build-push:
|
||||||
needs: [test]
|
needs: [test]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
|
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
|
- uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
@@ -38,7 +38,7 @@ jobs:
|
|||||||
tags: |
|
tags: |
|
||||||
type=ref,event=tag
|
type=ref,event=tag
|
||||||
type=ref,event=tag,suffix=-latest
|
type=ref,event=tag,suffix=-latest
|
||||||
- uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
- uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Project overview
|
## Project overview
|
||||||
|
|
||||||
This repository builds and publishes a Docker image for [OpenCode](https://opencode.ai), the open source AI coding agent. The image ships OpenCode 2, runs it in headless server mode (`opencode serve`), and is automatically rebuilt and pushed to Docker Hub (`jcabillot/opencode`) every night by a Gitea Actions pipeline.
|
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 Gitea Actions pipeline.
|
||||||
|
|
||||||
## Repository structure
|
## Repository structure
|
||||||
|
|
||||||
@@ -17,25 +17,18 @@ This repository builds and publishes a Docker image for [OpenCode](https://openc
|
|||||||
|
|
||||||
## Dependency management
|
## Dependency management
|
||||||
|
|
||||||
- **Always pin versions** in the Dockerfile `npm install` command (e.g. `@opencode/cli@2.0.32 n2-soul@9.0.9`). Never leave packages unpinned.
|
- **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.
|
- **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.
|
- **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
|
## Dockerfile conventions
|
||||||
|
|
||||||
- **Base image**: `node:26-trixie` — Debian-based Node.js image (not Alpine) so that downstream images can still use `apt-get` and Node-based MCP servers keep working.
|
- **Base image**: `node:24` — Debian-based Node.js image (not Alpine, needed for apt packages).
|
||||||
- **Install**: `npm i -g @opencode/cli@<version> n2-soul@<version>` — installs OpenCode 2 and Soul globally, both pinned. `@opencode/cli` replaced `opencode-ai` as the published package in OpenCode 2; `--allow-scripts=@opencode/cli` is required for its `postinstall` to select the native binary.
|
- **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.
|
- **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.
|
- **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).
|
- **Cluster tooling**: `kubectl` is copied from the official `registry.k8s.io/kubectl` image (multi-stage COPY).
|
||||||
- **Entrypoint**: `["opencode"]` — arguments are passed at runtime; `serve` starts the headless server. Bare `opencode` opens the TUI, so the server is always invoked explicitly.
|
- **Entrypoint**: `["opencode"]` — arguments are passed at runtime (e.g. `serve`).
|
||||||
|
|
||||||
## OpenCode 2 notes
|
|
||||||
|
|
||||||
- The npm package is `@opencode/cli` (bins `opencode` and `opencode2`); `opencode-ai` stops at 1.19.x and must not come back.
|
|
||||||
- `opencode attach` no longer exists: point a client at a server with `opencode --server <url>` (after the subcommand when one is given). `opencode-attach` wraps this.
|
|
||||||
- The server always authenticates: username is fixed to `opencode`, password comes from `OPENCODE_SERVER_PASSWORD` or `OPENCODE_PASSWORD`, and a random one is generated and logged when neither is set.
|
|
||||||
- The v1 REST API was replaced (`/global/health` is gone, every route now lives under `/api/*` and requires auth). Any client calling the v1 API — e.g. `perso/opencode-dispatch` — must be migrated separately.
|
|
||||||
|
|
||||||
## CI/CD conventions (Gitea Actions)
|
## CI/CD conventions (Gitea Actions)
|
||||||
|
|
||||||
@@ -51,17 +44,17 @@ This repository builds and publishes a Docker image for [OpenCode](https://openc
|
|||||||
docker build -t opencode .
|
docker build -t opencode .
|
||||||
|
|
||||||
# Run the server on all interfaces
|
# Run the server on all interfaces
|
||||||
docker run -it -p 4096:4096 opencode serve --hostname 0.0.0.0
|
docker run -it -p 4096:4096 opencode --hostname 0.0.0.0
|
||||||
|
|
||||||
# Run with a project mounted
|
# Run with a project mounted
|
||||||
docker run -it -p 4096:4096 \
|
docker run -it -p 4096:4096 \
|
||||||
-v $(pwd):/home/opencode/project \
|
-v $(pwd):/home/opencode/project \
|
||||||
opencode serve --hostname 0.0.0.0
|
opencode --hostname 0.0.0.0
|
||||||
|
|
||||||
# Protect with a password
|
# Protect with a password
|
||||||
docker run -it -p 4096:4096 \
|
docker run -it -p 4096:4096 \
|
||||||
-e OPENCODE_SERVER_PASSWORD=secret \
|
-e OPENCODE_SERVER_PASSWORD=secret \
|
||||||
opencode serve --hostname 0.0.0.0
|
opencode --hostname 0.0.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
## opencode serve options
|
## opencode serve options
|
||||||
@@ -70,15 +63,12 @@ docker run -it -p 4096:4096 \
|
|||||||
|------|---------|-------------|
|
|------|---------|-------------|
|
||||||
| `--port` | `4096` | Port to listen on |
|
| `--port` | `4096` | Port to listen on |
|
||||||
| `--hostname` | `127.0.0.1` | Hostname to bind |
|
| `--hostname` | `127.0.0.1` | Hostname to bind |
|
||||||
| `--cors` | `[]` | Additional allowed browser origins (repeatable) |
|
| `--mdns` | `false` | Enable mDNS discovery |
|
||||||
| `--service` | `false` | Run as the shared background service |
|
| `--cors` | `[]` | Additional allowed browser origins |
|
||||||
| `--stdio` | `false` | Serve over stdio for editor integrations |
|
|
||||||
|
|
||||||
## Environment variables
|
## Environment variables
|
||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `OPENCODE_SERVER_PASSWORD` | Server password (HTTP basic auth, username `opencode`) |
|
| `OPENCODE_SERVER_PASSWORD` | Enables HTTP basic auth |
|
||||||
| `OPENCODE_PASSWORD` | Same, takes precedence over `OPENCODE_SERVER_PASSWORD` |
|
| `OPENCODE_SERVER_USERNAME` | Overrides the default username (`opencode`) |
|
||||||
|
|
||||||
`OPENCODE_SERVER_USERNAME` existed in OpenCode 1 and is no longer read: the username is always `opencode`.
|
|
||||||
+4
-8
@@ -1,10 +1,9 @@
|
|||||||
FROM node:26-trixie
|
FROM node:24-trixie
|
||||||
|
|
||||||
ENV NPM_CONFIG_UPDATE_NOTIFIER=false \
|
ENV NPM_CONFIG_UPDATE_NOTIFIER=false \
|
||||||
NPM_CONFIG_LOGLEVEL=warn \
|
NPM_CONFIG_LOGLEVEL=warn \
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get upgrade -y --no-install-recommends ca-certificates && \
|
apt-get upgrade -y --no-install-recommends ca-certificates && \
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
@@ -13,16 +12,13 @@ RUN apt-get update && \
|
|||||||
groupadd -g 1000 opencode; \
|
groupadd -g 1000 opencode; \
|
||||||
useradd -m -u 1000 -g 1000 -s /usr/bin/bash opencode; \
|
useradd -m -u 1000 -g 1000 -s /usr/bin/bash opencode; \
|
||||||
npm update -g --no-fund --no-audit && \
|
npm update -g --no-fund --no-audit && \
|
||||||
npm install -g --no-fund --no-audit --ignore-scripts n2-soul@9.0.9 && \
|
npm install -g --no-fund --no-audit opencode-ai@1.17.15 n2-soul@9.0.9 && \
|
||||||
npm install -g --no-fund --no-audit --allow-scripts=better-sqlite3 better-sqlite3@12.11.1 && \
|
|
||||||
rm -rf /usr/local/lib/node_modules/n2-soul/node_modules/better-sqlite3 && \
|
|
||||||
npm install -g --no-fund --no-audit --allow-scripts=@opencode/cli @opencode/cli@2.0.32 && \
|
|
||||||
npm cache clean --force && \
|
npm cache clean --force && \
|
||||||
chown -R 1000:1000 /usr/local/lib/node_modules/n2-soul/
|
chown -R 1000:1000 /usr/local/lib/node_modules/n2-soul/
|
||||||
|
|
||||||
COPY --chmod=755 opencode-attach /usr/local/bin/opencode-attach
|
COPY --chmod=755 opencode-attach /usr/local/bin/opencode-attach
|
||||||
COPY --from=registry.k8s.io/kubectl:v1.37.1 /bin/kubectl /usr/local/bin/kubectl
|
COPY --from=registry.k8s.io/kubectl:v1.36.2 /bin/kubectl /usr/local/bin/kubectl
|
||||||
# hadolint ignore=DL3066
|
|
||||||
USER opencode
|
USER opencode
|
||||||
WORKDIR /home/opencode
|
WORKDIR /home/opencode
|
||||||
|
|
||||||
|
|||||||
Vendored
+38
@@ -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}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ Docker image for running [OpenCode](https://opencode.ai) as a headless HTTP serv
|
|||||||
|
|
||||||
## What is OpenCode?
|
## What is OpenCode?
|
||||||
|
|
||||||
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.
|
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
|
## Pull
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ OpenCode is an open source AI coding agent available as a terminal interface, de
|
|||||||
docker pull jcabillot/opencode
|
docker pull jcabillot/opencode
|
||||||
```
|
```
|
||||||
|
|
||||||
The image is rebuilt and pushed to Docker Hub automatically every night by the Gitea Actions pipeline.
|
The image is rebuilt and pushed to Docker Hub automatically every night via the Jenkins pipeline.
|
||||||
|
|
||||||
## Build locally
|
## Build locally
|
||||||
|
|
||||||
@@ -22,16 +22,14 @@ docker build -t opencode .
|
|||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
The entrypoint is the `opencode` binary; pass `serve` to start the headless server:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -it -p 4096:4096 jcabillot/opencode serve
|
docker run -it -p 4096:4096 jcabillot/opencode
|
||||||
```
|
```
|
||||||
|
|
||||||
The server listens on `127.0.0.1:4096` by default. To expose it on all interfaces:
|
By default the server listens on `127.0.0.1:4096`. To expose it on all interfaces:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -it -p 4096:4096 jcabillot/opencode serve --hostname 0.0.0.0
|
docker run -it -p 4096:4096 jcabillot/opencode --hostname 0.0.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
### Mount a project
|
### Mount a project
|
||||||
@@ -39,7 +37,7 @@ docker run -it -p 4096:4096 jcabillot/opencode serve --hostname 0.0.0.0
|
|||||||
```bash
|
```bash
|
||||||
docker run -it -p 4096:4096 \
|
docker run -it -p 4096:4096 \
|
||||||
-v $(pwd):/home/opencode/project \
|
-v $(pwd):/home/opencode/project \
|
||||||
jcabillot/opencode serve --hostname 0.0.0.0
|
jcabillot/opencode --hostname 0.0.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
### Secure with a password
|
### Secure with a password
|
||||||
@@ -47,17 +45,17 @@ docker run -it -p 4096:4096 \
|
|||||||
```bash
|
```bash
|
||||||
docker run -it -p 4096:4096 \
|
docker run -it -p 4096:4096 \
|
||||||
-e OPENCODE_SERVER_PASSWORD=your-password \
|
-e OPENCODE_SERVER_PASSWORD=your-password \
|
||||||
jcabillot/opencode serve --hostname 0.0.0.0
|
jcabillot/opencode --hostname 0.0.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
Authentication uses HTTP basic auth. The default username is `opencode`, override it with `OPENCODE_SERVER_USERNAME`.
|
||||||
|
|
||||||
## Troubleshooting helper
|
## Troubleshooting helper
|
||||||
|
|
||||||
The image includes an `opencode-attach` wrapper in `PATH` that runs:
|
The image includes an `opencode-attach` wrapper in `PATH` that runs:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
opencode --server "${OPENCODE_API_URL}"
|
opencode attach -p "${OPENCODE_SERVER_PASSWORD}" "${OPENCODE_API_URL}"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@@ -68,39 +66,31 @@ export OPENCODE_API_URL=http://127.0.0.1:4096
|
|||||||
opencode-attach
|
opencode-attach
|
||||||
```
|
```
|
||||||
|
|
||||||
Extra arguments are forwarded to the client, with `--server` appended to the subcommand:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
opencode-attach session list --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
Once running, the server exposes an OpenAPI 3.1 spec at:
|
Once running, the server exposes an OpenAPI 3.1 spec at:
|
||||||
|
|
||||||
```
|
```
|
||||||
http://localhost:4096/openapi.json
|
http://localhost:4096/doc
|
||||||
```
|
```
|
||||||
|
|
||||||
The web UI is served at `/` and is reachable without credentials; every `/api/*` route requires basic auth.
|
|
||||||
|
|
||||||
Key endpoints:
|
Key endpoints:
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| `GET` | `/api/info` | Health check and version |
|
| `GET` | `/global/health` | Health check and version |
|
||||||
| `GET` | `/api/session` | List sessions |
|
| `GET` | `/session` | List sessions |
|
||||||
| `POST` | `/api/session` | Create a session |
|
| `POST` | `/session` | Create a session |
|
||||||
| `POST` | `/api/session/:id/prompt` | Send a message |
|
| `POST` | `/session/:id/message` | Send a message |
|
||||||
| `GET` | `/api/event` | Server-sent events stream |
|
| `GET` | `/event` | Server-sent events stream |
|
||||||
|
|
||||||
See the [OpenCode v2 API reference](https://opencode.ai/v2/docs/api/) for the full API surface.
|
See the [OpenCode server docs](https://opencode.ai/docs/server/) for the full API reference.
|
||||||
|
|
||||||
## Image details
|
## Image details
|
||||||
|
|
||||||
- **Base image**: `node:26-trixie` (Debian)
|
- **Base image**: `node:24` (Debian)
|
||||||
- **Install**: `@opencode/cli` (OpenCode 2) via npm global install
|
- **Install**: `opencode-ai` via npm global install
|
||||||
- **User**: dedicated non-root `opencode` user
|
- **User**: dedicated non-root `opencode` user
|
||||||
- **Cluster tooling**: `kubectl` (copied from official registry image)
|
- **Cluster tooling**: `kubectl` (copied from official registry image)
|
||||||
- **Entrypoint**: `opencode`
|
- **Entrypoint**: `opencode serve`
|
||||||
- **Default port**: `4096`
|
- **Default port**: `4096`
|
||||||
+1
-9
@@ -45,12 +45,4 @@ trap cleanup_lock INT TERM EXIT
|
|||||||
kill_existing_instance
|
kill_existing_instance
|
||||||
printf '%s\n' "$$" > "$LOCKFILE"
|
printf '%s\n' "$$" > "$LOCKFILE"
|
||||||
|
|
||||||
# OpenCode 2 dropped `opencode attach`: a client is pointed at a server with
|
exec opencode attach -p "${OPENCODE_SERVER_PASSWORD}" "${OPENCODE_API_URL}" "$@"
|
||||||
# --server <url>, which must follow the subcommand when one is given.
|
|
||||||
if [ "$#" -eq 0 ]; then
|
|
||||||
set -- --server "${OPENCODE_API_URL}"
|
|
||||||
else
|
|
||||||
set -- "$@" --server "${OPENCODE_API_URL}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec opencode "$@"
|
|
||||||
+4
-4
@@ -12,12 +12,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"customType": "regex",
|
"customType": "regex",
|
||||||
"description": "Track @opencode/cli npm package pinned in Dockerfile RUN command",
|
"description": "Track opencode-ai npm package pinned in Dockerfile RUN command",
|
||||||
"managerFilePatterns": ["/^Dockerfile$/"],
|
"managerFilePatterns": ["/^Dockerfile$/"],
|
||||||
"matchStrings": ["@opencode/cli@(?<currentValue>[^\\s]+)"],
|
"matchStrings": ["opencode-ai@(?<currentValue>[^\\s]+)"],
|
||||||
"depNameTemplate": "@opencode/cli",
|
"depNameTemplate": "opencode-ai",
|
||||||
"datasourceTemplate": "npm",
|
"datasourceTemplate": "npm",
|
||||||
"versioningTemplate": "npm"
|
"versioningTemplate": "npm"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user