Docker Development Environment

This document describes how to use the Docker-based development environment for monkeypuzzle. This is the preferred way to create reproducible issues when contributing to the project.

Overview

The Docker development environment provides:

Prerequisites

Quick Start

1. Build the Docker Image

From the repository root:

docker build -t monkeypuzzle-dev .

This will:

Build time: ~2-5 minutes (depending on network speed)

2. Run the Container

Basic Usage (Read-Only Source)

If you just want to test the pre-built mp command:

docker run -it --rm monkeypuzzle-dev

This starts an interactive bash shell with mp available.

Development Mode (Live Code Changes)

For active development where you want to edit source code and see changes:

# Mount current directory as workspace
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev

Important: When mounting the source code, the pre-built mp binary in the container may be from an older version. To use your local changes, rebuild mp inside the container:

# Inside the container
cd /workspace
go build -o /usr/local/bin/mp .

Or use a local binary:

# Inside the container
cd /workspace
go build -o ./mp .
./mp --help

3. Verify Installation

Once inside the container, verify everything works:

# Check mp is available
mp --help

# Check git
git --version

# Check tmux
tmux -V

# Check gh CLI
gh --version

# Check Go version
go version

Common Workflows

Testing mp Commands

# Start container with workspace mounted
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev

# Inside container: test mp init
mp init --schema

# Test with JSON input
echo '{"name":"test","pr_provider":"github"}' | mp init

Developing with Live Reload

  1. Terminal 1: Start container with mounted source

    docker run -it --rm \
      -v "$(pwd):/workspace" \
      -w /workspace \
      monkeypuzzle-dev
  2. Terminal 2: Edit source code on your host machine

  3. Inside container: Rebuild and test

    go build -o ./mp .
    ./mp --help

Using mp Command

The piece commands (mp create, mp switch, …) need git, which the container has (tmux is there too if you want sessions):

# Start container
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev

# Initialize a project
mp init --name myproject --pr-provider github

# Create a new piece
mp create --name my-feature

# This creates a branch and git worktree and prints its path

Running Tests

docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev \
  bash -c "go test ./..."

Running Linters

docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev \
  bash -c "go vet ./... && go fmt ./..."

Creating Reproducible Issues

This Docker environment is the preferred way to create reproducible bug reports and test cases.

Step 1: Reproduce the Issue

# Build the image
docker build -t monkeypuzzle-dev .

# Run with your test case
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev \
  bash -c "mp <your-command-here>"

Step 2: Document the Environment

Include in your issue:

## Environment

- Docker version: `docker --version`
- Image: `monkeypuzzle-dev` (built from Dockerfile)
- OS: Ubuntu 24.04
- Go: 1.24.11
- mp version: commit hash (`git rev-parse HEAD`)

Step 3: Provide Reproduction Steps

## Steps to Reproduce

1. Build image: `docker build -t monkeypuzzle-dev .`
2. Run: `docker run -it --rm -v "$(pwd):/workspace" -w /workspace monkeypuzzle-dev`
3. Execute: `mp <command>`
4. Observe: [describe the issue]

Step 4: Include Minimal Test Case

If possible, create a minimal test case that reproduces the issue:

# Create a test script
cat > test-reproduce.sh << 'EOF'
#!/bin/bash
set -e
mp init --name test --pr-provider github
# ... more commands that reproduce the issue
EOF

# Run in container
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev \
  bash test-reproduce.sh

Advanced Usage

Custom User ID

If you need to match your host user ID (to avoid permission issues):

docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  -u $(id -u):$(id -g) \
  monkeypuzzle-dev

Note: The default user in the container is developer (UID 1000). If your host user has a different UID, files created in mounted volumes may have different ownership.

Persistent Go Module Cache

To speed up builds, you can mount the Go module cache:

docker run -it --rm \
  -v "$(pwd):/workspace" \
  -v go-mod-cache:/go/pkg/mod \
  -w /workspace \
  monkeypuzzle-dev

Running Specific Commands

You can run commands directly without entering the container:

# Run mp init
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev \
  mp init --schema

# Run tests
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  monkeypuzzle-dev \
  go test ./internal/core/init/... -v

Using Docker Compose (Optional)

Create a docker-compose.yml for convenience:

version: "3.8"

services:
  dev:
    build: .
    image: monkeypuzzle-dev
    volumes:
      - .:/workspace
    working_dir: /workspace
    stdin_open: true
    tty: true

Then use:

docker-compose run --rm dev bash

Troubleshooting

Permission Issues

If you encounter permission errors when mounting volumes:

# Option 1: Use your host user ID
docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  -u $(id -u):$(id -g) \
  monkeypuzzle-dev

# Option 2: Fix permissions on host
sudo chown -R $USER:$USER .

mp Command Not Found

If mp is not available:

# Rebuild inside container
cd /workspace
go build -o /usr/local/bin/mp .

Or use the local binary:

cd /workspace
go build -o ./mp .
./mp --help

Git Configuration

The container sets safe defaults, but you may want to configure git:

git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

GitHub CLI Authentication

If you need to use gh CLI (for PR operations):

# Authenticate (interactive)
gh auth login

# Or use a token
export GH_TOKEN=your_token_here

Network Issues

If you’re behind a proxy:

docker run -it --rm \
  -v "$(pwd):/workspace" \
  -w /workspace \
  -e HTTP_PROXY=http://proxy:port \
  -e HTTPS_PROXY=http://proxy:port \
  monkeypuzzle-dev

Building for Different Architectures

The Dockerfile is configured for amd64 by default. For other architectures:

# Build for ARM64 (Apple Silicon, etc.)
docker build --platform linux/arm64 -t monkeypuzzle-dev .

Note: You may need to adjust the GO_ARCH variable in the Dockerfile for non-amd64 architectures.

Best Practices

  1. Always use the Docker environment when reporting bugs to ensure reproducibility
  2. Mount source code as a volume for active development
  3. Rebuild mp inside container when source code changes
  4. Include Docker commands in bug reports for easy reproduction
  5. Use specific commit hashes when reporting issues tied to specific code versions

Integration with CI/CD

The Dockerfile can be used in CI/CD pipelines:

# Example GitHub Actions
- name: Test in Docker
  run: |
    docker build -t monkeypuzzle-dev .
    docker run --rm monkeypuzzle-dev go test ./...

See Also