Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:47:38 +08:00
commit 18faa0569e
47 changed files with 7969 additions and 0 deletions

View File

@@ -0,0 +1,268 @@
# Docker Compose Reference
## File Structure
```yaml
name: project-name # Optional, defaults to directory name
services:
service-name:
# Image or build
image: image:tag
build:
context: ./path
dockerfile: Dockerfile
# Networking
ports:
- "host:container"
networks:
- network-name
# Storage
volumes:
- named-volume:/path
- ./host-path:/container-path
# Environment
environment:
KEY: value
env_file:
- .env
# Dependencies
depends_on:
- other-service
# Lifecycle
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
# Resources
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
memory: 256M
networks:
network-name:
driver: bridge
volumes:
named-volume:
```
## Service Options
### Image vs Build
```yaml
# Use existing image
image: nginx:1.25-alpine
# Build from Dockerfile
build:
context: .
dockerfile: Dockerfile
args:
BUILD_ARG: value
```
### Port Mapping
```yaml
ports:
- "80:80" # host:container
- "443:443"
- "127.0.0.1:8080:80" # localhost only
- "8080-8090:8080-8090" # range
```
### Environment Variables
```yaml
# Inline
environment:
DATABASE_URL: postgres://db:5432/app
DEBUG: "false"
# From file
env_file:
- .env
- .env.local
```
### Dependencies
```yaml
depends_on:
- db
- redis
# With conditions (compose v2.1+)
depends_on:
db:
condition: service_healthy
```
### Restart Policies
| Policy | Behavior |
|--------|----------|
| no | Never restart (default) |
| always | Always restart |
| unless-stopped | Restart unless manually stopped |
| on-failure | Restart only on error exit |
### Health Checks
```yaml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s # Time between checks
timeout: 10s # Check timeout
retries: 3 # Failures before unhealthy
start_period: 40s # Grace period on startup
```
### Resource Limits
```yaml
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
```
## Network Configuration
### Custom Network
```yaml
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # No external access
```
### External Network
```yaml
networks:
existing-network:
external: true
```
### Macvlan Network
```yaml
networks:
lan:
driver: macvlan
driver_opts:
parent: eth0
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
```
## Volume Configuration
### Named Volume
```yaml
volumes:
data:
driver: local
services:
db:
volumes:
- data:/var/lib/mysql
```
### Bind Mount
```yaml
services:
web:
volumes:
- ./config:/etc/app/config:ro
- ./data:/app/data
```
### tmpfs Mount
```yaml
services:
app:
tmpfs:
- /tmp
- /run
```
## Multi-Environment Setup
### Using .env Files
```bash
# .env
COMPOSE_PROJECT_NAME=myapp
IMAGE_TAG=latest
```
```yaml
# docker-compose.yaml
services:
app:
image: myapp:${IMAGE_TAG}
```
### Override Files
```bash
# Base config
docker-compose.yaml
# Development overrides
docker-compose.override.yaml # Auto-loaded
# Production
docker compose -f docker-compose.yaml -f docker-compose.prod.yaml up
```
## Useful Commands
```bash
# Start with rebuild
docker compose up -d --build
# Scale service
docker compose up -d --scale web=3
# View config after variable substitution
docker compose config
# Execute command in service
docker compose exec web sh
# View service logs
docker compose logs -f web
# Restart single service
docker compose restart web
```

View File

@@ -0,0 +1,243 @@
# Dockerfile Reference
## Basic Structure
```dockerfile
# Base image
FROM ubuntu:22.04
# Metadata
LABEL maintainer="team@example.com"
LABEL version="1.0"
# Environment
ENV APP_HOME=/app
WORKDIR $APP_HOME
# Install dependencies
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
# Copy files
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Non-root user
RUN useradd -r -s /bin/false appuser
USER appuser
# Expose port
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/health || exit 1
# Entry point
ENTRYPOINT ["python"]
CMD ["app.py"]
```
## Multi-Stage Builds
Reduce final image size by separating build and runtime:
```dockerfile
# Build stage
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# Runtime stage
FROM alpine:3.18
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["myapp"]
```
## Common Base Images
| Image | Size | Use Case |
|-------|------|----------|
| alpine | ~5MB | Minimal, production |
| debian:slim | ~80MB | Compatibility |
| ubuntu | ~75MB | Development |
| distroless | ~20MB | Security-focused |
| scratch | 0MB | Static binaries only |
## Instructions Reference
### FROM
```dockerfile
FROM image:tag
FROM image:tag AS builder
FROM --platform=linux/amd64 image:tag
```
### RUN
```dockerfile
# Shell form
RUN apt-get update && apt-get install -y package
# Exec form
RUN ["executable", "param1", "param2"]
```
### COPY vs ADD
```dockerfile
# COPY - preferred for local files
COPY ./src /app/src
COPY --chown=user:group files /app/
# ADD - can extract tars, fetch URLs (use sparingly)
ADD archive.tar.gz /app/
```
### ENV vs ARG
```dockerfile
# ARG - build-time only
ARG VERSION=1.0
# ENV - persists in image
ENV APP_VERSION=$VERSION
```
### EXPOSE
```dockerfile
EXPOSE 8080
EXPOSE 443/tcp
EXPOSE 53/udp
```
Documentation only - doesn't publish ports.
### ENTRYPOINT vs CMD
```dockerfile
# ENTRYPOINT - main executable
ENTRYPOINT ["python"]
# CMD - default arguments (can be overridden)
CMD ["app.py"]
# Combined: python app.py
# Override: docker run image other.py -> python other.py
```
### USER
```dockerfile
RUN useradd -r -s /bin/false appuser
USER appuser
```
### HEALTHCHECK
```dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/health || exit 1
```
## Best Practices
### Layer Caching
Order from least to most frequently changed:
```dockerfile
# Rarely changes - cached
FROM node:18-alpine
WORKDIR /app
# Changes when deps change
COPY package*.json ./
RUN npm install
# Changes frequently - rebuild each time
COPY . .
```
### Reduce Layers
Combine RUN commands:
```dockerfile
# Bad - 3 layers
RUN apt-get update
RUN apt-get install -y package
RUN rm -rf /var/lib/apt/lists/*
# Good - 1 layer
RUN apt-get update && \
apt-get install -y package && \
rm -rf /var/lib/apt/lists/*
```
### Security
```dockerfile
# Use specific tags
FROM node:18.17.0-alpine # Not :latest
# Non-root user
USER nobody
# Read-only filesystem
# (Set at runtime with --read-only)
# No secrets in image
# (Use build args or runtime secrets)
```
### .dockerignore
```
.git
.gitignore
node_modules
*.log
.env
Dockerfile
docker-compose.yaml
README.md
```
## Build Commands
```bash
# Basic build
docker build -t myimage:tag .
# With build args
docker build --build-arg VERSION=1.0 -t myimage .
# No cache
docker build --no-cache -t myimage .
# Specific Dockerfile
docker build -f Dockerfile.prod -t myimage .
# Multi-platform
docker buildx build --platform linux/amd64,linux/arm64 -t myimage .
```
## Debugging Builds
```bash
# Build with progress output
docker build --progress=plain -t myimage .
# Inspect layers
docker history myimage
# Check image size
docker images myimage
```

View File

@@ -0,0 +1,229 @@
# Docker Networking Reference
## Network Drivers
### Bridge (Default)
Isolated container network with port mapping.
```yaml
networks:
app-network:
driver: bridge
```
- Containers get private IPs (172.17.0.0/16 default)
- Port mapping exposes services (`-p 80:80`)
- DNS resolution between containers by name
- Default for single-host deployments
### Host
Container shares host network stack.
```yaml
services:
app:
network_mode: host
```
- No network isolation
- No port mapping needed (container uses host ports)
- Best performance (no NAT overhead)
- Use for: Network tools, performance-critical apps
### Macvlan
Container gets own MAC address on physical network.
```yaml
networks:
lan:
driver: macvlan
driver_opts:
parent: eth0
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
ip_range: 192.168.1.128/25
```
- Container appears as physical device on LAN
- Direct network access, no port mapping
- Use for: Services needing LAN presence (DNS, DHCP)
- Requires promiscuous mode on parent interface
### IPvlan
Like macvlan but shares host MAC address.
```yaml
networks:
lan:
driver: ipvlan
driver_opts:
parent: eth0
ipvlan_mode: l2 # or l3
```
- L2 mode: Same subnet as host
- L3 mode: Different subnet, requires routing
- Use when: Macvlan blocked by switch, cloud environments
### None
No networking.
```yaml
services:
isolated:
network_mode: none
```
## Port Mapping
```yaml
ports:
# Simple mapping
- "80:80"
# Different host port
- "8080:80"
# Localhost only
- "127.0.0.1:8080:80"
# UDP
- "53:53/udp"
# Range
- "8080-8090:8080-8090"
# Random host port
- "80"
```
## DNS and Service Discovery
### Automatic DNS
Containers on same network resolve each other by service name:
```yaml
services:
web:
networks:
- app
db:
networks:
- app
```
`web` can reach `db` at hostname `db`.
### Aliases
```yaml
services:
db:
networks:
app:
aliases:
- database
- mysql
```
### Custom DNS
```yaml
services:
app:
dns:
- 8.8.8.8
- 8.8.4.4
dns_search:
- example.com
```
## Network Isolation
### Internal Networks
No external connectivity:
```yaml
networks:
backend:
internal: true
```
### Multiple Networks
```yaml
services:
web:
networks:
- frontend
- backend
db:
networks:
- backend # Not on frontend
networks:
frontend:
backend:
internal: true
```
## Static IPs
```yaml
services:
app:
networks:
app-network:
ipv4_address: 172.20.0.10
networks:
app-network:
ipam:
config:
- subnet: 172.20.0.0/24
```
## Troubleshooting
### Inspect Network
```bash
docker network ls
docker network inspect <network>
```
### Container Network Info
```bash
docker inspect <container> --format '{{json .NetworkSettings.Networks}}'
```
### Test Connectivity
```bash
# From inside container
docker exec <container> ping <target>
docker exec <container> curl <url>
# Check DNS
docker exec <container> nslookup <hostname>
```
### Common Issues
| Problem | Check |
|---------|-------|
| Can't reach container | Port mapping, firewall, network attachment |
| DNS not working | Same network, container running |
| Slow network | Network mode, MTU settings |
| Port already in use | `lsof -i :<port>`, change mapping |

View File

@@ -0,0 +1,227 @@
# Docker on Proxmox VMs
Best practices for running Docker workloads on Proxmox VE.
## Template Selection
Use Docker-ready templates (102+) which have Docker pre-installed:
| Template ID | Name | Docker? |
|-------------|------|---------|
| 100 | tmpl-ubuntu-2404-base | No |
| 101 | tmpl-ubuntu-2404-standard | No |
| 102 | tmpl-ubuntu-2404-docker | Yes |
| 103 | tmpl-ubuntu-2404-github-runner | Yes |
| 104 | tmpl-ubuntu-2404-pihole | Yes |
**DO NOT** install Docker via cloud-init on templates 102+.
## VM vs LXC for Docker
| Factor | VM (QEMU) | LXC Unprivileged | LXC Privileged |
|--------|-----------|------------------|----------------|
| Docker support | Full | Limited | Works but risky |
| Isolation | Complete | Shared kernel | Shared kernel |
| Overhead | Higher | Lower | Lower |
| Nested containers | Works | Requires config | Works |
| GPU passthrough | Yes | Limited | Limited |
| Security | Best | Good | Avoid |
**Recommendation:** Use VMs for Docker workloads. LXC adds complexity for marginal resource savings.
## VM Sizing for Docker
### Minimum for Docker host
```
CPU: 2 cores
RAM: 4 GB (2 GB for OS, 2 GB for containers)
Disk: 50 GB (20 GB OS, 30 GB images/volumes)
```
### Per-container overhead
```
Base: ~10 MB RAM per container
Image layers: Shared between containers
Volumes: Depends on data
```
### Sizing formula
```
Total RAM = 2 GB (OS) + sum(container memory limits) + 20% buffer
Total Disk = 20 GB (OS) + images + volumes + 20% buffer
```
## Storage Backend Selection
| Proxmox Storage | Docker Use Case | Performance |
|-----------------|-----------------|-------------|
| local-lvm | General workloads | Good |
| ZFS | Database containers | Better (snapshots) |
| Ceph | HA workloads | Good (distributed) |
| NFS | Shared config/data | Moderate |
### Volume mapping to Proxmox storage
```yaml
# docker-compose.yaml
volumes:
db_data:
driver: local
driver_opts:
type: none
device: /mnt/storage/mysql # Map to Proxmox storage mount
o: bind
```
## Network Considerations
### Bridge mode (default)
Container gets private IP, NAT to VM IP. Good for most workloads.
```yaml
services:
web:
ports:
- "80:80" # VM_IP:80 -> container:80
```
### Host mode
Container shares VM network stack. Use for network tools or performance.
```yaml
services:
pihole:
network_mode: host # Container uses VM's IPs directly
```
### Macvlan (direct LAN access)
Container gets own IP on Proxmox bridge.
```bash
# On Docker host (VM)
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
lan
```
```yaml
services:
app:
networks:
lan:
ipv4_address: 192.168.1.50
networks:
lan:
external: true
```
**Note:** Requires Proxmox bridge without VLAN tagging on that interface, or pass-through the VLAN-tagged interface to VM.
## Resource Limits
Always set limits to prevent container runaway affecting VM:
```yaml
services:
app:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
```
## GPU Passthrough
For containers needing GPU (AI/ML, transcoding):
1. **Proxmox:** Pass GPU to VM
```
hostpci0: 0000:01:00.0,pcie=1
```
2. **VM:** Install NVIDIA drivers + nvidia-container-toolkit
3. **Compose:**
```yaml
services:
plex:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
```
## Backup Considerations
### What to backup
| Data | Method | Location |
|------|--------|----------|
| VM disk | Proxmox vzdump | Includes everything |
| Docker volumes | docker run --volumes-from | Application-level |
| Compose files | Git | Version control |
### Proxmox backup includes Docker
When backing up the VM with vzdump, all Docker data (images, volumes, containers) is included.
```bash
vzdump <vmid> --mode snapshot --storage backup
```
### Application-consistent backups
For databases, use pre/post scripts:
```bash
# Pre-backup: flush and lock
docker exec mysql mysql -e "FLUSH TABLES WITH READ LOCK;"
# vzdump runs...
# Post-backup: unlock
docker exec mysql mysql -e "UNLOCK TABLES;"
```
## Troubleshooting
### Container can't reach internet
1. Check VM can reach internet: `ping 8.8.8.8`
2. Check Docker DNS: `docker run --rm alpine nslookup google.com`
3. Check iptables forwarding: `sysctl net.ipv4.ip_forward`
### Port not accessible from LAN
1. Check Proxmox firewall allows port
2. Check VM firewall (ufw/iptables)
3. Check container is bound to 0.0.0.0 not 127.0.0.1
### Disk space issues
```bash
# Check Docker disk usage
docker system df
# Clean up
docker system prune -a --volumes # WARNING: removes all unused data
# Check VM disk
df -h
```

View File

@@ -0,0 +1,140 @@
# LXC vs Docker Containers
Understanding when to use Proxmox LXC containers vs Docker containers.
## Fundamental Differences
| Aspect | LXC (Proxmox) | Docker |
|--------|---------------|--------|
| Abstraction | System container (full OS) | Application container |
| Init system | systemd, runit, etc. | Single process (PID 1) |
| Management | Proxmox (pct) | Docker daemon |
| Persistence | Stateful by default | Ephemeral by default |
| Updates | apt/yum inside container | Replace container |
| Networking | Proxmox managed | Docker managed |
## When to Use LXC
- **Long-running services** with traditional management (systemd, cron)
- **Multi-process applications** that expect init system
- **Legacy apps** not designed for containers
- **Dev/test environments** mimicking full VMs
- **Resource efficiency** when full VM isolation not needed
- **Direct Proxmox management** (backup, snapshots, migration)
```bash
# Create LXC
pct create 200 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
--hostname mycontainer \
--storage local-lvm \
--rootfs local-lvm:8 \
--cores 2 \
--memory 2048 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp
```
## When to Use Docker
- **Microservices** with single responsibility
- **CI/CD pipelines** with reproducible builds
- **Rapid deployment** and scaling
- **Application isolation** within a host
- **Compose stacks** with multi-container apps
- **Ecosystem tooling** (registries, orchestration)
```yaml
# docker-compose.yaml
services:
app:
image: myapp:1.0
restart: unless-stopped
```
## Decision Matrix
| Scenario | Recommendation | Rationale |
|----------|---------------|-----------|
| Pi-hole | Docker on VM | Easy updates, compose ecosystem |
| Database server | LXC or VM | Stateful, traditional management |
| Web app microservice | Docker | Ephemeral, scalable |
| Development environment | LXC | Full OS, multiple services |
| CI runner | Docker on VM | Isolation, reproducibility |
| Network appliance | LXC | Direct network access, systemd |
| Home automation | Docker on VM | Compose stacks, easy backup |
## Hybrid Approach
Common pattern: **VM runs Docker**, managed by Proxmox.
```
Proxmox Node
├── VM: docker-host-1 (template 102)
│ ├── Container: nginx
│ ├── Container: app
│ └── Container: redis
├── VM: docker-host-2 (template 102)
│ ├── Container: postgres
│ └── Container: backup
└── LXC: pihole (direct network)
```
Benefits:
- Proxmox handles VM-level backup/migration
- Docker handles application deployment
- Clear separation of concerns
## Docker in LXC (Not Recommended)
Running Docker inside LXC is possible but adds complexity:
### Requirements
1. Privileged container OR nested containers enabled
2. AppArmor profile modifications
3. Keyctl feature enabled
```bash
# LXC config (Proxmox)
lxc.apparmor.profile: unconfined
lxc.cgroup.devices.allow: a
lxc.cap.drop:
features: keyctl=1,nesting=1
```
### Issues
- Security: Reduced isolation
- Compatibility: Some Docker features broken
- Debugging: Two container layers
- Backup: More complex
**Recommendation:** Use VM with Docker instead.
## Resource Comparison
For equivalent workload:
| Resource | VM + Docker | LXC | Docker in LXC |
|----------|-------------|-----|---------------|
| RAM overhead | ~500 MB | ~50 MB | ~100 MB |
| Disk overhead | ~5 GB | ~500 MB | ~1 GB |
| Boot time | 30-60s | 2-5s | 5-10s |
| Isolation | Full | Shared kernel | Shared kernel |
| Complexity | Low | Low | High |
## Migration Paths
### LXC to Docker
1. Export application config from LXC
2. Create Dockerfile/compose
3. Build image
4. Deploy to Docker host
5. Migrate data volumes
### Docker to LXC
1. Install service directly in LXC (apt/yum)
2. Configure with systemd
3. Migrate data
4. Update Proxmox firewall rules

View File

@@ -0,0 +1,212 @@
# Docker Troubleshooting Reference
## Common Errors
| Error | Cause | Solution |
|-------|-------|----------|
| Container exits immediately | Bad entrypoint, missing deps | Check logs, verify CMD |
| Port already in use | Conflict with host/other container | `lsof -i :<port>`, change mapping |
| Volume permission denied | UID mismatch | Check ownership, use named volumes |
| Network not found | Network removed/not created | `docker network create` |
| Image pull failed | Registry/auth/name issue | Check registry, credentials, name |
| OOM killed | Exceeded memory limit | Increase limit or optimize app |
| DNS resolution failed | Network config issue | Check DNS settings, network mode |
| Health check failing | App not responding | Check command, increase timeout |
## Diagnostic Commands
### Container Status
```bash
# List all containers (including stopped)
docker ps -a
# Check exit code
docker inspect <container> --format '{{.State.ExitCode}}'
# Check restart count
docker inspect <container> --format '{{.RestartCount}}'
```
### Logs
```bash
# View logs
docker logs <container>
# Follow logs
docker logs -f <container>
# Last N lines
docker logs --tail 100 <container>
# With timestamps
docker logs -t <container>
# Since time
docker logs --since 10m <container>
```
### Resource Usage
```bash
# Real-time stats
docker stats
# Single container
docker stats <container>
# Disk usage
docker system df
docker system df -v # Verbose
```
### Container Details
```bash
# Full inspection
docker inspect <container>
# Specific fields
docker inspect <container> --format '{{.State.Status}}'
docker inspect <container> --format '{{json .NetworkSettings.Networks}}'
docker inspect <container> --format '{{.Mounts}}'
```
### Process and Network
```bash
# Running processes
docker top <container>
# Execute command
docker exec <container> ps aux
docker exec <container> netstat -tlnp
# Network connectivity
docker exec <container> ping <host>
docker exec <container> curl <url>
docker exec <container> nslookup <hostname>
```
## Troubleshooting Workflows
### Container Won't Start
1. Check logs: `docker logs <container>`
2. Check exit code: `docker inspect <container> --format '{{.State.ExitCode}}'`
3. Run interactively: `docker run -it <image> sh`
4. Check entrypoint/cmd: `docker inspect <image> --format '{{.Config.Cmd}}'`
### Container Keeps Restarting
1. Check logs for errors
2. Verify health check if configured
3. Check resource limits (OOM)
4. Test entrypoint manually
### Network Issues
1. Verify network exists: `docker network ls`
2. Check container attached: `docker inspect <container> --format '{{.NetworkSettings.Networks}}'`
3. Test DNS: `docker exec <container> nslookup <service>`
4. Check port mapping: `docker port <container>`
### Volume Issues
1. Check mount: `docker inspect <container> --format '{{.Mounts}}'`
2. Verify permissions inside: `docker exec <container> ls -la /path`
3. Check host path exists (bind mounts)
4. Try named volume instead
### Performance Issues
1. Check resource usage: `docker stats`
2. Review limits: `docker inspect <container> --format '{{.HostConfig.Memory}}'`
3. Check for resource contention
4. Profile application inside container
## Cleanup
```bash
# Remove stopped containers
docker container prune
# Remove unused images
docker image prune
# Remove unused volumes
docker volume prune
# Remove unused networks
docker network prune
# Remove everything unused
docker system prune -a --volumes
```
## Debugging Compose
```bash
# Validate compose file
docker compose config
# See what would run
docker compose config --services
# Check why service isn't starting
docker compose logs <service>
# Force recreate
docker compose up -d --force-recreate
# Rebuild images
docker compose up -d --build
```
## Common Compose Issues
| Problem | Check |
|---------|-------|
| Service not starting | `docker compose logs <service>` |
| depends_on not working | Service starts but app not ready (use healthcheck) |
| Volume not persisting | Check volume name, not recreated |
| Env vars not loading | Check .env file location, syntax |
| Network errors | Check network names, external networks |
## Health Check Debugging
```bash
# Check health status
docker inspect <container> --format '{{.State.Health.Status}}'
# View health log
docker inspect <container> --format '{{json .State.Health}}' | jq
# Test health command manually
docker exec <container> <health-command>
```
## Emergency Recovery
### Force Stop
```bash
docker kill <container>
```
### Remove Stuck Container
```bash
docker rm -f <container>
```
### Reset Docker
```bash
# Restart Docker daemon
sudo systemctl restart docker
# Or on macOS
# Restart Docker Desktop
```

View File

@@ -0,0 +1,230 @@
# Docker Volumes Reference
## Volume Types
### Named Volumes (Recommended)
Managed by Docker, stored in `/var/lib/docker/volumes/`.
```yaml
volumes:
db-data:
services:
db:
volumes:
- db-data:/var/lib/mysql
```
Benefits:
- Portable across hosts
- Backup-friendly
- No permission issues
- Can use volume drivers (NFS, etc.)
### Bind Mounts
Direct host path mapping.
```yaml
services:
web:
volumes:
- ./config:/etc/app/config:ro
- /host/data:/container/data
```
Benefits:
- Direct file access from host
- Development workflow (live reload)
- Access to host files
Drawbacks:
- Host-dependent paths
- Permission issues possible
- Less portable
### tmpfs Mounts
In-memory storage (Linux only).
```yaml
services:
app:
tmpfs:
- /tmp
- /run:size=100m
```
Benefits:
- Fast (RAM-based)
- Secure (not persisted)
- Good for secrets, cache
## Volume Options
### Read-Only
```yaml
volumes:
- ./config:/etc/app/config:ro
```
### Bind Propagation
```yaml
volumes:
- type: bind
source: ./data
target: /data
bind:
propagation: rslave
```
### Volume Driver Options
```yaml
volumes:
nfs-data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/export/data"
```
## Common Patterns
### Database Data
```yaml
services:
postgres:
image: postgres:15
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
volumes:
pgdata:
```
### Configuration Files
```yaml
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html:ro
```
### Shared Data Between Services
```yaml
services:
app:
volumes:
- shared:/data
worker:
volumes:
- shared:/data
volumes:
shared:
```
### Log Persistence
```yaml
services:
app:
volumes:
- logs:/var/log/app
volumes:
logs:
```
## Backup and Restore
### Backup Named Volume
```bash
# Create backup
docker run --rm \
-v myvolume:/source:ro \
-v $(pwd):/backup \
alpine tar czf /backup/myvolume.tar.gz -C /source .
# Restore backup
docker run --rm \
-v myvolume:/target \
-v $(pwd):/backup \
alpine tar xzf /backup/myvolume.tar.gz -C /target
```
### Copy Files from Volume
```bash
docker cp <container>:/path/to/file ./local-file
```
## Volume Management
```bash
# List volumes
docker volume ls
# Inspect volume
docker volume inspect <volume>
# Remove unused volumes
docker volume prune
# Remove specific volume
docker volume rm <volume>
# Create volume manually
docker volume create --name myvolume
```
## Permissions
### Common Permission Issues
```bash
# Check container user
docker exec <container> id
# Check volume permissions
docker exec <container> ls -la /data
```
### Solutions
```yaml
# Run as specific user
services:
app:
user: "1000:1000"
volumes:
- ./data:/data
```
Or fix host permissions:
```bash
chown -R 1000:1000 ./data
```
## Best Practices
1. **Use named volumes for data** - More portable than bind mounts
2. **Read-only when possible** - Use `:ro` for config files
3. **Separate concerns** - Different volumes for data, config, logs
4. **Backup strategy** - Plan for volume backup/restore
5. **Don't store in image** - Data should be in volumes, not image layers
6. **Use .dockerignore** - Exclude data directories from build context