Compare commits

...

5 Commits

4 changed files with 145 additions and 58 deletions
+90 -43
View File
@@ -46,25 +46,21 @@ docker run -d --name devbox \
joakimp/opencode-devbox:latest sleep infinity
# Shell 1: run opencode
docker exec -it devbox opencode
docker exec -it -u developer devbox opencode
# Shell 2 (separate terminal): aws, git, etc.
docker exec -it devbox bash
docker exec -it -u developer devbox bash
# When done
docker rm -f devbox
```
With docker-compose this is simpler:
```bash
docker compose up -d
docker compose exec devbox opencode # terminal 1
docker compose exec devbox bash # terminal 2
```
> **Note:** Always use `-u developer` with `docker exec` — the container starts as root for UID adjustment, then drops to `developer`. Without `-u developer`, exec runs as root.
## Environment Variables
All configuration is done via environment variables, typically stored in a `.env` file.
### Provider Configuration
| Variable | Description | Default |
@@ -87,14 +83,7 @@ Set the key matching your provider:
| Variable | Description | Default |
|---|---|---|
| `AWS_REGION` | AWS region | `us-east-1` |
| `AWS_PROFILE` | AWS profile name | `default` |
For SSO authentication, start with `bash` and run:
```bash
aws sso login --sso-session <your-session> --use-device-code
opencode
```
| `AWS_PROFILE` | AWS SSO profile name | `default` |
### Git
@@ -114,14 +103,66 @@ The entrypoint automatically detects the owner of `/workspace` and adjusts the c
| `USER_UID` | Container user UID | Auto-detect from `/workspace` owner |
| `USER_GID` | Container user GID | Auto-detect from `/workspace` owner |
## Initial Setup
### 1. Create a project directory
```bash
docker run -it --rm \
-e USER_UID=$(id -u) \
-e USER_GID=$(id -g) \
-v ~/projects:/workspace \
joakimp/opencode-devbox:latest
mkdir -p ~/projects
```
### 2. Create a `.env` file
Create a `.env` file with your configuration. Examples for each provider:
**Anthropic:**
```bash
OPENCODE_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
GIT_USER_NAME=Your Name
GIT_USER_EMAIL=you@example.com
```
**OpenAI:**
```bash
OPENCODE_PROVIDER=openai
OPENAI_API_KEY=sk-...
GIT_USER_NAME=Your Name
GIT_USER_EMAIL=you@example.com
```
**AWS Bedrock (SSO):**
```bash
OPENCODE_PROVIDER=amazon-bedrock
OPENCODE_MODEL=amazon-bedrock/anthropic.claude-sonnet-4-5-v1
AWS_REGION=eu-west-1
AWS_PROFILE=your-profile-name
GIT_USER_NAME=Your Name
GIT_USER_EMAIL=you@example.com
```
### 3. AWS SSO setup (Bedrock users only)
AWS SSO requires a `~/.aws/config` file on the host with your SSO session configuration. If you already have this on another machine, copy it:
```bash
scp -r user@other-machine:~/.aws ~/.aws
```
Or configure from scratch:
```bash
aws configure sso
```
You'll be prompted for:
- SSO session name
- SSO start URL
- SSO region
- Registration scopes (typically `sso:account:access`)
The `~/.aws` directory must be mounted into the container (see docker-compose example below).
## Data Storage and Persistence
Understanding what survives container restarts and what doesn't:
@@ -130,27 +171,16 @@ Understanding what survives container restarts and what doesn't:
|---|---|---|---|
| `/workspace` | Host bind mount | ✅ Yes — lives on host | Your project files |
| `/home/developer/.ssh` | Host bind mount (ro) | ✅ Yes — lives on host | SSH keys |
| `/home/developer/.aws` | Host bind mount | ✅ Yes — lives on host | AWS credentials/SSO cache |
| `/home/developer/.local/share/opencode` | Named volume (if configured) | ✅ Yes — Docker volume | Session history, memory, auth tokens |
| `/home/developer/.config/opencode/opencode.json` | Generated by entrypoint | ❌ No — regenerated each start | Provider config, MCP server definitions |
| `/home/developer/.aws` | Host bind mount (if configured) | ✅ Yes — lives on host | AWS credentials/SSO cache |
### Key points
- **Project files** (`/workspace`) are always safe — they're your host filesystem.
- **opencode config** is auto-generated from `OPENCODE_PROVIDER` env var on each start. It only sets provider and model — no MCP servers. To persist MCP server config, mount your own config file (see Custom opencode Config below).
- **opencode data** (session history, memory) is lost with `--rm` unless you add a named volume.
- **AWS SSO tokens** are stored inside the container and lost on restart. Re-run `aws sso login` after restarting.
### Persisting opencode data
Add a named volume to keep session history and memory between runs:
```bash
docker run -it --rm \
-v opencode-data:/home/developer/.local/share/opencode \
... \
joakimp/opencode-devbox:latest
```
- **AWS SSO tokens** persist across restarts when `~/.aws` is mounted (recommended for Bedrock users).
## Custom opencode Config
@@ -167,16 +197,19 @@ When a config file is mounted, the `OPENCODE_PROVIDER` auto-config is skipped.
## Using docker-compose
Create a `docker-compose.yml` and a `.env` file in the same directory:
Create a directory with a `docker-compose.yml` and a `.env` file:
```bash
mkdir opencode-devbox && cd opencode-devbox
```
`.env` — your secrets and settings (never commit this):
`.env` — your settings (never commit this):
```bash
ANTHROPIC_API_KEY=sk-ant-...
OPENCODE_PROVIDER=amazon-bedrock
OPENCODE_MODEL=amazon-bedrock/anthropic.claude-sonnet-4-5-v1
AWS_REGION=eu-west-1
AWS_PROFILE=your-profile-name
GIT_USER_NAME=Your Name
GIT_USER_EMAIL=you@example.com
```
@@ -189,16 +222,16 @@ services:
image: joakimp/opencode-devbox:latest
stdin_open: true
tty: true
env_file:
- .env
environment:
- TERM=xterm-256color
- OPENCODE_PROVIDER=anthropic
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- GIT_USER_NAME=${GIT_USER_NAME}
- GIT_USER_EMAIL=${GIT_USER_EMAIL}
volumes:
- ~/projects:/workspace
- ~/.ssh:/home/developer/.ssh:ro
- devbox-data:/home/developer/.local/share/opencode
# Mount AWS config for Bedrock SSO (required for amazon-bedrock provider)
# - ~/.aws:/home/developer/.aws
# Optional: mount your own opencode config (MCP servers, custom models, etc.)
# - ./opencode.json:/home/developer/.config/opencode/opencode.json:ro
# Optional: mount opencode skills from host
@@ -209,11 +242,25 @@ volumes:
devbox-data:
```
Docker Compose automatically loads `.env` from the same directory as the compose file. The `${VAR}` references are substituted with values from `.env`.
Docker Compose loads `.env` automatically from the same directory. All variables from `.env` are passed to the container via `env_file`. Do **not** hardcode provider settings in the `environment:` section — use `.env` instead.
Then:
```bash
# Start in background
docker compose up -d
# Open a shell (always use -u developer with exec)
docker compose exec -u developer devbox bash
# For Bedrock: authenticate, then start opencode
aws sso login --sso-session <your-session> --use-device-code
opencode
# Or run opencode directly (if no SSO needed)
docker compose exec -u developer devbox opencode
# One-shot mode (creates and removes container)
docker compose run --rm devbox # direct to opencode
docker compose run --rm devbox bash # interactive shell
```
+13 -2
View File
@@ -26,18 +26,29 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
jq \
ripgrep \
fd-find \
fzf \
tree \
less \
vim-tiny \
sudo \
gosu \
locales \
procps \
unzip \
&& ln -s /usr/bin/fdfind /usr/local/bin/fd \
&& rm -rf /var/lib/apt/lists/*
# ── gosu (install from GitHub to avoid CVEs in Debian's old Go-compiled package)
ARG GOSU_VERSION=1.19
RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "amd64" ;; arm64) echo "arm64" ;; *) echo "amd64" ;; esac) && \
curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${ARCH}" -o /usr/local/bin/gosu && \
chmod +x /usr/local/bin/gosu && \
gosu --version
# ── fzf (install from GitHub to avoid CVEs in Debian's old Go-compiled package)
ARG FZF_VERSION=0.71.0
RUN ARCH=$(case "${TARGETARCH}" in amd64) echo "amd64" ;; arm64) echo "arm64" ;; *) echo "amd64" ;; esac) && \
curl -fsSL "https://github.com/junegunn/fzf/releases/download/v${FZF_VERSION}/fzf-${FZF_VERSION}-linux_${ARCH}.tar.gz" | tar -xz -C /usr/local/bin fzf && \
fzf --version
# Set locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG=en_US.UTF-8
+39 -10
View File
@@ -76,10 +76,10 @@ docker compose run --rm devbox
docker compose up -d
# Attach a shell to the running container
docker compose exec devbox bash
docker compose exec -u developer devbox bash
# Or run a single command inside it
docker compose exec devbox aws --version
docker compose exec -u developer devbox aws --version
```
> `run` creates a new container (cleaned up with `--rm`). `exec` attaches to an already running one.
@@ -95,6 +95,7 @@ docker compose exec devbox aws --version
| `ANTHROPIC_API_KEY` | Anthropic API key | — |
| `OPENAI_API_KEY` | OpenAI API key | — |
| `AWS_REGION` | AWS region for Bedrock | `us-east-1` |
| `AWS_PROFILE` | AWS SSO profile name | `default` |
| `GIT_USER_NAME` | Git commit author name | — |
| `GIT_USER_EMAIL` | Git commit author email | — |
| `WORKSPACE_PATH` | Host path to mount | `.` |
@@ -150,11 +151,40 @@ docker compose build --build-arg OPENCODE_VERSION=1.5.0
## AWS Bedrock Authentication
When using AWS Bedrock as your LLM provider, you need to authenticate via AWS SSO from inside the container. Since the container runs headless (no browser), use the device-code flow:
When using AWS Bedrock as your LLM provider, you need:
### 1. AWS config on the host
The container needs access to your `~/.aws/config` with SSO session configuration. If you already have this on another machine, copy it:
```bash
# Start the container interactively
docker compose run --rm devbox bash
scp -r user@other-machine:~/.aws ~/.aws
```
Or configure from scratch on the host:
```bash
aws configure sso
```
### 2. Mount `~/.aws` into the container
Uncomment the AWS volume mount in `docker-compose.yml`:
```yaml
- ~/.aws:/home/developer/.aws
```
Note: do **not** use `:ro` — SSO writes token cache files to this directory.
### 3. Authenticate inside the container
Since the container runs headless (no browser), use the device-code flow:
```bash
# Start the container
docker compose up -d
docker compose exec -u developer devbox bash
# Authenticate — prints a URL and code you open in your local browser
aws sso login --sso-session <your-sso-session> --use-device-code
@@ -165,7 +195,7 @@ opencode
The `--use-device-code` flag outputs a URL and short code instead of trying to open a browser. Copy the URL into any browser (on your laptop, phone, etc.), enter the code, and complete the 2FA flow. The CLI in the container picks up the session automatically.
SSO sessions typically last 812 hours before requiring re-authentication.
SSO sessions typically last 812 hours before requiring re-authentication. Since `~/.aws` is mounted from the host, tokens persist across container restarts.
## Secret Scanning
@@ -201,6 +231,7 @@ Allowlisted paths and rules are in `.gitleaks.toml`. The defaults extend gitleak
Host Machine
├── ~/projects/my-app ──bind mount──▶ /workspace (container)
├── ~/.ssh ──bind mount──▶ /home/developer/.ssh (ro)
├── ~/.aws ──bind mount──▶ /home/developer/.aws (Bedrock SSO)
└── .env ──env vars───▶ provider config + API keys
Container (Debian bookworm)
@@ -208,7 +239,7 @@ Container (Debian bookworm)
├── AWS CLI v2 (SSO + Bedrock auth)
├── git, ssh, ripgrep, fd, jq, curl, fzf
├── Node.js (for MCP servers)
├── entrypoint.sh (SSH perms, git config, provider setup)
├── entrypoint.sh (UID adjustment, git config, provider setup)
└── /workspace ← your code lives here
```
@@ -218,14 +249,12 @@ Container (Debian bookworm)
|---|---|---|---|
| `/workspace` | Host bind mount | ✅ Yes | Your project files |
| `/home/developer/.ssh` | Host bind mount (ro) | ✅ Yes | SSH keys |
| `/home/developer/.aws` | Host bind mount (if configured) | ✅ Yes | AWS credentials/SSO cache |
| `/home/developer/.local/share/opencode` | Named volume `devbox-data` | ✅ Yes | Session history, memory |
| `/home/developer/.config/opencode/opencode.json` | Generated by entrypoint | ❌ No | Provider/model config |
| `/home/developer/.aws` | Not mounted by default | ❌ No | AWS SSO tokens |
**opencode config** (`opencode.json`) is auto-generated from `OPENCODE_PROVIDER` on each start. It sets provider and model only — no MCP servers. To use MCP servers or custom settings, mount your own config file (see Custom opencode config above).
To persist AWS SSO sessions across restarts, uncomment the `~/.aws` volume mount in `docker-compose.yml`.
## License
MIT
+3 -3
View File
@@ -3,7 +3,7 @@
# Usage:
# cp .env.example .env # configure your provider and keys
# docker compose up -d
# docker compose exec devbox opencode
# docker compose exec -u developer devbox opencode
#
# Or for interactive one-shot:
# docker compose run --rm devbox
@@ -40,8 +40,8 @@ services:
# Optional: persist opencode data (auth, memory, etc.)
- devbox-data:/home/developer/.local/share/opencode
# Optional: AWS credentials for Bedrock
# - ~/.aws:/home/developer/.aws:ro
# Optional: AWS credentials/SSO config (not read-only — SSO writes token cache)
# - ~/.aws:/home/developer/.aws
volumes:
devbox-data: