Files
opencode-container/README.md
T
2026-10-04 17:21:17 +02:00

294 lines
6.6 KiB
Markdown

# OpenCode Development Container
This repository provides a Podman-based development container for running an AI coding agent in an isolated and reproducible environment.
The container includes common software development tools, Node.js, OpenCode, Python, Java, Maven, Git, Neovim, and other command-line utilities.
The host project directory and selected development caches/configuration directories are mounted into the container.
## Requirements
* Linux
* Podman
* Bash
* A working internet connection when building the image
* CA certificates, if access to internal HTTPS services requires custom CAs
## Files
* `Dockerfile` — builds the development image.
* `build.sh` — builds or updates the image.
* `dev.sh` — starts the development container.
* `entrypoint.sh` — initializes the runtime environment.
## Build the image
Run:
```bash
./build.sh
```
The default image is:
```text
localhost/opencode-dev
```
The build uses the current host UID and GID for the `dev` user, so files created in mounted directories normally belong to the host user.
### Build without cache
```bash
./build.sh --no-cache
```
### Update the base image and Ubuntu packages
```bash
./build.sh --update
```
### Show the build command without running it
```bash
./build.sh --dry-run
```
## Build arguments
The following environment variables can be used to customize the image:
```bash
UBUNTU_VERSION=26.04
NODE_VERSION=24.21.0
OPENCODE_VERSION=2.0.3
IMAGE_REPO=localhost/opencode-dev
```
For example:
```bash
NODE_VERSION=24.21.0 OPENCODE_VERSION=2.0.3 ./build.sh --no-cache
```
## Custom CA certificates
Custom CA certificates must be placed in the repository `certs/` directory before building the image. See [`certs/README.md`](certs/README.md) for accepted formats and rules.
This directory is kept in git through a placeholder file, so a fresh clone builds without creating it first.
The Dockerfile copies this directory to:
```text
/usr/local/share/ca-certificates
```
and runs:
```bash
update-ca-certificates
```
The resulting system CA bundle is also exposed through:
```text
NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
```
This allows both system tools and Node.js applications to trust the additional certificates.
**Important:** CA certificates need to be present when the image is built. The runtime container does not install certificates from the host. After adding or removing a certificate, rebuild with `./build.sh --no-cache --update`.
## Run the container
Run:
```bash
./dev.sh
```
By default, the host directory is:
```text
$HOME/opencode-dev
```
and projects are stored in:
```text
$HOME/opencode-dev/projects
```
The container starts in `/workspace`.
To start in a specific project:
```bash
./dev.sh my-project
```
or:
```bash
./dev.sh /path/to/opencode-dev/projects/my-project
```
Absolute paths outside the projects directory are not accepted as the initial working directory.
## Mounted directories
The following host directories are mounted into the container:
| Host | Container | Purpose |
| ------------------ | --------------------------------- | -------------------------------- |
| `projects/` | `/workspace` | Source code |
| `opencode-config/` | `/home/dev/.config/opencode` | OpenCode configuration |
| `opencode-data/` | `/home/dev/.local/share/opencode` | OpenCode persistent data |
| `opencode-cache/` | `/home/dev/.cache/opencode` | OpenCode cache |
| `m2/` | `/home/dev/.m2` | Maven cache |
| `npm-cache/` | `/home/dev/.npm` | npm cache |
| `pip-cache/` | `/home/dev/.cache/pip` | pip cache |
| `bash/` | `/host-bash` | Host-provided Bash configuration |
| `$HOME/.gitconfig` | `/home/dev/.gitconfig` | Git configuration |
All standard development directories are created automatically by `dev.sh`.
## Additional mounts
Additional host directories can be mounted with `--mount`.
Example:
```bash
./dev.sh my-project --mount "$HOME/other:/extra"
```
Read-only mounts are also supported:
```bash
./dev.sh my-project --mount "$HOME/data:/data:ro"
```
Multiple mounts can be specified:
```bash
./dev.sh my-project \
--mount "$HOME/data:/data:ro" \
--mount "$HOME/tools:/tools:rw"
```
## Environment variables
The main runtime paths can be customized:
```bash
OPENCODE_DEV_HOME
PROJECT_DIR
OPENCODE_CONFIG
OPENCODE_SHARE_DATA
OPENCODE_CACHE
M2_FOLDER
NPM_CACHE
PIP_CACHE
BASH_FOLDER
IMAGE_REPO
```
Example:
```bash
OPENCODE_DEV_HOME="$HOME/my-opencode" ./dev.sh
```
## Git configuration
The host Git configuration is mounted read-only:
```text
$HOME/.gitconfig -> /home/dev/.gitconfig
```
If the file does not exist, the script prints a warning and Git uses the container defaults.
SSH configuration and SSH agent forwarding are currently disabled in the script. They can be enabled by uncommenting the corresponding sections in `dev.sh`.
## Security
The container runs with several restrictions:
* Runs as the `dev` user.
* Uses the host UID/GID.
* Drops all Linux capabilities.
* Uses `no-new-privileges`.
* Uses a temporary container (`--rm`).
* Does not run as root.
* Uses the default Podman network.
The project directory is mounted read/write because the AI agent needs to create and modify source files.
## Locale
The host locale is passed to the container through:
```text
HOST_LANG
HOST_LC_ALL
```
The entrypoint generates the requested UTF-8 locale when necessary.
For example, the host locale is automatically passed when running:
```bash
./dev.sh
```
## Typical workflow
Build the image:
```bash
./build.sh
```
Start the development environment:
```bash
./dev.sh
```
Or start directly in a project:
```bash
./dev.sh my-project
```
Inside the container, the project is available under:
```bash
/workspace
```
OpenCode can then be started normally:
```bash
opencode
```
The container is removed when the shell exits, while source code, OpenCode data, configuration, and development caches remain on the host.
## Customization
Most image versions are defined at the top of the `Dockerfile`:
```dockerfile
ARG UBUNTU_VERSION=26.04
ARG NODE_VERSION=24.21.0
ARG OPENCODE_VERSION=2.0.3
```
Runtime paths and container options are defined in `dev.sh`.
This separation allows the image to contain the stable development environment while projects, configuration, caches, and other working data remain outside the container.