mirror of
https://github.com/aminnairi/dotfiles.git
synced 2026-09-14 11:02:13 +02:00
configuration for the docker skill for opencode
This commit is contained in:
@@ -0,0 +1,560 @@
|
|||||||
|
---
|
||||||
|
name: docker
|
||||||
|
description: Docker containerization - images, containers, volumes, networking, docker-compose, best practices
|
||||||
|
metadata:
|
||||||
|
language: bash
|
||||||
|
audience: developers
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Docker is a platform for developing, shipping, and running applications in containers. Use this skill when working with Docker or Docker Compose.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Docker Engine
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install docker.io
|
||||||
|
sudo systemctl start docker
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
# Add user to docker group
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Standalone (recommended)
|
||||||
|
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify installation:
|
||||||
|
```bash
|
||||||
|
docker --version
|
||||||
|
docker-compose --version
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic Concepts
|
||||||
|
|
||||||
|
### Images
|
||||||
|
|
||||||
|
- **Image**: A read-only template for creating containers
|
||||||
|
- **Container**: A runnable instance of an image
|
||||||
|
- **Tag**: Version identifier for images (e.g., `nginx:latest`)
|
||||||
|
- **Registry**: Storage for images (Docker Hub, GHCR, ECR, etc.)
|
||||||
|
|
||||||
|
### Common Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List images
|
||||||
|
docker images
|
||||||
|
docker image ls
|
||||||
|
|
||||||
|
# Pull an image
|
||||||
|
docker pull nginx:latest
|
||||||
|
|
||||||
|
# Remove an image
|
||||||
|
docker rmi nginx:latest
|
||||||
|
|
||||||
|
# Build an image from Dockerfile
|
||||||
|
docker build -t myapp:latest .
|
||||||
|
|
||||||
|
# Tag an image
|
||||||
|
docker tag myapp:latest registry.io/myapp:latest
|
||||||
|
|
||||||
|
# Push to registry
|
||||||
|
docker push registry.io/myapp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Contexts
|
||||||
|
|
||||||
|
Docker contexts allow you to manage connections to multiple Docker hosts from a single Docker CLI. Useful for switching between local Docker, remote servers, or Kubernetes clusters.
|
||||||
|
|
||||||
|
### Basic Context Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all contexts
|
||||||
|
docker context ls
|
||||||
|
|
||||||
|
# Show current context
|
||||||
|
docker context show
|
||||||
|
|
||||||
|
# Use a specific context
|
||||||
|
docker context use my-remote-host
|
||||||
|
|
||||||
|
# Create a new context
|
||||||
|
docker context create my-remote-host \
|
||||||
|
--docker "host=ssh://user@remote-server:22"
|
||||||
|
|
||||||
|
# Create context from existing Docker configuration
|
||||||
|
docker context create my-context --docker "host=tcp://localhost:2375"
|
||||||
|
|
||||||
|
# Inspect a context
|
||||||
|
docker context inspect my-remote-host
|
||||||
|
|
||||||
|
# Remove a context
|
||||||
|
docker context rm my-remote-host
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSH Context
|
||||||
|
|
||||||
|
Connect to a remote Docker host via SSH:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create SSH context
|
||||||
|
docker context create production \
|
||||||
|
--docker "host=ssh://user@production-server"
|
||||||
|
|
||||||
|
# Use the context
|
||||||
|
docker context use production
|
||||||
|
docker ps
|
||||||
|
docker run -d nginx:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kubernetes Context
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List Kubernetes contexts (requires kubectl)
|
||||||
|
kubectl config get-contexts
|
||||||
|
|
||||||
|
# Create Docker context from Kubernetes context
|
||||||
|
docker context create k8s-prod \
|
||||||
|
--kubernetes "context-name=production"
|
||||||
|
|
||||||
|
# Switch to Kubernetes context
|
||||||
|
docker context use k8s-prod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use with Docker Compose
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Use a specific context with compose
|
||||||
|
docker --context my-remote-host compose up -d
|
||||||
|
|
||||||
|
# Or set context in compose file (Docker Compose v2)
|
||||||
|
COMPOSE_DOCKER_CLI_HOST=1 docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Name meaningfully** - Use prefixes like `local-`, `prod-`, `dev-`
|
||||||
|
2. **Test before switching** - Use `docker context inspect` to verify
|
||||||
|
3. **Keep local default** - Keep `default` or `local` for local development
|
||||||
|
4. **Document remote connections** - Note SSH keys and endpoints
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Example context setup
|
||||||
|
docker context create local # Local Docker (default)
|
||||||
|
docker context create dev-server --docker "host=ssh://dev@dev-server"
|
||||||
|
docker context create prod-server --docker "host=ssh://prod@prod-server"
|
||||||
|
|
||||||
|
# Quick switch
|
||||||
|
docker context use dev-server
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dockerfile
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Use multi-stage builds** - Reduce final image size
|
||||||
|
2. **Order commands by change frequency** - Cache unchanged layers
|
||||||
|
3. **Use specific tags** - Avoid `latest` in production
|
||||||
|
4. **Use .dockerignore** - Exclude unnecessary files
|
||||||
|
5. **Run as non-root** - Security best practice
|
||||||
|
6. **Use official base images** - Better security and maintenance
|
||||||
|
|
||||||
|
### Node.js Example
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# Build stage
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM node:20-alpine AS production
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
|
USER node
|
||||||
|
EXPOSE 3000
|
||||||
|
CMD ["node", "dist/index.js"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python Example
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
FROM python:3.11-slim AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --user -r requirements.txt
|
||||||
|
|
||||||
|
FROM python:3.11-slim
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /root/.local /root/.local
|
||||||
|
COPY . .
|
||||||
|
ENV PATH=/root/.local/bin:$PATH
|
||||||
|
EXPOSE 8000
|
||||||
|
CMD ["python", "main.py"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### .dockerignore
|
||||||
|
|
||||||
|
```
|
||||||
|
node_modules
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
README.md
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
```
|
||||||
|
|
||||||
|
## Containers
|
||||||
|
|
||||||
|
### Run a Container
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run in background (detached)
|
||||||
|
docker run -d myapp:latest
|
||||||
|
|
||||||
|
# Run with port mapping
|
||||||
|
docker run -d -p 8080:3000 myapp:latest
|
||||||
|
|
||||||
|
# Run with volume mount
|
||||||
|
docker run -d -v /host/path:/container/path myapp:latest
|
||||||
|
|
||||||
|
# Run with environment variables
|
||||||
|
docker run -d -e NODE_ENV=production -e API_KEY=xxx myapp:latest
|
||||||
|
|
||||||
|
# Run with name
|
||||||
|
docker run -d --name my-container myapp:latest
|
||||||
|
|
||||||
|
# Interactive mode
|
||||||
|
docker run -it ubuntu:latest /bin/bash
|
||||||
|
|
||||||
|
# Remove container after exit
|
||||||
|
docker run --rm myapp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List running containers
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# List all containers
|
||||||
|
docker ps -a
|
||||||
|
|
||||||
|
# Stop a container
|
||||||
|
docker stop my-container
|
||||||
|
|
||||||
|
# Start a stopped container
|
||||||
|
docker start my-container
|
||||||
|
|
||||||
|
# Restart a container
|
||||||
|
docker restart my-container
|
||||||
|
|
||||||
|
# Remove a container
|
||||||
|
docker rm my-container
|
||||||
|
|
||||||
|
# Remove all stopped containers
|
||||||
|
docker container prune
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker logs -f my-container
|
||||||
|
|
||||||
|
# Execute command in running container
|
||||||
|
docker exec -it my-container sh
|
||||||
|
|
||||||
|
# Inspect container details
|
||||||
|
docker inspect my-container
|
||||||
|
|
||||||
|
# View resource usage
|
||||||
|
docker stats my-container
|
||||||
|
```
|
||||||
|
|
||||||
|
## Volumes
|
||||||
|
|
||||||
|
### Named Volumes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a volume
|
||||||
|
docker volume create my-data
|
||||||
|
|
||||||
|
# List volumes
|
||||||
|
docker volume ls
|
||||||
|
|
||||||
|
# Inspect volume
|
||||||
|
docker volume inspect my-data
|
||||||
|
|
||||||
|
# Remove volume
|
||||||
|
docker volume rm my-data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bind Mounts
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Mount host directory
|
||||||
|
docker run -v /host/path:/container/path myapp:latest
|
||||||
|
|
||||||
|
# Mount read-only
|
||||||
|
docker run -v /host/path:/container/path:ro myapp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use in Dockerfile
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
VOLUME /app/data
|
||||||
|
```
|
||||||
|
|
||||||
|
## Networking
|
||||||
|
|
||||||
|
### Networks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a network
|
||||||
|
docker network create my-network
|
||||||
|
|
||||||
|
# List networks
|
||||||
|
docker network ls
|
||||||
|
|
||||||
|
# Connect container to network
|
||||||
|
docker network connect my-network my-container
|
||||||
|
|
||||||
|
# Disconnect container from network
|
||||||
|
docker network disconnect my-network my-container
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port Exposure
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
EXPOSE 3000 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Compose
|
||||||
|
|
||||||
|
### Basic Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
volumes:
|
||||||
|
- ./data:/app/data
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: myapp
|
||||||
|
POSTGRES_USER: user
|
||||||
|
POSTGRES_PASSWORD: password
|
||||||
|
volumes:
|
||||||
|
- db-data:/var/lib/postgresql/data
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db-data:
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start services
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Start with build
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# Stop services
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Stop and remove volumes
|
||||||
|
docker-compose down -v
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# List services
|
||||||
|
docker-compose ps
|
||||||
|
|
||||||
|
# Execute command in service
|
||||||
|
docker-compose exec app sh
|
||||||
|
|
||||||
|
# Scale a service
|
||||||
|
docker-compose up -d --scale app=3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Healthchecks
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: .
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Profiles
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: .
|
||||||
|
|
||||||
|
debug:
|
||||||
|
build: .
|
||||||
|
profiles:
|
||||||
|
- debug
|
||||||
|
command: ["sleep", "infinity"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Run with profile: `docker-compose --profile debug up`
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Development with Volumes
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
target: development
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
- /app/node_modules
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
command: npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hot Reload
|
||||||
|
|
||||||
|
For Node.js with nodemon:
|
||||||
|
```dockerfile
|
||||||
|
FROM node:20-alpine
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
COPY . .
|
||||||
|
CMD ["npm", "run", "dev"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
1. **Don't run as root** - Use `USER` directive
|
||||||
|
2. **Scan for vulnerabilities** - Use `docker scout` or `trivy`
|
||||||
|
3. **Use specific tags** - Not `latest`
|
||||||
|
4. **Read-only containers** - Use `--read-only` flag
|
||||||
|
5. **Limit capabilities** - Use `--cap-drop` and `--cap-add`
|
||||||
|
6. **Secrets management** - Use Docker secrets or environment variables
|
||||||
|
7. **Multi-stage builds** - Minimize attack surface
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Security scanning
|
||||||
|
docker scout cves myapp:latest
|
||||||
|
|
||||||
|
# Run securely
|
||||||
|
docker run \
|
||||||
|
--read-only \
|
||||||
|
--cap-drop ALL \
|
||||||
|
--user 1000:1000 \
|
||||||
|
myapp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Interactive shell
|
||||||
|
docker run -it --rm myapp:latest sh
|
||||||
|
|
||||||
|
# Inspect with dive (if installed)
|
||||||
|
dive myapp:latest
|
||||||
|
|
||||||
|
# Check layers
|
||||||
|
docker history myapp:latest
|
||||||
|
|
||||||
|
# Debug running container
|
||||||
|
docker exec sh
|
||||||
|
|
||||||
|
# Copy files from -it my-container container
|
||||||
|
docker cp my-container:/app/logs ./logs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Node.js + Nginx
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: ./app
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
volumes:
|
||||||
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database + Backup
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
volumes:
|
||||||
|
- db-data:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
backup:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
volumes:
|
||||||
|
- ./backups:/backups
|
||||||
|
command: >
|
||||||
|
sh -c "while true; do
|
||||||
|
pg_dump -h db -U postgres mydb > /backups/backup-$$(date +%Y%m%d-%H%M%S).sql;
|
||||||
|
sleep 86400;
|
||||||
|
done"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- Use `docker system prune -a` to clean up unused resources
|
||||||
|
- Use `--force-rm` when building to remove intermediate containers
|
||||||
|
- Use `-f` flag to force operations
|
||||||
|
- Use `--no-cache` for clean builds
|
||||||
|
- Tag images before pushing to registries
|
||||||
|
- Use `docker-compose config` to validate compose files
|
||||||
Reference in New Issue
Block a user