Docker Deployment¶
Deploy the documentation server with Docker for production use.
Quick Start¶
# Build the image
docker build -t markdown-docs-server .
# Run with your docs
docker run -d \
-p 8080:8080 \
-v $(pwd)/docs:/app/docs \
--name docs-server \
markdown-docs-server
Visit http://localhost:8080
Dockerfile¶
The included Dockerfile is production-optimized:
FROM python:3.13-slim
# Install uv
RUN pip install --no-cache-dir uv
# Set working directory
WORKDIR /app
# Copy dependency files
COPY pyproject.toml uv.lock ./
# Install dependencies
RUN uv sync --no-dev
# Copy source code
COPY src/ ./src/
# Create directories
RUN mkdir -p /app/docs /app/cache
# Default environment variables
ENV DOCS_ROOT=/app/docs
ENV CACHE_ROOT=/app/cache
ENV PORT=8080
# Expose port
EXPOSE 8080
# Run server
CMD ["uv", "run", "python", "-m", "docs_server"]
Features: - Python 3.13 slim base - Multi-stage build for minimal size - Non-root user (TODO: add in production) - Caching layers for fast rebuilds - Healthcheck support
Building¶
Basic Build¶
docker build -t my-docs .
With Build Args¶
docker build \
--build-arg PYTHON_VERSION=3.13 \
-t my-docs:v1.0.0 \
.
Multi-Platform¶
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t my-docs:latest \
.
Running¶
Development¶
docker run -it \
-p 8080:8080 \
-v $(pwd)/docs:/app/docs \
-e DEBUG=true \
markdown-docs-server
Production¶
docker run -d \
--name docs-server \
-p 8080:8080 \
-v /var/www/docs:/app/docs:ro \
-e BASE_URL=https://docs.mysite.com \
-e DEBUG=false \
--restart unless-stopped \
--memory=512m \
--cpus=1 \
markdown-docs-server
With Environment File¶
# Create .env file
cat > .env <<EOF
DOCS_ROOT=/app/docs
BASE_URL=https://docs.example.com
DEBUG=false
PORT=8080
EOF
# Run with env file
docker run -d \
--env-file .env \
-p 8080:8080 \
-v $(pwd)/docs:/app/docs \
markdown-docs-server
Docker Compose¶
Basic Setup¶
version: '3.8'
services:
docs:
build: .
ports:
- "8080:8080"
volumes:
- ./docs:/app/docs:ro
environment:
- BASE_URL=https://docs.mysite.com
- DEBUG=false
restart: unless-stopped
With Reverse Proxy¶
version: '3.8'
services:
docs:
build: .
expose:
- "8080"
volumes:
- ./docs:/app/docs:ro
environment:
- BASE_URL=https://docs.mysite.com
restart: unless-stopped
networks:
- web
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- docs
networks:
- web
networks:
web:
With Health Checks¶
version: '3.8'
services:
docs:
build: .
ports:
- "8080:8080"
volumes:
- ./docs:/app/docs:ro
environment:
- BASE_URL=https://docs.mysite.com
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
Volume Mounts¶
Read-Only Docs¶
docker run -v $(pwd)/docs:/app/docs:ro markdown-docs-server
Persistent Cache¶
docker run \
-v $(pwd)/docs:/app/docs:ro \
-v docs-cache:/app/cache \
markdown-docs-server
Assets Only¶
docker run \
-v $(pwd)/docs:/app/docs:ro \
-v $(pwd)/assets:/app/docs/assets:ro \
markdown-docs-server
Environment Variables¶
docker run \
-e DOCS_ROOT=/app/docs \
-e CACHE_ROOT=/app/cache \
-e BASE_URL=https://docs.example.com \
-e DEBUG=false \
-e PORT=8080 \
-p 8080:8080 \
markdown-docs-server
See Environment Variables for complete reference.
Networking¶
Host Network¶
docker run --network host markdown-docs-server
Custom Network¶
# Create network
docker network create docs-net
# Run container
docker run --network docs-net markdown-docs-server
Link to Other Containers¶
docker run \
--link database:db \
--link redis:cache \
markdown-docs-server
Resource Limits¶
Memory Limit¶
docker run --memory=512m markdown-docs-server
CPU Limit¶
docker run --cpus=1.5 markdown-docs-server
Combined¶
docker run \
--memory=512m \
--cpus=1 \
--memory-swap=1g \
markdown-docs-server
Production Best Practices¶
1. Use Specific Tags¶
# Bad
docker pull markdown-docs-server:latest
# Good
docker pull markdown-docs-server:v1.0.0
2. Read-Only Volumes¶
-v $(pwd)/docs:/app/docs:ro
3. Health Checks¶
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
4. Restart Policies¶
--restart unless-stopped
5. Logging¶
docker run \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
markdown-docs-server
6. Security¶
# Run as non-root (add to Dockerfile)
USER nobody
# Drop capabilities
--cap-drop=ALL
Monitoring¶
View Logs¶
# Real-time logs
docker logs -f docs-server
# Last 100 lines
docker logs --tail 100 docs-server
# Since timestamp
docker logs --since 2024-01-01T00:00:00 docs-server
Container Stats¶
docker stats docs-server
Health Check¶
docker inspect --format='{{json .State.Health}}' docs-server | jq
Troubleshooting¶
Container Won't Start¶
# Check logs
docker logs docs-server
# Inspect container
docker inspect docs-server
# Check if port is in use
docker ps | grep 8080
Permission Issues¶
# Check volume mounts
docker inspect docs-server | jq '.[0].Mounts'
# Fix permissions
chmod -R 755 docs/
Out of Memory¶
# Increase memory limit
docker update --memory=1g docs-server
# Or restart with new limit
docker stop docs-server
docker run --memory=1g ...
Updating¶
Rolling Update¶
# Pull new image
docker pull markdown-docs-server:latest
# Stop old container
docker stop docs-server
docker rm docs-server
# Start new container
docker run -d \
--name docs-server \
-p 8080:8080 \
-v $(pwd)/docs:/app/docs \
markdown-docs-server:latest
Zero-Downtime Update¶
Use Docker Compose:
docker-compose up -d --no-deps --build docs
Clean Up¶
Remove Container¶
docker stop docs-server
docker rm docs-server
Remove Image¶
docker rmi markdown-docs-server
Clean All¶
docker system prune -a
Next Steps¶
- Environment Variables - Configuration reference
- Production Tips - Optimization guide
- Examples - Advanced configurations