docs refactor
All checks were successful
Datadog Software Composition Analysis / Datadog SBOM Generation and Upload (push) Successful in 52s
Datadog Secrets Scanning / Datadog Static Analyzer (push) Successful in 1m1s
Datadog Static Analysis / Datadog Static Analyzer (push) Successful in 5m50s

This commit is contained in:
2025-10-09 18:21:23 -04:00
parent c9a3a21f07
commit ad81d7f3db
39 changed files with 12551 additions and 1037 deletions

View File

@ -0,0 +1,735 @@
---
version: "1.0"
date: "2025-01-15"
author: "DWS Foldsite Team"
title: "Docker Deployment"
description: "Running Foldsite in Docker containers"
summary: "Complete guide to deploying Foldsite with Docker for consistent, isolated, and portable deployments."
quick_tips:
- "Docker ensures consistent environments across development and production"
- "Use docker-compose for easy multi-container setup"
- "Mount content as volumes for live updates without rebuilding"
---
# Docker Deployment
Docker provides isolated, reproducible deployments of Foldsite. Perfect for testing, staging, and production environments.
## Why Docker?
**Benefits:**
- **Consistency** - Same environment everywhere
- **Isolation** - Dependencies don't conflict with system
- **Portability** - Run anywhere Docker runs
- **Easy deployment** - Single command to start
- **Version control** - Docker images are versioned
**Use cases:**
- Team development (everyone has same environment)
- Staging environments before production
- Production deployments
- CI/CD pipelines
- Cloud platform deployments
## Prerequisites
### Install Docker
**macOS:**
```bash
# Download Docker Desktop from docker.com
# Or use Homebrew
brew install --cask docker
```
**Linux (Ubuntu/Debian):**
```bash
# Update package index
sudo apt update
# Install Docker
sudo apt install docker.io docker-compose
# Add your user to docker group
sudo usermod -aG docker $USER
# Log out and back in for group changes
```
**Windows:**
```bash
# Download Docker Desktop from docker.com
# Requires WSL2
```
**Verify installation:**
```bash
docker --version
docker-compose --version
```
## Quick Start with Docker Compose
### Step 1: Create docker-compose.yml
In your Foldsite directory:
```yaml
version: '3.8'
services:
foldsite:
image: python:3.11-slim
container_name: foldsite
working_dir: /app
command: >
sh -c "pip install -r requirements.txt &&
python main.py --config config.toml"
ports:
- "8081:8081"
volumes:
- .:/app
- ./my-site/content:/app/content
- ./my-site/templates:/app/templates
- ./my-site/styles:/app/styles
environment:
- PYTHONUNBUFFERED=1
restart: unless-stopped
```
### Step 2: Create config.toml for Docker
```toml
[paths]
content_dir = "/app/content"
templates_dir = "/app/templates"
styles_dir = "/app/styles"
[server]
listen_address = "0.0.0.0" # Important: bind to all interfaces
listen_port = 8081
admin_browser = false
max_threads = 4
debug = false
access_log = true
```
### Step 3: Start Container
```bash
# Start in background
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose down
```
Visit `http://localhost:8081` to see your site!
## Building a Custom Docker Image
For production, build a dedicated Foldsite image:
### Create Dockerfile
```dockerfile
# Dockerfile
FROM python:3.11-slim
# Set working directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Copy requirements first (for caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Create directories for content
RUN mkdir -p /content /templates /styles
# Expose port
EXPOSE 8081
# Run application
CMD ["python", "main.py", "--config", "/app/config.toml"]
```
### Build Image
```bash
# Build image
docker build -t foldsite:latest .
# Tag for versioning
docker tag foldsite:latest foldsite:1.0.0
```
### Run Container
```bash
docker run -d \
--name foldsite \
-p 8081:8081 \
-v $(pwd)/my-site/content:/content \
-v $(pwd)/my-site/templates:/templates \
-v $(pwd)/my-site/styles:/styles \
foldsite:latest
```
## Development with Docker
### Hot Reload Setup
Mount your code as volumes for live updates:
```yaml
# docker-compose.dev.yml
version: '3.8'
services:
foldsite:
build: .
container_name: foldsite-dev
ports:
- "8081:8081"
volumes:
# Mount everything for development
- .:/app
- ./my-site/content:/app/content
- ./my-site/templates:/app/templates
- ./my-site/styles:/app/styles
environment:
- PYTHONUNBUFFERED=1
- FLASK_ENV=development
command: >
sh -c "pip install -r requirements.txt &&
python main.py --config config.toml"
```
**Usage:**
```bash
# Start development environment
docker-compose -f docker-compose.dev.yml up
# Changes to content, templates, and styles appear immediately
# Code changes require restart
```
### Interactive Development
Run commands inside container:
```bash
# Start bash session in running container
docker exec -it foldsite bash
# Inside container, you can:
python main.py --config config.toml
pip install new-package
ls /app/content
```
## Production Docker Setup
### Multi-Stage Build
Optimize image size with multi-stage build:
```dockerfile
# Dockerfile.production
# Stage 1: Build dependencies
FROM python:3.11-slim as builder
WORKDIR /app
# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# Stage 2: Runtime
FROM python:3.11-slim
WORKDIR /app
# Copy Python dependencies from builder
COPY --from=builder /root/.local /root/.local
# Copy application
COPY . .
# Create non-root user
RUN useradd -m -u 1000 foldsite && \
chown -R foldsite:foldsite /app
# Switch to non-root user
USER foldsite
# Make sure scripts in .local are usable
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8081
# Use Gunicorn for production
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8081", "main:app"]
```
### Production docker-compose.yml
```yaml
version: '3.8'
services:
foldsite:
build:
context: .
dockerfile: Dockerfile.production
container_name: foldsite-prod
ports:
- "8081:8081"
volumes:
- ./content:/app/content:ro # Read-only
- ./templates:/app/templates:ro
- ./styles:/app/styles:ro
environment:
- PYTHONUNBUFFERED=1
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8081/"]
interval: 30s
timeout: 10s
retries: 3
```
## Docker Compose Examples
### With Nginx Reverse Proxy
```yaml
version: '3.8'
services:
foldsite:
build: .
container_name: foldsite
expose:
- "8081"
volumes:
- ./content:/app/content:ro
- ./templates:/app/templates:ro
- ./styles:/app/styles:ro
restart: always
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- foldsite
restart: always
```
**nginx.conf:**
```nginx
events {
worker_connections 1024;
}
http {
upstream foldsite {
server foldsite:8081;
}
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://foldsite;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Cache static assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
proxy_pass http://foldsite;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
}
```
### Multiple Sites
Run multiple Foldsite instances:
```yaml
version: '3.8'
services:
blog:
build: .
ports:
- "8081:8081"
volumes:
- ./blog/content:/app/content
- ./blog/templates:/app/templates
- ./blog/styles:/app/styles
restart: always
portfolio:
build: .
ports:
- "8082:8081"
volumes:
- ./portfolio/content:/app/content
- ./portfolio/templates:/app/templates
- ./portfolio/styles:/app/styles
restart: always
```
## Volume Management
### Content Volumes
**Development** - Mount host directories:
```yaml
volumes:
- ./my-site/content:/app/content
- ./my-site/templates:/app/templates
- ./my-site/styles:/app/styles
```
**Production** - Read-only mounts:
```yaml
volumes:
- ./content:/app/content:ro
- ./templates:/app/templates:ro
- ./styles:/app/styles:ro
```
### Named Volumes
For persistent data:
```yaml
services:
foldsite:
volumes:
- content-data:/app/content
- templates-data:/app/templates
volumes:
content-data:
templates-data:
```
**Backup named volumes:**
```bash
# Backup
docker run --rm \
-v foldsite_content-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/content-backup.tar.gz -C /data .
# Restore
docker run --rm \
-v foldsite_content-data:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/content-backup.tar.gz -C /data
```
## Environment Variables
Pass configuration via environment:
```yaml
services:
foldsite:
environment:
- FOLDSITE_DEBUG=false
- FOLDSITE_PORT=8081
- FOLDSITE_MAX_THREADS=4
```
**Use in config:**
```python
# In a config loader
import os
debug = os.getenv('FOLDSITE_DEBUG', 'false').lower() == 'true'
port = int(os.getenv('FOLDSITE_PORT', '8081'))
```
## Common Docker Commands
### Container Management
```bash
# Start containers
docker-compose up -d
# Stop containers
docker-compose down
# Restart
docker-compose restart
# View logs
docker-compose logs -f
# View logs for specific service
docker-compose logs -f foldsite
# Exec into running container
docker exec -it foldsite bash
# View running containers
docker ps
# View all containers (including stopped)
docker ps -a
```
### Image Management
```bash
# Build image
docker-compose build
# Pull images
docker-compose pull
# List images
docker images
# Remove unused images
docker image prune
# Remove all unused data
docker system prune -a
```
### Debugging
```bash
# Check container logs
docker logs foldsite
# Follow logs
docker logs -f foldsite
# Inspect container
docker inspect foldsite
# View container stats
docker stats foldsite
# Check container health
docker ps --filter health=healthy
```
## Troubleshooting
### Port Already in Use
```
Error: port is already allocated
```
**Solution:** Change port mapping:
```yaml
ports:
- "8082:8081" # Map to different host port
```
### Permission Errors
```
PermissionError: [Errno 13] Permission denied
```
**Solution:** Fix volume permissions:
```bash
# Fix ownership
sudo chown -R $USER:$USER ./my-site
# Or run container as your user
docker run --user $(id -u):$(id -g) ...
```
### Container Won't Start
```bash
# Check logs
docker-compose logs
# Common issues:
# 1. Missing requirements.txt
# 2. Wrong working directory
# 3. Port conflicts
# 4. Volume mount errors
```
### Changes Not Appearing
**Content changes:**
- Should appear immediately (volumes mounted)
- Try hard refresh in browser
**Code changes:**
- Require container restart: `docker-compose restart`
**Template changes:**
- Should appear immediately
- Check volume mounts are correct
### Container Crashes
```bash
# View exit reason
docker ps -a
# Check logs
docker logs foldsite
# Try running interactively
docker run -it foldsite bash
```
## Performance Optimization
### Resource Limits
Limit container resources:
```yaml
services:
foldsite:
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
```
### Build Cache
Speed up builds:
```bash
# Use BuildKit
DOCKER_BUILDKIT=1 docker build .
# Cache from registry
docker build --cache-from myregistry/foldsite:latest .
```
### Layer Optimization
Order Dockerfile for better caching:
```dockerfile
# Dependencies first (change rarely)
COPY requirements.txt .
RUN pip install -r requirements.txt
# Code last (changes often)
COPY . .
```
## CI/CD Integration
### GitHub Actions Example
```yaml
# .github/workflows/docker.yml
name: Build Docker Image
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build image
run: docker build -t foldsite:${{ github.sha }} .
- name: Test
run: |
docker run -d --name test foldsite:${{ github.sha }}
docker logs test
docker stop test
```
## Cloud Platform Deployment
### Deploy to AWS ECS
```bash
# Build and push to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com
docker tag foldsite:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/foldsite:latest
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/foldsite:latest
```
### Deploy to Google Cloud Run
```bash
# Build and push to GCR
gcloud builds submit --tag gcr.io/PROJECT_ID/foldsite
gcloud run deploy --image gcr.io/PROJECT_ID/foldsite --platform managed
```
### Deploy to Azure Container Instances
```bash
# Create container instance
az container create \
--resource-group myResourceGroup \
--name foldsite \
--image myregistry.azurecr.io/foldsite:latest \
--ports 8081
```
## Next Steps
- **[Production Deployment](production.md)** - Production-grade setup
- **[Local Development](local-development.md)** - Development workflow
- **[Support](../support.md)** - Get help
Docker provides a solid foundation for deploying Foldsite anywhere. From development to production, containers ensure consistency and reliability.