595 lines
14 KiB
Markdown
595 lines
14 KiB
Markdown
# Development Containers
|
|
|
|
## What is a Development Container?
|
|
|
|
A **Development Container** (devcontainer) is a containerized development environment that provides:
|
|
|
|
- ✅ **Consistent development environment** across all team members
|
|
- ✅ **Pre-configured tools and dependencies** ready to use
|
|
- ✅ **Instant setup** - no manual installation of dependencies
|
|
- ✅ **Isolated environment** that won't conflict with your host system
|
|
- ✅ **Version-controlled configuration** shared with the team
|
|
|
|
The devcontainer includes Python 3.13, all project dependencies, development tools, and shell customizations pre-installed and configured.
|
|
|
|
## Prerequisites
|
|
|
|
You need Docker installed on your system:
|
|
|
|
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) (macOS/Windows)
|
|
- [Docker Engine](https://docs.docker.com/engine/install/) (Linux)
|
|
|
|
Check Docker is working:
|
|
```bash
|
|
docker --version
|
|
docker ps
|
|
```
|
|
|
|
## Quick Start (Terminal-First Approach)
|
|
|
|
### 1. Clone and Build Container
|
|
|
|
```bash
|
|
# Clone the repository
|
|
git clone https://git.cleverthis.com/cleverthis/base/base-python
|
|
cd base-python
|
|
|
|
# Build the development container
|
|
docker build -f .devcontainer/Dockerfile -t boilerplate-dev .
|
|
|
|
# Run the development container
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
--name boilerplate-dev \
|
|
boilerplate-dev bash
|
|
```
|
|
|
|
### 2. Inside the Container
|
|
|
|
Once inside the container, everything is pre-configured:
|
|
|
|
```bash
|
|
# Check Python environment
|
|
python --version # Python 3.13.x
|
|
which python # /usr/local/bin/python
|
|
|
|
# Virtual environment is auto-activated
|
|
echo $VIRTUAL_ENV # /workspaces/boilerplate/.venv
|
|
|
|
# Check tools are installed
|
|
ruff --version # Linting and formatting
|
|
pyright --version # Type checking
|
|
behave --version # BDD testing
|
|
nox --version # Test automation
|
|
|
|
# Run development commands
|
|
nox -s behave # Run BDD tests
|
|
nox -s lint # Run linting
|
|
nox -s format # Format code
|
|
nox -s typecheck # Type checking
|
|
|
|
# Test the CLI
|
|
python -m boilerplate --name "DevContainer" --count 2
|
|
```
|
|
|
|
### 3. Available Shell Aliases
|
|
|
|
The container includes pre-configured aliases for faster development:
|
|
|
|
```bash
|
|
# Development shortcuts
|
|
dev-test # nox -s behave
|
|
dev-lint # nox -s lint
|
|
dev-format # nox -s format
|
|
dev-type # nox -s typecheck
|
|
dev-docs # nox -s serve_docs
|
|
dev-all # nox (run all checks)
|
|
|
|
# Docker shortcuts
|
|
d # docker
|
|
build-docker # docker build -t boilerplate:dev .
|
|
|
|
# Git shortcuts
|
|
gs # git status
|
|
ga # git add
|
|
gc # git commit
|
|
gp # git push
|
|
gl # git pull
|
|
|
|
# Python shortcuts
|
|
py # python
|
|
pip # uv pip (faster package manager)
|
|
venv # uv venv
|
|
```
|
|
|
|
### 4. Persistent Development
|
|
|
|
For ongoing development with persistent changes:
|
|
|
|
```bash
|
|
# Create a named container for persistence
|
|
docker run -it \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-v boilerplate-venv:/workspaces/boilerplate/.venv \
|
|
-v boilerplate-cache:/tmp/uv-cache \
|
|
-w /workspaces/boilerplate \
|
|
--name boilerplate-dev-persistent \
|
|
boilerplate-dev bash
|
|
|
|
# Later, restart the same container
|
|
docker start -ai boilerplate-dev-persistent
|
|
```
|
|
|
|
## IDE Integration
|
|
|
|
### Emacs with TRAMP
|
|
|
|
Connect to your running container from Emacs:
|
|
|
|
```bash
|
|
# 1. Start container with SSH (add to Dockerfile if needed)
|
|
docker run -it --name boilerplate-dev \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-p 2222:22 \
|
|
boilerplate-dev
|
|
|
|
# 2. In Emacs, connect via TRAMP
|
|
# M-x find-file
|
|
# /docker:boilerplate-dev:/workspaces/boilerplate/
|
|
```
|
|
|
|
**Emacs Configuration:**
|
|
```elisp
|
|
;; .emacs or init.el
|
|
(require 'tramp)
|
|
(setq tramp-default-method "docker")
|
|
|
|
;; Python development
|
|
(use-package python-mode)
|
|
(use-package lsp-mode
|
|
:hook ((python-mode . lsp)))
|
|
(use-package lsp-pyright
|
|
:after lsp-mode)
|
|
|
|
;; Connect to container Python
|
|
(setq python-interpreter "/usr/local/bin/python")
|
|
```
|
|
|
|
### Vim/Neovim
|
|
|
|
#### Option 1: Terminal Vim Inside Container
|
|
|
|
```bash
|
|
# Run container with vim pre-installed
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev vim
|
|
|
|
# Or use neovim if installed
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev nvim
|
|
```
|
|
|
|
#### Option 2: Host Vim with Container Tools
|
|
|
|
```bash
|
|
# 1. Start container as daemon
|
|
docker run -d --name boilerplate-tools \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev tail -f /dev/null
|
|
|
|
# 2. Create wrapper scripts
|
|
cat > vim-ruff << 'EOF'
|
|
#!/bin/bash
|
|
docker exec boilerplate-tools ruff "$@"
|
|
EOF
|
|
chmod +x vim-ruff
|
|
|
|
# 3. Configure Vim to use container tools
|
|
```
|
|
|
|
**Vim Configuration:**
|
|
```vim
|
|
" .vimrc or init.vim
|
|
" Python development setup
|
|
let g:python3_host_prog = 'docker exec boilerplate-tools python'
|
|
|
|
" Use container tools for linting
|
|
let g:ale_linters = {
|
|
\ 'python': ['ruff'],
|
|
\}
|
|
let g:ale_python_ruff_executable = './vim-ruff'
|
|
|
|
" Use container tools for formatting
|
|
let g:ale_fixers = {
|
|
\ 'python': ['ruff'],
|
|
\}
|
|
```
|
|
|
|
### VS Code
|
|
|
|
#### Option 1: Terminal-First with VS Code Terminal
|
|
|
|
```bash
|
|
# 1. Start container
|
|
docker run -it --name boilerplate-dev \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash
|
|
|
|
# 2. Open VS Code and connect to terminal
|
|
# Terminal → New Terminal
|
|
# Select "Docker" or connect to running container
|
|
```
|
|
|
|
#### Option 2: Dev Containers Extension
|
|
|
|
```bash
|
|
# 1. Install Dev Containers extension
|
|
# Extensions → Search "Dev Containers" → Install
|
|
|
|
# 2. Open project folder
|
|
code .
|
|
|
|
# 3. Reopen in container
|
|
# Ctrl+Shift+P → "Dev Containers: Reopen in Container"
|
|
```
|
|
|
|
**VS Code Configuration:**
|
|
The `.devcontainer/devcontainer.json` is pre-configured with:
|
|
- Python 3.13 environment
|
|
- 15+ relevant extensions
|
|
- Proper settings for ruff, pyright
|
|
- Integrated terminal with aliases
|
|
- Port forwarding for development servers
|
|
|
|
### PyCharm
|
|
|
|
#### Option 1: Remote Python Interpreter
|
|
|
|
```bash
|
|
# 1. Start container as daemon
|
|
docker run -d --name boilerplate-pycharm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-p 2222:22 \
|
|
boilerplate-dev
|
|
|
|
# 2. Configure PyCharm remote interpreter
|
|
# File → Settings → Project → Python Interpreter
|
|
# Add Interpreter → Docker → Existing container
|
|
# Container: boilerplate-pycharm
|
|
# Python path: /usr/local/bin/python
|
|
```
|
|
|
|
#### Option 2: Docker Compose Integration
|
|
|
|
Create `docker-compose.dev.yml`:
|
|
```yaml
|
|
version: '3.8'
|
|
services:
|
|
dev:
|
|
build:
|
|
context: .
|
|
dockerfile: .devcontainer/Dockerfile
|
|
volumes:
|
|
- .:/workspaces/boilerplate
|
|
- boilerplate-venv:/workspaces/boilerplate/.venv
|
|
working_dir: /workspaces/boilerplate
|
|
command: tail -f /dev/null
|
|
ports:
|
|
- "8000:8000"
|
|
- "3000:3000"
|
|
|
|
volumes:
|
|
boilerplate-venv:
|
|
```
|
|
|
|
```bash
|
|
# Start development environment
|
|
docker-compose -f docker-compose.dev.yml up -d
|
|
|
|
# PyCharm configuration
|
|
# File → Settings → Build, Execution, Deployment → Docker
|
|
# Add Docker server (usually auto-detected)
|
|
# Configure Python interpreter to use docker-compose service
|
|
```
|
|
|
|
**PyCharm Configuration Steps:**
|
|
1. **Settings** → **Project** → **Python Interpreter**
|
|
2. **Add Interpreter** → **Docker Compose**
|
|
3. **Configuration file**: `docker-compose.dev.yml`
|
|
4. **Service**: `dev`
|
|
5. **Python interpreter path**: `/usr/local/bin/python`
|
|
6. **Apply** and **OK**
|
|
|
|
## What's Included in the Container
|
|
|
|
### 🐍 **Python Environment**
|
|
```bash
|
|
python --version # Python 3.13.x
|
|
pip --version # uv-powered pip replacement
|
|
which python # /usr/local/bin/python
|
|
echo $PYTHONPATH # /workspaces/boilerplate/src
|
|
```
|
|
|
|
### 🛠️ **Development Tools**
|
|
```bash
|
|
ruff --version # Lightning-fast linting and formatting
|
|
pyright --version # Strict type checking
|
|
nox --version # Test automation across Python versions
|
|
behave --version # BDD testing framework
|
|
hypothesis --version # Property-based testing
|
|
pre-commit --version # Git hooks for code quality
|
|
```
|
|
|
|
### 🔧 **System Tools**
|
|
```bash
|
|
git --version # Git with helpful aliases
|
|
docker --version # Docker-in-Docker for building containers
|
|
kubectl version --client # Kubernetes CLI
|
|
helm version # Helm package manager
|
|
gh --version # GitHub CLI for repository management
|
|
```
|
|
|
|
### 📝 **Shell Environment**
|
|
```bash
|
|
echo $SHELL # /bin/zsh (Oh My Zsh configured)
|
|
alias # List all available aliases
|
|
env | grep PYTHON # Python-related environment variables
|
|
```
|
|
|
|
## Advanced Usage
|
|
|
|
### Port Forwarding
|
|
|
|
Forward ports from container to host:
|
|
|
|
```bash
|
|
# Forward development server ports
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
-p 8000:8000 \
|
|
-p 3000:3000 \
|
|
-p 8080:8080 \
|
|
boilerplate-dev bash
|
|
|
|
# Now you can access:
|
|
# http://localhost:8000 - Application server
|
|
# http://localhost:3000 - MkDocs development server
|
|
# http://localhost:8080 - Development server
|
|
```
|
|
|
|
### Volume Mounts for Performance
|
|
|
|
For better performance, especially on macOS/Windows:
|
|
|
|
```bash
|
|
# Use named volumes for dependencies
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-v boilerplate-venv:/workspaces/boilerplate/.venv \
|
|
-v boilerplate-cache:/tmp/uv-cache \
|
|
-v boilerplate-node-modules:/workspaces/boilerplate/node_modules \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash
|
|
```
|
|
|
|
### Custom Configuration
|
|
|
|
Mount custom configuration files:
|
|
|
|
```bash
|
|
# Mount custom git config
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-v ~/.gitconfig:/home/vscode/.gitconfig:ro \
|
|
-v ~/.ssh:/home/vscode/.ssh:ro \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash
|
|
|
|
# Mount custom shell config
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-v ~/.zshrc:/home/vscode/.zshrc.local:ro \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash
|
|
```
|
|
|
|
### Development Workflow
|
|
|
|
```bash
|
|
# 1. Start development container
|
|
docker run -it --name dev-session \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-v boilerplate-venv:/workspaces/boilerplate/.venv \
|
|
-p 3000:3000 \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash
|
|
|
|
# 2. Inside container - start documentation server
|
|
nox -s serve_docs & # Runs in background
|
|
|
|
# 3. Make changes to code
|
|
vim src/boilerplate/cli.py
|
|
|
|
# 4. Run tests
|
|
dev-test # Quick BDD tests
|
|
|
|
# 5. Check code quality
|
|
dev-lint # Linting
|
|
dev-format # Auto-format code
|
|
dev-type # Type checking
|
|
|
|
# 6. Run full test suite
|
|
dev-all # All checks
|
|
|
|
# 7. Exit container (preserves named volumes)
|
|
exit
|
|
|
|
# 8. Later, restart same session
|
|
docker start -ai dev-session
|
|
```
|
|
|
|
## GitHub Codespaces Alternative
|
|
|
|
For cloud-based development without local Docker:
|
|
|
|
```bash
|
|
# 1. Go to your GitHub repository
|
|
# 2. Click "Code" → "Codespaces" → "Create codespace on main"
|
|
# 3. Wait 2-3 minutes for automatic setup
|
|
# 4. Everything is pre-configured and ready!
|
|
|
|
# Inside Codespace, same commands work:
|
|
nox -s behave # Run tests
|
|
dev-all # Run all checks
|
|
python -m boilerplate --help
|
|
```
|
|
|
|
**Codespace Features:**
|
|
- 🌐 **Browser-based**: No local setup required
|
|
- ⚡ **Fast SSD storage**: 32GB workspace storage
|
|
- 🔄 **Persistent**: Your work is saved automatically
|
|
- 💰 **Free tier**: 60 hours/month for personal accounts
|
|
- 🔒 **Secure**: Runs in GitHub's infrastructure
|
|
|
|
## Troubleshooting
|
|
|
|
### Container Won't Start
|
|
|
|
```bash
|
|
# Check Docker is running
|
|
docker --version
|
|
docker ps
|
|
|
|
# Free up disk space
|
|
docker system prune -f
|
|
|
|
# Rebuild container
|
|
docker build -f .devcontainer/Dockerfile -t boilerplate-dev . --no-cache
|
|
```
|
|
|
|
### Permission Issues
|
|
|
|
```bash
|
|
# Run as your user ID
|
|
docker run -it --rm \
|
|
-u $(id -u):$(id -g) \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash
|
|
|
|
# Or fix permissions after
|
|
sudo chown -R $(id -u):$(id -g) .
|
|
```
|
|
|
|
### Tools Not Working
|
|
|
|
```bash
|
|
# Check if tools are installed
|
|
docker run --rm boilerplate-dev which ruff pyright behave nox
|
|
|
|
# Check PATH
|
|
docker run --rm boilerplate-dev echo $PATH
|
|
|
|
# Reinstall dependencies
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash -c "uv pip install -e .[dev]"
|
|
```
|
|
|
|
### Performance Issues
|
|
|
|
```bash
|
|
# Allocate more resources to Docker
|
|
# Docker Desktop → Settings → Resources
|
|
# Memory: 4GB+, CPU: 2+ cores
|
|
|
|
# Use volumes for better performance
|
|
docker run -it --rm \
|
|
-v $(pwd):/workspaces/boilerplate \
|
|
-v boilerplate-cache:/tmp/uv-cache \
|
|
-w /workspaces/boilerplate \
|
|
boilerplate-dev bash
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 🔄 **Container Lifecycle**
|
|
```bash
|
|
# For short tasks - use --rm
|
|
docker run --rm boilerplate-dev nox -s lint
|
|
|
|
# For development sessions - use named containers
|
|
docker run --name dev-session boilerplate-dev bash
|
|
docker start -ai dev-session # Resume later
|
|
```
|
|
|
|
### 📁 **Volume Management**
|
|
```bash
|
|
# List volumes
|
|
docker volume ls
|
|
|
|
# Clean up unused volumes
|
|
docker volume prune
|
|
|
|
# Backup important data
|
|
docker run --rm -v boilerplate-venv:/data -v $(pwd):/backup \
|
|
alpine tar czf /backup/venv-backup.tar.gz -C /data .
|
|
```
|
|
|
|
### 🔒 **Security**
|
|
```bash
|
|
# Don't store secrets in container images
|
|
# Use environment variables or mounted secrets
|
|
docker run -e SECRET_KEY="$SECRET_KEY" boilerplate-dev
|
|
|
|
# Use read-only mounts when possible
|
|
docker run -v $(pwd):/workspace:ro boilerplate-dev
|
|
```
|
|
|
|
### ⚡ **Performance**
|
|
```bash
|
|
# Use named volumes for dependencies
|
|
-v boilerplate-venv:/workspaces/boilerplate/.venv
|
|
|
|
# Enable BuildKit for faster builds
|
|
export DOCKER_BUILDKIT=1
|
|
docker build -f .devcontainer/Dockerfile -t boilerplate-dev .
|
|
|
|
# Use multi-stage builds for smaller images (already configured)
|
|
```
|
|
|
|
## Integration with CI/CD
|
|
|
|
The devcontainer environment matches your CI/CD pipeline exactly:
|
|
|
|
- ✅ **Same Python version** (3.13)
|
|
- ✅ **Same tools** (ruff, pyright, behave)
|
|
- ✅ **Same dependencies** (from pyproject.toml)
|
|
- ✅ **Same commands** (nox sessions)
|
|
|
|
This eliminates "works on my machine" problems completely!
|
|
|
|
```bash
|
|
# What works in container will work in CI
|
|
dev-all # Local testing
|
|
# Same as CI pipeline commands in .forgejo/workflows/ci.yml
|
|
```
|
|
|
|
## Further Reading
|
|
|
|
- [Development Containers Specification](https://containers.dev/)
|
|
- [Docker Best Practices](https://docs.docker.com/develop/dev-best-practices/)
|
|
- [Container Security Guide](https://docs.docker.com/engine/security/)
|
|
|
|
---
|
|
|
|
**Ready to develop?** Start with the terminal-first approach and choose your preferred editor integration! |