Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# AGENTS.md — docker-opencode

## Repo Overview

Docker-based AI development container. Provides OpenCode, uv, Bun, Node.js, and optional CUDA in an isolated Ubuntu 24.04 environment.

**Two images**: `Dockerfile.cpu` and `Dockerfile.gpu` (CUDA 12). Selected via `--profile cpu` or `--profile gpu` in docker compose.

---

## Key Directories

| Path | Purpose |
|------|---------|
| `configs/` | Env templates, OpenCode configs, agent templates |
| `configs/opencode/` | `oh-my-opencode-free.json` and `oh-my-opencode-paid.json` |
| `configs/templates/` | `AGENTS.md-global` (deployed to `~/.config/opencode/AGENTS.md` in container) |
| `data/` | Persistent per-project OpenCode data (gitignored) |
| `.github/workflows/` | CI: docker-build (PR/push), version-check (monthly cron) |

---

## Commands

```bash
# Create project config
cp configs/_template.env configs/my-project.env

# Start container
docker compose --env-file configs/my-project.env --profile cpu up -d

# Enter container
docker exec -it my-project-cpu bash

# Stop
docker compose --env-file configs/my-project.env down
```

Inside the container:
```bash
switch-opencode-config free # Free models (no API keys)
switch-opencode-config paid # GitHub Copilot models
switch-opencode-config default # Restore installer config
```

---

## Conventions

- **No hardcoded values**. All configurable values must be defined as constants, env vars, or in config files. Never inline literals for paths, ports, credentials, model names, or feature flags.
- `configs/*.env` files are gitignored except `_template.env`. Never commit personal configs or API keys.
- CI triggers on `Dockerfile.*`, `docker-compose.yml`, and workflow changes only.

---

## Git Rules

- NEVER execute git commands without explicit user permission. Read-only commands (status, log, diff) are allowed for context.
- NEVER mention AI tool names in comments, commit messages, or documentation.
- ALWAYS ask before creating branches for substantial changes. Suggest a branch name and wait for confirmation.
- NEVER commit unless explicitly requested.

---

## References

- Global agent rules: `configs/templates/AGENTS.md-global`
- Project-specific templates: `configs/templates/AGENTS.md-python`
- Full setup: `README.md`
55 changes: 23 additions & 32 deletions Dockerfile.cpu
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ ARG MYGID=1000
ARG USERNAME=hannya

ENV DEBIAN_FRONTEND=noninteractive
ENV HOME=/root

# ── System ────────────────────────────────────────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
Expand All @@ -25,24 +24,6 @@ RUN curl -fsSL https://nodejs.org/dist/v22.22.2/node-v22.22.2-linux-x64.tar.gz |
# ── uv ────────────────────────────────────────────────────────────────────────
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# ── Bun ───────────────────────────────────────────────────────────────────────
RUN curl -fsSL https://bun.sh/install | bash && \
cp $HOME/.bun/bin/bun /usr/local/bin/bun && \
cp $HOME/.bun/bin/bunx /usr/local/bin/bunx

# ── OpenCode + oh-my-openagent ───────────────────────────────────────────────
RUN curl -fsSL https://opencode.ai/install | bash
RUN npm install -g oh-my-opencode oh-my-opencode-linux-x64
RUN bunx oh-my-opencode install --no-tui --claude=no --openai=no --gemini=no --copilot=no --opencode-zen=yes

# Ensure opencode binary is on PATH
RUN cp $HOME/.opencode/bin/opencode /usr/local/bin/opencode

# Save generated config + templates to a safe location
RUN mkdir -p /opt/opencode-config && \
cp -r $HOME/.config/opencode/* /opt/opencode-config/ 2>/dev/null || true && \
cp $HOME/.config/opencode/oh-my-opencode.json /opt/opencode-config/oh-my-opencode.json.backup 2>/dev/null || true

# ── User ──────────────────────────────────────────────────────────────────────
RUN OLD_USER=$(awk -v uid="${MYUID}" -F ':' '$3==uid {print $1}' /etc/passwd) && \
if [ -z "${OLD_USER}" ]; then \
Expand All @@ -63,25 +44,35 @@ RUN OLD_USER=$(awk -v uid="${MYUID}" -F ':' '$3==uid {print $1}' /etc/passwd) &&
touch /home/${USERNAME}/.sudo_as_admin_successful && \
echo 'export PS1="\[\e[01;36m\][DOCKER] \u@\h\[\e[00m\]:\[\e[01;34m\]\w\[\e[00m\]\$ "' >> /home/${USERNAME}/.bashrc

ENV TERM=xterm-256color
ENV SHELL=/bin/bash
# ── Project configs ───────────────────────────────────────────────────────────
COPY --chown=${USERNAME}:${MYGID} configs/opencode/ /home/${USERNAME}/.config/opencode/
COPY --chown=${USERNAME}:${MYGID} configs/templates/AGENTS.md-global /home/${USERNAME}/.config/opencode/AGENTS.md
COPY --chown=${USERNAME}:${MYGID} configs/templates/switch-opencode-config.sh /usr/local/bin/switch-opencode-config
RUN chmod +x /usr/local/bin/switch-opencode-config

# ── Everything else as user ──────────────────────────────────────────────────
USER ${USERNAME}
ENV HOME=/home/${USERNAME}
ENV PATH="/home/${USERNAME}/.local/bin:/home/${USERNAME}/.bun/bin:${PATH}"
ENV PATH="/home/${USERNAME}/.opencode/bin:/home/${USERNAME}/.local/bin:/home/${USERNAME}/.bun/bin:${PATH}"

WORKDIR /workspace
# Bun
RUN curl -fsSL https://bun.sh/install | bash

# OpenCode
RUN curl -fsSL https://opencode.ai/install | bash

# oh-my-openagent
RUN bunx oh-my-openagent install --no-tui --claude=no --openai=no --gemini=no --copilot=no --opencode-zen=yes && \
cp ~/.config/opencode/oh-my-openagent.json ~/.config/opencode/oh-my-openagent-default.json

# ── Entrypoint ────────────────────────────────────────────────────────────────
COPY --chown=${USERNAME}:${MYGID} entrypoint.sh /entrypoint.sh
COPY --chown=${USERNAME}:${MYGID} configs/ /opt/project-configs/
RUN chmod +x /entrypoint.sh && \
chmod +x /opt/project-configs/templates/switch-opencode-config.sh && \
cp /opt/project-configs/templates/switch-opencode-config.sh /usr/local/bin/switch-opencode-config
RUN chmod +x /entrypoint.sh

# Copy project configs into the safe config dir
RUN cp /opt/project-configs/opencode/oh-my-opencode-free.json /opt/opencode-config/ 2>/dev/null || true && \
cp /opt/project-configs/opencode/oh-my-opencode-paid.json /opt/opencode-config/ 2>/dev/null || true && \
cp /opt/project-configs/templates/AGENTS.md-global /opt/opencode-config/AGENTS.md 2>/dev/null || true
ENV TERM=xterm-256color
ENV SHELL=/bin/bash

USER ${USERNAME}
WORKDIR /workspace

ENTRYPOINT ["/entrypoint.sh"]
CMD ["bash"]
55 changes: 23 additions & 32 deletions Dockerfile.gpu
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ ARG MYGID=1000
ARG USERNAME=hannya

ENV DEBIAN_FRONTEND=noninteractive
ENV HOME=/root

# ── System ────────────────────────────────────────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
Expand All @@ -28,24 +27,6 @@ RUN curl -fsSL https://nodejs.org/dist/v22.22.2/node-v22.22.2-linux-x64.tar.gz |
# ── uv ────────────────────────────────────────────────────────────────────────
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# ── Bun ───────────────────────────────────────────────────────────────────────
RUN curl -fsSL https://bun.sh/install | bash && \
cp $HOME/.bun/bin/bun /usr/local/bin/bun && \
cp $HOME/.bun/bin/bunx /usr/local/bin/bunx

# ── OpenCode + oh-my-openagent ───────────────────────────────────────────────
RUN curl -fsSL https://opencode.ai/install | bash
RUN npm install -g oh-my-opencode oh-my-opencode-linux-x64
RUN bunx oh-my-opencode install --no-tui --claude=no --openai=no --gemini=no --copilot=no --opencode-zen=yes

# Ensure opencode binary is on PATH
RUN cp $HOME/.opencode/bin/opencode /usr/local/bin/opencode

# Save generated config + templates to a safe location
RUN mkdir -p /opt/opencode-config && \
cp -r $HOME/.config/opencode/* /opt/opencode-config/ 2>/dev/null || true && \
cp $HOME/.config/opencode/oh-my-opencode.json /opt/opencode-config/oh-my-opencode.json.backup 2>/dev/null || true

# ── User ──────────────────────────────────────────────────────────────────────
RUN OLD_USER=$(awk -v uid="${MYUID}" -F ':' '$3==uid {print $1}' /etc/passwd) && \
if [ -z "${OLD_USER}" ]; then \
Expand All @@ -71,25 +52,35 @@ ENV NVIDIA_VISIBLE_DEVICES=all
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility,graphics
ENV LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:${LD_LIBRARY_PATH}

ENV TERM=xterm-256color
ENV SHELL=/bin/bash
# ── Project configs ───────────────────────────────────────────────────────────
COPY --chown=${USERNAME}:${MYGID} configs/opencode/ /home/${USERNAME}/.config/opencode/
COPY --chown=${USERNAME}:${MYGID} configs/templates/AGENTS.md-global /home/${USERNAME}/.config/opencode/AGENTS.md
COPY --chown=${USERNAME}:${MYGID} configs/templates/switch-opencode-config.sh /usr/local/bin/switch-opencode-config
RUN chmod +x /usr/local/bin/switch-opencode-config

# ── Everything else as user ──────────────────────────────────────────────────
USER ${USERNAME}
ENV HOME=/home/${USERNAME}
ENV PATH="/home/${USERNAME}/.local/bin:/home/${USERNAME}/.bun/bin:${PATH}"
ENV PATH="/home/${USERNAME}/.opencode/bin:/home/${USERNAME}/.local/bin:/home/${USERNAME}/.bun/bin:${PATH}"

WORKDIR /workspace
# Bun
RUN curl -fsSL https://bun.sh/install | bash

# OpenCode
RUN curl -fsSL https://opencode.ai/install | bash

# oh-my-openagent
RUN bunx oh-my-openagent install --no-tui --claude=no --openai=no --gemini=no --copilot=no --opencode-zen=yes && \
cp ~/.config/opencode/oh-my-openagent.json ~/.config/opencode/oh-my-openagent-default.json

# ── Entrypoint ────────────────────────────────────────────────────────────────
COPY --chown=${USERNAME}:${MYGID} entrypoint.sh /entrypoint.sh
COPY --chown=${USERNAME}:${MYGID} configs/ /opt/project-configs/
RUN chmod +x /entrypoint.sh && \
chmod +x /opt/project-configs/templates/switch-opencode-config.sh && \
cp /opt/project-configs/templates/switch-opencode-config.sh /usr/local/bin/switch-opencode-config
RUN chmod +x /entrypoint.sh

# Copy project configs into the safe config dir
RUN cp /opt/project-configs/opencode/oh-my-opencode-free.json /opt/opencode-config/ 2>/dev/null || true && \
cp /opt/project-configs/opencode/oh-my-opencode-paid.json /opt/opencode-config/ 2>/dev/null || true && \
cp /opt/project-configs/templates/AGENTS.md-global /opt/opencode-config/AGENTS.md 2>/dev/null || true
ENV TERM=xterm-256color
ENV SHELL=/bin/bash

USER ${USERNAME}
WORKDIR /workspace

ENTRYPOINT ["/entrypoint.sh"]
CMD ["bash"]
1 change: 1 addition & 0 deletions configs/templates/AGENTS.md-global
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Global rules for all AI agents in this environment.
- Fail fast, fail loud: never silently swallow errors or hide failures behind fallbacks.
- Minimal changes: touch only what is necessary.
- Read before writing: understand existing patterns before modifying.
- **No hardcoded values**: all configurable values must be defined as constants, env vars, or in config files. Never inline literals for paths, ports, credentials, model names, or feature flags.

---

Expand Down
19 changes: 9 additions & 10 deletions configs/templates/switch-opencode-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@ CONFIG_DIR="$HOME/.config/opencode"

case "$1" in
free)
cp "$CONFIG_DIR/oh-my-opencode-free.json" "$CONFIG_DIR/oh-my-apenagent.json"
echo "FREE activated (OpenCode Zen free models)"
cp "$CONFIG_DIR/oh-my-openagent-free.json" "$CONFIG_DIR/oh-my-openagent.json"
echo "Free config activated"
;;
paid)
cp "$CONFIG_DIR/oh-my-opencode-paid.json" "$CONFIG_DIR/oh-my-openagent.json"
echo "PAID activated (GitHub Copilot models)"
cp "$CONFIG_DIR/oh-my-openagent-paid.json" "$CONFIG_DIR/oh-my-openagent.json"
echo "Paid config activated"
;;
default)
cp "$CONFIG_DIR/oh-my-openagent.json.bak" "$CONFIG_DIR/oh-my-openagent.json"
echo "Default config restored (from installer backup)"
cp "$CONFIG_DIR/oh-my-openagent-default.json" "$CONFIG_DIR/oh-my-openagent.json"
echo "Default config restored"
;;
*)
echo "Usage: $0 {free|paid|default}"
echo " free - OpenCode Zen free models only"
echo " paid - GitHub Copilot models"
echo " default - Restore installer-generated config"
echo "Usage: $0 {free|paid}"
echo " free - Free models only"
echo " paid - Paid models"
;;
esac
38 changes: 30 additions & 8 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ services:

stdin_open: true
tty: true
user: "1000:1000"

volumes:
- ${PROJECT_PATH:-.}:/home/hannya/workspace:rw
- ${HOME}/.mujoco:/home/hannya/.mujoco:ro
- /tmp/.X11-unix:/tmp/.X11-unix:rw
- /dev/dri:/dev/dri

Expand All @@ -38,11 +38,13 @@ services:

environment:
- HOME=/home/hannya
- MYUID=${MYUID:-1000}
- MYGID=${MYGID:-1000}
- TERM=xterm-256color
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
- GOOGLE_API_KEY=${GOOGLE_API_KEY:-}
- OPENCODE_CONFIG=${OPENCODE_CONFIG:-default}
- OPENCODE_CONFIG=free
- XLA_PYTHON_CLIENT_MEM_FRACTION=${XLA_PYTHON_CLIENT_MEM_FRACTION:-0.7}
- XLA_PYTHON_CLIENT_PREALLOCATE=${XLA_PYTHON_CLIENT_PREALLOCATE:-false}
- UV_PROJECT_ENVIRONMENT=$HOME/workspace/.venv
Expand All @@ -58,14 +60,23 @@ services:
capabilities: [ gpu ]

security_opt:
- no-new-privileges:true
- no-new-privileges:false
cap_drop:
- ALL
- SYS_ADMIN
- NET_RAW
- MKNOD
- AUDIT_WRITE
- SETFCAP
cap_add:
- CHOWN
- SETUID
- SETGID
- SYS_PTRACE
- DAC_OVERRIDE
- FOWNER
- KILL
- NET_BIND_SERVICE
- NET_ADMIN

restart: "no"

Expand All @@ -82,10 +93,10 @@ services:

stdin_open: true
tty: true
user: "1000:1000"

volumes:
- ${PROJECT_PATH:-.}:/home/hannya/workspace:rw
- ${HOME}/.mujoco:/home/hannya/.mujoco:ro
- /tmp/.X11-unix:/tmp/.X11-unix:rw
- /dev/dri:/dev/dri

Expand All @@ -96,24 +107,35 @@ services:

environment:
- HOME=/home/hannya
- MYUID=${MYUID:-1000}
- MYGID=${MYGID:-1000}
- TERM=xterm-256color
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
- GOOGLE_API_KEY=${GOOGLE_API_KEY:-}
- OPENCODE_CONFIG=${OPENCODE_CONFIG:-default}
- OPENCODE_CONFIG=free
- JAX_PLATFORMS=cpu
- UV_PROJECT_ENVIRONMENT=$HOME/workspace/.venv
- DISPLAY=${DISPLAY:-}
- QT_X11_NO_MITSHM=1

security_opt:
- no-new-privileges:true
- no-new-privileges:false
cap_drop:
- ALL
- SYS_ADMIN
- NET_RAW
- MKNOD
- AUDIT_WRITE
- SETFCAP
cap_add:
- CHOWN
- SETUID
- SETGID
- SYS_PTRACE
- DAC_OVERRIDE
- FOWNER
- KILL
- NET_BIND_SERVICE
- NET_ADMIN

restart: "no"
Loading
Loading