Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2153aa5659 | |||
| 0e4525ca53 | |||
| 43cecab0f7 | |||
| 2d9fadf220 | |||
| f08480182a | |||
| 5ec47fdf4b | |||
| 210cb7d1a1 | |||
| 0a3e142b8f | |||
| 158e1590a6 | |||
| 271dc2eb35 | |||
| 875afe0039 | |||
| 9e381ebe32 | |||
| 3e048218c3 | |||
| 6ecd65d18d |
@@ -31,6 +31,11 @@ WORKSPACE_PATH=~/projects
|
|||||||
# Path to SSH keys on host
|
# Path to SSH keys on host
|
||||||
SSH_KEY_PATH=~/.ssh
|
SSH_KEY_PATH=~/.ssh
|
||||||
|
|
||||||
|
# ── Locale (defaults to en_US.UTF-8) ─────────────────────────────────
|
||||||
|
# LANG=sv_SE.UTF-8
|
||||||
|
# LANGUAGE=sv_SE:sv
|
||||||
|
# LC_ALL=sv_SE.UTF-8
|
||||||
|
|
||||||
# ── oh-my-opencode-slim (multi-agent orchestration) ──────────────────
|
# ── oh-my-opencode-slim (multi-agent orchestration) ──────────────────
|
||||||
# Requires image built with INSTALL_OMOS=true
|
# Requires image built with INSTALL_OMOS=true
|
||||||
# ENABLE_OMOS=false
|
# ENABLE_OMOS=false
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# ── Shared machine setup ─────────────────────────────────────────────
|
||||||
|
# Your corporate signum / username (REQUIRED)
|
||||||
|
# This isolates your container, config, and data from other users.
|
||||||
|
SIGNUM=your-signum-here
|
||||||
|
|
||||||
|
# ── Provider ─────────────────────────────────────────────────────────
|
||||||
|
OPENCODE_PROVIDER=amazon-bedrock
|
||||||
|
OPENCODE_MODEL=amazon-bedrock/eu.anthropic.claude-opus-4-6-v1
|
||||||
|
AWS_REGION=eu-west-1
|
||||||
|
AWS_PROFILE=default
|
||||||
|
|
||||||
|
# ── Git ──────────────────────────────────────────────────────────────
|
||||||
|
GIT_USER_NAME=Your Name
|
||||||
|
GIT_USER_EMAIL=your.name@example.com
|
||||||
|
|
||||||
|
# ── Paths (adjust to your layout) ───────────────────────────────────
|
||||||
|
# Default: ~/src mounted as /workspace
|
||||||
|
# WORKSPACE_PATH=~/src
|
||||||
|
|
||||||
|
# SSH keys — defaults to shared ~/.ssh
|
||||||
|
# If you have per-user keys: SSH_KEY_PATH=~/<signum>/.ssh
|
||||||
|
# SSH_KEY_PATH=~/.ssh
|
||||||
|
|
||||||
|
# ── Locale (defaults to en_US.UTF-8) ────────────────────────────────
|
||||||
|
# LANG=sv_SE.UTF-8
|
||||||
|
# LANGUAGE=sv_SE:sv
|
||||||
|
# LC_ALL=sv_SE.UTF-8
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Project overview
|
||||||
|
|
||||||
|
Docker image packaging [opencode](https://opencode.ai) into a production-ready dev container. Two image variants (base and omos) are published to Docker Hub via Gitea Actions CI. Not a library or application — this is infrastructure (Dockerfile, entrypoint scripts, docker-compose, documentation).
|
||||||
|
|
||||||
|
## File roles
|
||||||
|
|
||||||
|
- `Dockerfile` — single multi-stage build for both variants. OMOS variant is controlled by `INSTALL_OMOS=true` build arg. All GitHub-sourced binaries are pinned with version ARGs.
|
||||||
|
- `entrypoint.sh` — runs as root: UID/GID adjustment, SSH permissions, volume ownership fixes. Then drops to developer via gosu.
|
||||||
|
- `entrypoint-user.sh` — runs as developer: git config, opencode.json generation from env vars, OMOS setup.
|
||||||
|
- `DOCKER_HUB.md` — pushed to Docker Hub description via CI API call. Must stay under 25KB. Short description field must be ≤100 bytes.
|
||||||
|
- `README.md` — source repo documentation. Must stay in sync with DOCKER_HUB.md (both describe the same features but for different audiences).
|
||||||
|
- `.gitea/workflows/docker-publish.yml` — CI pipeline: three parallel jobs (build-base, build-omos, update-description). Triggered by tag push only.
|
||||||
|
|
||||||
|
## Versioning scheme
|
||||||
|
|
||||||
|
Tags follow `v{opencode_version}{letter}` — e.g. `v1.4.3k`. The number matches the opencode npm version. The letter suffix increments for container-level changes (tooling, docs, CVE fixes) on the same opencode version. CI produces four Docker Hub tags per release: `vX.Y.Zn`, `latest`, `vX.Y.Zn-omos`, `latest-omos`.
|
||||||
|
|
||||||
|
## Critical conventions
|
||||||
|
|
||||||
|
- **entrypoint.sh volume ownership loop** — when adding a new named volume mount point, add it to the `for dir in ...` loop in `entrypoint.sh` so root-owned volumes get chowned on startup.
|
||||||
|
- **Three docs to keep in sync** — Dockerfile changes that add tools or features must be reflected in `README.md`, `DOCKER_HUB.md`, and `.env.example`. The docker-compose examples in both docs must match the source `docker-compose.yml` pattern.
|
||||||
|
- **GitHub-sourced binaries** — fzf, gosu, git-lfs, neovim, bat, eza, zoxide, uv, rustup are installed from upstream releases (not apt) with pinned versions. Use the same `ARCH` case-switch pattern for multi-arch support (amd64/arm64).
|
||||||
|
- **Shell scripts use `set -euo pipefail`** — both entrypoints are strict. Errors in volume chown or SSH permission operations are intentionally suppressed with `|| true`.
|
||||||
|
- **Docker Hub description update** — uses `/v2/auth/token` endpoint (not the deprecated `/v2/users/login`). Auth uses `identifier`/`secret` fields, returns `access_token`, sent as `Bearer`. Short description must be ≤100 bytes.
|
||||||
|
|
||||||
|
## CI quirks
|
||||||
|
|
||||||
|
- Both build jobs include an IPv4 preference step (`gai.conf` + `driver-opts: network=host` for buildx) to work around intermittent IPv6 failures on the Gitea runners.
|
||||||
|
- `update-description` job runs only when both builds succeed (`needs: [build-base, build-omos]`).
|
||||||
|
- Tags must be pushed to trigger CI. Pushing to `main` alone does not build images.
|
||||||
|
|
||||||
|
## Testing changes
|
||||||
|
|
||||||
|
No test suite. Verify by:
|
||||||
|
1. Building locally: `docker compose build`
|
||||||
|
2. Running: `docker compose run --rm devbox bash`
|
||||||
|
3. Checking tool availability inside container: `nvim --version`, `bat --version`, `uv --version`, etc.
|
||||||
|
4. For entrypoint changes: test with a non-1000 UID workspace to verify UID adjustment and volume ownership fixes.
|
||||||
|
|
||||||
|
## Commit style
|
||||||
|
|
||||||
|
Imperative mood, first line summarizes the change. Multi-line body explains "why" when non-obvious. Examples from history:
|
||||||
|
- `Fix ownership of named volume mount points in entrypoint`
|
||||||
|
- `Add uv package manager to base image for on-demand Python support`
|
||||||
|
- `Upgrade base image from Debian bookworm to trixie (current stable)`
|
||||||
+29
-7
@@ -114,6 +114,25 @@ The entrypoint automatically detects the owner of `/workspace` and adjusts the c
|
|||||||
| `USER_UID` | Container user UID | Auto-detect from `/workspace` owner |
|
| `USER_UID` | Container user UID | Auto-detect from `/workspace` owner |
|
||||||
| `USER_GID` | Container user GID | Auto-detect from `/workspace` owner |
|
| `USER_GID` | Container user GID | Auto-detect from `/workspace` owner |
|
||||||
|
|
||||||
|
### Locale and Editor
|
||||||
|
|
||||||
|
The container defaults to English (`en_US.UTF-8`) and neovim as the editor. Override via environment variables:
|
||||||
|
|
||||||
|
| Variable | Description | Default |
|
||||||
|
|---|---|---|
|
||||||
|
| `LANG` | System locale | `en_US.UTF-8` |
|
||||||
|
| `LANGUAGE` | Language priority list | `en_US:en` |
|
||||||
|
| `LC_ALL` | Override all locale settings | `en_US.UTF-8` |
|
||||||
|
| `EDITOR` | Default text editor | `nvim` |
|
||||||
|
|
||||||
|
All common UTF-8 locales are pre-generated in the image. Example for Swedish:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
LANG=sv_SE.UTF-8
|
||||||
|
LANGUAGE=sv_SE:sv
|
||||||
|
LC_ALL=sv_SE.UTF-8
|
||||||
|
```
|
||||||
|
|
||||||
## Initial Setup
|
## Initial Setup
|
||||||
|
|
||||||
### 1. Create host directories
|
### 1. Create host directories
|
||||||
@@ -157,7 +176,7 @@ GIT_USER_EMAIL=you@example.com
|
|||||||
**AWS Bedrock (SSO):**
|
**AWS Bedrock (SSO):**
|
||||||
```bash
|
```bash
|
||||||
OPENCODE_PROVIDER=amazon-bedrock
|
OPENCODE_PROVIDER=amazon-bedrock
|
||||||
OPENCODE_MODEL=amazon-bedrock/anthropic.claude-sonnet-4-5-v1
|
OPENCODE_MODEL=amazon-bedrock/eu.anthropic.claude-opus-4-6-v1
|
||||||
AWS_REGION=eu-west-1
|
AWS_REGION=eu-west-1
|
||||||
AWS_PROFILE=your-profile-name
|
AWS_PROFILE=your-profile-name
|
||||||
GIT_USER_NAME=Your Name
|
GIT_USER_NAME=Your Name
|
||||||
@@ -237,13 +256,13 @@ docker run -it --rm \
|
|||||||
|
|
||||||
## Python Development with uv
|
## Python Development with uv
|
||||||
|
|
||||||
The image includes [uv](https://docs.astral.sh/uv/), a fast Python package manager that replaces pip, venv, and pyenv. Python is not pre-installed but can be installed on demand:
|
The image includes Python 3.13 (from Debian Trixie) and [uv](https://docs.astral.sh/uv/), a fast Python package manager that replaces pip, venv, and pyenv:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install Python (persists across restarts with devbox-uv volume)
|
# Python 3.13 is available out of the box
|
||||||
uv python install 3.12
|
python3 --version
|
||||||
|
|
||||||
# Create a virtual environment and install dependencies
|
# Use uv for package management
|
||||||
uv venv
|
uv venv
|
||||||
uv pip install -r requirements.txt
|
uv pip install -r requirements.txt
|
||||||
|
|
||||||
@@ -255,6 +274,9 @@ uv run python script.py
|
|||||||
|
|
||||||
# Install standalone Python tools
|
# Install standalone Python tools
|
||||||
uvx ruff check .
|
uvx ruff check .
|
||||||
|
|
||||||
|
# Install a newer Python version (persists with devbox-uv volume)
|
||||||
|
uv python install 3.14
|
||||||
```
|
```
|
||||||
|
|
||||||
To persist Python installs across container restarts, add a named volume:
|
To persist Python installs across container restarts, add a named volume:
|
||||||
@@ -352,7 +374,7 @@ mkdir opencode-devbox && cd opencode-devbox
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
OPENCODE_PROVIDER=amazon-bedrock
|
OPENCODE_PROVIDER=amazon-bedrock
|
||||||
OPENCODE_MODEL=amazon-bedrock/anthropic.claude-sonnet-4-5-v1
|
OPENCODE_MODEL=amazon-bedrock/eu.anthropic.claude-opus-4-6-v1
|
||||||
AWS_REGION=eu-west-1
|
AWS_REGION=eu-west-1
|
||||||
AWS_PROFILE=your-profile-name
|
AWS_PROFILE=your-profile-name
|
||||||
GIT_USER_NAME=Your Name
|
GIT_USER_NAME=Your Name
|
||||||
@@ -432,7 +454,7 @@ docker compose run --rm devbox bash # interactive shell
|
|||||||
- **opencode** — AI coding assistant
|
- **opencode** — AI coding assistant
|
||||||
- **Node.js 22** — for npx-based MCP servers
|
- **Node.js 22** — for npx-based MCP servers
|
||||||
- **AWS CLI v2** — SSO and Bedrock authentication
|
- **AWS CLI v2** — SSO and Bedrock authentication
|
||||||
- **Dev tools** — git, git-lfs, ssh, ripgrep, fd, fzf, bat, eza, zoxide, uv, rustup, jq, make, curl, wget, neovim 0.12, tmux, htop, tree
|
- **Dev tools** — git, git-lfs, git-crypt, age, ssh, ripgrep, fd, fzf, bat, eza, zoxide, uv, rustup, jq, make, curl, wget, neovim 0.12, tmux, htop, tree
|
||||||
- **Non-root user** — runs as `developer` with UID auto-matched to workspace owner (sudo available)
|
- **Non-root user** — runs as `developer` with UID auto-matched to workspace owner (sudo available)
|
||||||
|
|
||||||
### OMOS image (`latest-omos`)
|
### OMOS image (`latest-omos`)
|
||||||
|
|||||||
+6
-3
@@ -5,7 +5,7 @@ ARG DEBIAN_VERSION=trixie-slim
|
|||||||
FROM debian:${DEBIAN_VERSION} AS base
|
FROM debian:${DEBIAN_VERSION} AS base
|
||||||
|
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
ARG OPENCODE_VERSION=1.4.3
|
ARG OPENCODE_VERSION=1.4.11
|
||||||
|
|
||||||
LABEL maintainer="joakimp"
|
LABEL maintainer="joakimp"
|
||||||
LABEL description="Portable opencode developer container"
|
LABEL description="Portable opencode developer container"
|
||||||
@@ -32,6 +32,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
make \
|
make \
|
||||||
patch \
|
patch \
|
||||||
diffutils \
|
diffutils \
|
||||||
|
git-crypt \
|
||||||
|
age \
|
||||||
sudo \
|
sudo \
|
||||||
locales \
|
locales \
|
||||||
procps \
|
procps \
|
||||||
@@ -107,12 +109,13 @@ RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "x86_64" ;; arm64) echo "aarch64"
|
|||||||
curl -fsSL "https://static.rust-lang.org/rustup/dist/${ARCH}-unknown-linux-gnu/rustup-init" -o /usr/local/bin/rustup-init && \
|
curl -fsSL "https://static.rust-lang.org/rustup/dist/${ARCH}-unknown-linux-gnu/rustup-init" -o /usr/local/bin/rustup-init && \
|
||||||
chmod +x /usr/local/bin/rustup-init
|
chmod +x /usr/local/bin/rustup-init
|
||||||
|
|
||||||
# Set locale
|
# Set locale — generate common UTF-8 locales (override via LANG/LC_ALL env vars)
|
||||||
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
|
RUN sed -i '/\.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
|
||||||
ENV LANG=en_US.UTF-8
|
ENV LANG=en_US.UTF-8
|
||||||
ENV LANGUAGE=en_US:en
|
ENV LANGUAGE=en_US:en
|
||||||
ENV LC_ALL=en_US.UTF-8
|
ENV LC_ALL=en_US.UTF-8
|
||||||
ENV EDITOR=nvim
|
ENV EDITOR=nvim
|
||||||
|
ENV PATH="/home/developer/.local/bin:/home/developer/.cargo/bin:${PATH}"
|
||||||
|
|
||||||
# ── Node.js (required for opencode v1.x install + MCP servers) ──────
|
# ── Node.js (required for opencode v1.x install + MCP servers) ──────
|
||||||
ARG NODE_VERSION=22
|
ARG NODE_VERSION=22
|
||||||
|
|||||||
@@ -117,6 +117,10 @@ docker compose exec -u developer devbox aws --version
|
|||||||
| `SSH_KEY_PATH` | Host SSH key directory | `~/.ssh` |
|
| `SSH_KEY_PATH` | Host SSH key directory | `~/.ssh` |
|
||||||
| `USER_UID` | Override container user UID | Auto-detect from `/workspace` |
|
| `USER_UID` | Override container user UID | Auto-detect from `/workspace` |
|
||||||
| `USER_GID` | Override container user GID | Auto-detect from `/workspace` |
|
| `USER_GID` | Override container user GID | Auto-detect from `/workspace` |
|
||||||
|
| `LANG` | System locale | `en_US.UTF-8` |
|
||||||
|
| `LANGUAGE` | Language priority list | `en_US:en` |
|
||||||
|
| `LC_ALL` | Override all locale settings | `en_US.UTF-8` |
|
||||||
|
| `EDITOR` | Default text editor | `nvim` |
|
||||||
| `ENABLE_OMOS` | Enable oh-my-opencode-slim multi-agent orchestration | `false` |
|
| `ENABLE_OMOS` | Enable oh-my-opencode-slim multi-agent orchestration | `false` |
|
||||||
| `OMOS_TMUX` | Enable tmux pane integration for OMOS | `false` |
|
| `OMOS_TMUX` | Enable tmux pane integration for OMOS | `false` |
|
||||||
| `OMOS_SKILLS` | Install OMOS recommended skills on first run | `true` |
|
| `OMOS_SKILLS` | Install OMOS recommended skills on first run | `true` |
|
||||||
@@ -153,13 +157,13 @@ volumes:
|
|||||||
|
|
||||||
### Python development with uv
|
### Python development with uv
|
||||||
|
|
||||||
The image includes [uv](https://docs.astral.sh/uv/), a fast Python package manager that replaces pip, venv, and pyenv. Python is not pre-installed but can be installed on demand:
|
The image includes Python 3.13 (from Debian Trixie) and [uv](https://docs.astral.sh/uv/), a fast Python package manager that replaces pip, venv, and pyenv:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install Python (persists across restarts with devbox-uv volume)
|
# Python 3.13 is available out of the box
|
||||||
uv python install 3.12
|
python3 --version
|
||||||
|
|
||||||
# Create a virtual environment and install dependencies
|
# Use uv for package management
|
||||||
uv venv
|
uv venv
|
||||||
uv pip install -r requirements.txt
|
uv pip install -r requirements.txt
|
||||||
|
|
||||||
@@ -171,6 +175,9 @@ uv run python script.py
|
|||||||
|
|
||||||
# Install standalone Python tools
|
# Install standalone Python tools
|
||||||
uvx ruff check .
|
uvx ruff check .
|
||||||
|
|
||||||
|
# Install a newer Python version (persists with devbox-uv volume)
|
||||||
|
uv python install 3.14
|
||||||
```
|
```
|
||||||
|
|
||||||
Python installations are stored in `~/.local/share/uv/`. To persist them across container restarts, add the `devbox-uv` named volume to your `docker-compose.yml`:
|
Python installations are stored in `~/.local/share/uv/`. To persist them across container restarts, add the `devbox-uv` named volume to your `docker-compose.yml`:
|
||||||
@@ -264,6 +271,39 @@ volumes:
|
|||||||
- devbox-vscode:/home/developer/.vscode-server
|
- devbox-vscode:/home/developer/.vscode-server
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Shared machine setup (multiple users, single OS account)
|
||||||
|
|
||||||
|
For machines where multiple users share one OS account (e.g. a common `garage` user), a separate compose file isolates each user's config and data using a `SIGNUM` variable.
|
||||||
|
|
||||||
|
Each user creates their own directory and setup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Replace <signum> with your username/identifier
|
||||||
|
mkdir -p ~/<signum>/opencode-devbox
|
||||||
|
cd ~/<signum>/opencode-devbox
|
||||||
|
|
||||||
|
# Copy the shared-machine compose and env files
|
||||||
|
cp /path/to/opencode-devbox/docker-compose.shared.yml docker-compose.yml
|
||||||
|
cp /path/to/opencode-devbox/.env.shared.example .env
|
||||||
|
|
||||||
|
# Create per-user config directory
|
||||||
|
mkdir -p ~/<signum>/.config/opencode
|
||||||
|
|
||||||
|
# Edit .env with your signum, provider, keys, etc.
|
||||||
|
vim .env
|
||||||
|
|
||||||
|
# Start
|
||||||
|
docker compose up -d
|
||||||
|
docker compose exec -u developer devbox-<signum> opencode
|
||||||
|
```
|
||||||
|
|
||||||
|
Each user's container, config, and named volumes are fully isolated:
|
||||||
|
- Container name: `devbox-<signum>` (no collisions)
|
||||||
|
- Named volumes: prefixed with the project directory name (automatic per-user isolation)
|
||||||
|
- Opencode config: `~/<signum>/.config/opencode/` (per-user settings, OMOS config, etc.)
|
||||||
|
|
||||||
|
See `docker-compose.shared.yml` and `.env.shared.example` for the full configuration.
|
||||||
|
|
||||||
### Rebuilding the Image
|
### Rebuilding the Image
|
||||||
|
|
||||||
`docker compose run` and `docker compose up` use the existing image — they **do not rebuild** when you change the Dockerfile or build args (e.g. updating `OPENCODE_VERSION`). Rebuild explicitly:
|
`docker compose run` and `docker compose up` use the existing image — they **do not rebuild** when you change the Dockerfile or build args (e.g. updating `OPENCODE_VERSION`). Rebuild explicitly:
|
||||||
@@ -438,7 +478,7 @@ Container (Debian trixie)
|
|||||||
├── oh-my-opencode-slim (optional — multi-agent orchestration plugin, includes Bun)
|
├── oh-my-opencode-slim (optional — multi-agent orchestration plugin, includes Bun)
|
||||||
├── AWS CLI v2 (SSO + Bedrock auth)
|
├── AWS CLI v2 (SSO + Bedrock auth)
|
||||||
├── neovim 0.12, tmux, htop, bat, eza, zoxide, uv, rustup, make
|
├── neovim 0.12, tmux, htop, bat, eza, zoxide, uv, rustup, make
|
||||||
├── git, ssh, ripgrep, fd, fzf, jq, curl, tree
|
├── git, git-crypt, age, ssh, ripgrep, fd, fzf, jq, curl, tree
|
||||||
├── Node.js (for MCP servers)
|
├── Node.js (for MCP servers)
|
||||||
├── Bun (optional — included with oh-my-opencode-slim)
|
├── Bun (optional — included with oh-my-opencode-slim)
|
||||||
├── entrypoint.sh (UID adjustment, git config, provider setup)
|
├── entrypoint.sh (UID adjustment, git config, provider setup)
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# opencode-devbox docker-compose for shared machines
|
||||||
|
#
|
||||||
|
# For machines where multiple users share one OS account (e.g. 'garage').
|
||||||
|
# Each user gets isolated config, data, and named volumes by setting
|
||||||
|
# SIGNUM in their .env file.
|
||||||
|
#
|
||||||
|
# Setup per user:
|
||||||
|
# 1. mkdir -p ~/<signum>/opencode-devbox && cd ~/<signum>/opencode-devbox
|
||||||
|
# 2. cp docker-compose.shared.yml docker-compose.yml
|
||||||
|
# 3. cp .env.shared.example .env
|
||||||
|
# 4. Edit .env with your signum, provider, keys, etc.
|
||||||
|
# 5. mkdir -p ~/<signum>/.config/opencode
|
||||||
|
# 6. docker compose up -d
|
||||||
|
#
|
||||||
|
# Named volumes are automatically isolated per user because Docker Compose
|
||||||
|
# prefixes them with the project directory name (e.g. opencode-devbox_devbox-data).
|
||||||
|
# Since each user runs from ~/<signum>/opencode-devbox/, volumes don't collide.
|
||||||
|
|
||||||
|
services:
|
||||||
|
devbox:
|
||||||
|
image: joakimp/opencode-devbox:latest
|
||||||
|
container_name: devbox-${SIGNUM:?Set SIGNUM in .env}
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
- TERM=xterm-256color
|
||||||
|
volumes:
|
||||||
|
# Host workspace — user's project directory
|
||||||
|
- ${WORKSPACE_PATH:-~/src}:/workspace
|
||||||
|
|
||||||
|
# SSH keys — user-specific if available, else shared
|
||||||
|
- ${SSH_KEY_PATH:-~/.ssh}:/home/developer/.ssh:ro
|
||||||
|
|
||||||
|
# Opencode config — per-user (persists settings across restarts)
|
||||||
|
- ${HOME}/${SIGNUM}/.config/opencode:/home/developer/.config/opencode
|
||||||
|
|
||||||
|
# Persist opencode data (auth, memory, session history)
|
||||||
|
- devbox-data:/home/developer/.local/share/opencode
|
||||||
|
|
||||||
|
# Persist uv data (Python installs)
|
||||||
|
- devbox-uv:/home/developer/.local/share/uv
|
||||||
|
|
||||||
|
# Optional: AWS credentials (per-user if available)
|
||||||
|
# - ${HOME}/${SIGNUM}/.aws:/home/developer/.aws
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
devbox-data:
|
||||||
|
devbox-uv:
|
||||||
+2
-1
@@ -48,7 +48,8 @@ EOF
|
|||||||
"provider": {
|
"provider": {
|
||||||
"amazon-bedrock": {
|
"amazon-bedrock": {
|
||||||
"options": {
|
"options": {
|
||||||
"region": "${AWS_REGION:-us-east-1}"
|
"region": "${AWS_REGION:-us-east-1}",
|
||||||
|
"profile": "${AWS_PROFILE:-default}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,5 +46,24 @@ if [ -d "/home/$USER_NAME/.ssh" ] && [ "$(ls -A "/home/$USER_NAME/.ssh" 2>/dev/n
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ── Fix ownership of named volume mount points ──────────────────────
|
||||||
|
# Named volumes are created as root on first use. Fix ownership so the
|
||||||
|
# developer user can write to them.
|
||||||
|
FINAL_UID="${TARGET_UID:-$CURRENT_UID}"
|
||||||
|
FINAL_GID="${TARGET_GID:-$CURRENT_GID}"
|
||||||
|
for dir in \
|
||||||
|
/home/"$USER_NAME"/.local/share/opencode \
|
||||||
|
/home/"$USER_NAME"/.local/share/uv \
|
||||||
|
/home/"$USER_NAME"/.rustup \
|
||||||
|
/home/"$USER_NAME"/.cargo \
|
||||||
|
/home/"$USER_NAME"/.vscode-server \
|
||||||
|
/home/"$USER_NAME"/.config/opencode \
|
||||||
|
/home/"$USER_NAME"/.config/nvim \
|
||||||
|
/home/"$USER_NAME"/.agents/skills; do
|
||||||
|
if [ -d "$dir" ] && [ "$(stat -c '%u' "$dir" 2>/dev/null)" != "$FINAL_UID" ]; then
|
||||||
|
chown -R "$FINAL_UID":"$FINAL_GID" "$dir" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# ── Drop to developer user for remaining setup ──────────────────────
|
# ── Drop to developer user for remaining setup ──────────────────────
|
||||||
exec gosu "$USER_NAME" /usr/local/bin/entrypoint-user.sh "$@"
|
exec gosu "$USER_NAME" /usr/local/bin/entrypoint-user.sh "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user