Claude-skill-registry docker-development
Local Docker development workflow for the Orient. Use when asked to build Docker images, run containers locally, debug container issues, optimize builds, use docker-compose, or troubleshoot containerization problems. Covers per-package Dockerfiles, compose layering, build optimization, and local debugging.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/docker-development" ~/.claude/skills/majiayu000-claude-skill-registry-docker-development && rm -rf "$T"
skills/data/docker-development/SKILL.mdDocker Development
Quick Reference
# Development mode (hot-reload, uses local code) ./run.sh dev # Start dev environment ./run.sh dev stop # Stop services ./run.sh dev logs # View logs ./run.sh dev status # Show service status # Testing mode (full Docker stack) ./run.sh test # Build and start containers ./run.sh test pull # Use pre-built images ./run.sh test status # Check health ./run.sh test stop # Stop containers ./run.sh test clean # Remove volumes (fresh start)
Instance Naming Conventions
| Mode | Container Names | Ports |
|---|---|---|
| Dev (instance 0) | | 80, 9000, 9001 |
| Test | | 80, 9000, 9001 |
| Instance N | | 80+N*1000, etc. |
Compose File Layering
# Base configuration docker-compose.v2.yml # Service definitions # Environment overlays docker-compose.local.yml # Local builds docker-compose.prod.yml # Production images docker-compose.staging.yml # Staging config # Usage docker compose -f docker-compose.v2.yml -f docker-compose.local.yml up
Database: SQLite (File-Based)
The Orient uses SQLite for all database operations. No separate database container is needed.
Database location:
- Dev mode:
.dev-data/instance-N/orient.db - Docker:
(volume-mounted)/app/data/orient.db
Environment variables:
DATABASE_TYPE=sqlite SQLITE_DATABASE=/app/data/orient.db
Container Lifecycle
Starting Containers
# With build (slow, may hang on metadata) docker compose --env-file ../.env -f docker-compose.v2.yml -f docker-compose.local.yml --profile slack up -d # Without build (use existing images) docker compose --env-file ../.env -f docker-compose.v2.yml -f docker-compose.local.yml --profile slack up -d --no-build
Stopping Containers
# Stop test stack ./run.sh test stop # Stop specific containers (dev instance 0) docker stop orienter-nginx-0 orienter-minio-0 docker rm orienter-nginx-0 orienter-minio-0
Viewing Logs
docker logs orienter-opencode --tail 100 -f # Follow logs docker logs orienter-bot-slack 2>&1 | tail -50 # Last 50 lines
Health Checks
./run.sh test status # Quick health overview docker ps # Container status docker inspect --format='{{.State.Health.Status}}' orienter-opencode
Common Issues
1. Port Conflicts
Symptom:
Bind for 0.0.0.0:9000 failed: port is already allocated
Fix: Stop conflicting containers:
# Find what's using the port lsof -i :9000 # Stop dev containers before starting test docker stop orienter-nginx-0 orienter-minio-0 docker rm orienter-nginx-0 orienter-minio-0
2. Build Hangs on Metadata Loading (macOS)
Symptom:
./run.sh test hangs at "load metadata for docker.io/library/node:20-alpine"
Cause: Docker buildx slow to fetch from Docker Hub.
Workarounds:
# Option 1: Pre-pull images docker pull node:20-alpine docker pull node:20-slim # Option 2: Use existing local images docker compose ... up -d --no-build # Option 3: Use ghcr.io images (requires auth) ./run.sh test pull
3. ECONNRESET During Tests
Symptom: E2E tests fail with
fetch failed / ECONNRESET
Cause: Container crashed or restarted during test run.
Debug:
# Check container status docker ps -a | grep opencode # Check if recently restarted # Look for "Up X seconds" when tests ran for minutes # View crash logs docker logs orienter-opencode 2>&1 | tail -100
4. Container Won't Start
Debug steps:
# Check exit code docker ps -a --filter "name=orienter-opencode" # Check logs for errors docker logs orienter-opencode 2>&1 # Check if image exists docker images | grep docker-opencode # Rebuild single service docker compose ... build opencode
5. ghcr.io Authentication
Symptom:
./run.sh test pull fails with 401 Unauthorized
Fix:
# Authenticate to GitHub Container Registry echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
6. SQLite Database Issues
Symptom: Database not persisting or permission errors
Fix:
# Check volume mount docker inspect orienter-dashboard | grep -A 5 Mounts # Ensure data directory exists with correct permissions mkdir -p .dev-data/instance-0 chmod 755 .dev-data/instance-0 # Verify database schema sqlite3 .dev-data/instance-0/orient.db ".tables"
Switching Between Stacks
Always stop one stack before starting another:
# From dev to test ./run.sh dev stop ./run.sh test # From test to dev ./run.sh test stop ./run.sh dev
Building Images
# Build all services docker compose -f docker-compose.v2.yml -f docker-compose.local.yml build # Build single service docker compose -f docker-compose.v2.yml -f docker-compose.local.yml build dashboard # Build with no cache docker compose ... build --no-cache opencode # Build with progress output docker compose ... build dashboard --progress=plain
Environment Variables
Compose files use
--env-file ../.env to load environment. Required vars:
,MINIO_ROOT_USERMINIO_ROOT_PASSWORDANTHROPIC_API_KEYDASHBOARD_JWT_SECRETORIENT_MASTER_KEY
,SLACK_BOT_TOKEN
(for Slack profile)SLACK_SIGNING_SECRET
Services Architecture
The Docker stack includes:
| Service | Purpose | Port(s) |
|---|---|---|
| dashboard | Dashboard API + WhatsApp routes | 4098 |
| opencode | OpenCode API | 4099 |
| bot-slack | Slack bot (profile-activated) | - |
| minio | Object storage | 9000, 9001 |
| nginx | Reverse proxy | 80 |
Note: WhatsApp functionality is integrated into the Dashboard service (single port 4098).