# Configuration Reference This document catalogs all configuration templates and files available in the `configs/` directory for deploying services on systems-prod-01. ## Template Overview | Template | Purpose | Service Type | |----------|---------|--------------| | `wordpress-template.yml` | WordPress with MariaDB | WordPress Site | | `invoiceninja-template.yml` | Invoice Ninja invoicing app | Web Application | | `traefik/docker-compose.yml` | Traefik reverse proxy | Infrastructure | ## Traefik Configuration ### Location `configs/traefik/` ### Files - **`docker-compose.yml`** - Traefik container orchestration - **`traefik.yml`** - Static configuration (entrypoints, providers, API) - **`dynamic.yml`** - Dynamic configuration (routers, services, middlewares) ### When to Use - Setting up a new server from scratch - Reconfiguring the reverse proxy - Adding global middlewares or routes - Reference for Traefik label syntax ### Key Features - Automatic SSL with Let's Encrypt - HTTP to HTTPS redirect - Docker provider for automatic service discovery - Dashboard on port 8080 with basic auth ## WordPress Template ### Location `configs/wordpress-template.yml` ### Supporting Files - `configs/wordpress.env.example` - Environment variables template - `configs/uploads.ini` - PHP upload size configuration - `configs/my.cnf` - MariaDB optimization ### When to Use - Migrating a WordPress site from another server - Deploying a new WordPress site - Reference for WordPress + Traefik integration ### Key Features - WordPress 6.7 with Apache - MariaDB 10.11 (LTS, WordPress-compatible) - Traefik integration with automatic SSL - Health checks for database - Separate internal network for database ### Usage Example ```bash # 1. Create service directory ssh jared@15.204.247.153 "mkdir -p ~/services/SITENAME" # 2. Copy and adapt template cp configs/wordpress-template.yml /tmp/docker-compose.yml # Edit with your site details # 3. Deploy to server scp /tmp/docker-compose.yml jared@15.204.247.153:~/services/SITENAME/ ssh jared@15.204.247.153 "cd ~/services/SITENAME && docker compose up -d" ``` ### Template Customization Checklist - [ ] Replace `SITENAME` with actual service name - [ ] Update domain names in Traefik labels - [ ] Set database credentials - [ ] Configure volume paths - [ ] Adjust memory/resource limits if needed - [ ] Verify network names match server setup ## Invoice Ninja Template ### Location `configs/invoiceninja-template.yml` ### Supporting Files - `configs/invoiceninja.env.example` - Environment variables - `configs/invoiceninja-nginx.conf` - Nginx configuration ### When to Use - Deploying Invoice Ninja for invoicing/billing - Reference for PHP-FPM + Nginx + MySQL setup - Multi-container application pattern ### Key Features - Invoice Ninja v5 - Nginx + PHP-FPM architecture - MySQL database with health checks - Persistent storage for invoices and uploads - Traefik integration ## Configuration Patterns ### Standard Service Structure All services follow this pattern: ```yaml services: app: image: application:latest restart: unless-stopped networks: - traefik # External access - internal # Backend communication labels: - "traefik.enable=true" - "traefik.http.routers.SERVICENAME.rule=Host(`domain.com`)" - "traefik.http.routers.SERVICENAME.entrypoints=websecure" - "traefik.http.routers.SERVICENAME.tls.certresolver=letsencrypt" volumes: - ./data:/var/www/html networks: traefik: external: true internal: external: true ``` ### Traefik Labels Guide **Basic routing:** ```yaml - "traefik.enable=true" - "traefik.http.routers.SERVICENAME.rule=Host(`domain.com`)" - "traefik.http.routers.SERVICENAME.entrypoints=websecure" - "traefik.http.routers.SERVICENAME.tls.certresolver=letsencrypt" ``` **Multiple domains:** ```yaml - "traefik.http.routers.SERVICENAME.rule=Host(`domain.com`) || Host(`www.domain.com`)" ``` **Custom port (if app doesn't use 80):** ```yaml - "traefik.http.services.SERVICENAME.loadbalancer.server.port=8080" ``` **Basic auth middleware:** ```yaml - "traefik.http.routers.SERVICENAME.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=user:$$apr1$$hashed$$password" ``` ## Environment Variable Management ### Best Practices 1. **Never commit secrets** - Use `.env` files (gitignored) 2. **Use example files** - Provide `.env.example` with placeholders 3. **Document required vars** - List all necessary environment variables 4. **Escape dollar signs** - In docker-compose.yml, use `$$` for literal `$` ### Example .env File Structure ```bash # Database Configuration DB_NAME=myapp_db DB_USER=myapp_user DB_PASSWORD=CHANGE_ME_STRONG_PASSWORD # Application Settings APP_NAME=MyApplication APP_URL=https://myapp.com APP_DEBUG=false # Email Configuration (if needed) MAIL_HOST=smtp.example.com MAIL_PORT=587 MAIL_USERNAME=user@example.com MAIL_PASSWORD=CHANGE_ME ``` ## Creating Custom Templates When creating a new service template: 1. **Start with a working configuration** from existing templates 2. **Document all required changes** in comments 3. **Include health checks** where possible 4. **Use standard network pattern** (traefik + internal) 5. **Follow naming conventions** (lowercase, hyphens) 6. **Test thoroughly** before documenting ### Template File Naming - `SERVICETYPE-template.yml` - Docker Compose template - `SERVICETYPE.env.example` - Environment variables - `SERVICETYPE-config-file` - Additional config files ## Docker Compose Tips ### Volume Management **Bind mounts** (for configs): ```yaml volumes: - ./config.php:/var/www/html/config.php:ro ``` **Named volumes** (for databases): ```yaml volumes: - db_data:/var/lib/mysql volumes: db_data: ``` ### Health Checks **Web application:** ```yaml healthcheck: test: ["CMD", "curl", "-f", "http://localhost/health"] interval: 30s timeout: 10s retries: 3 ``` **Database:** ```yaml healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 30s timeout: 10s retries: 5 ``` ### Resource Limits ```yaml deploy: resources: limits: cpus: '2.0' memory: 2G reservations: cpus: '0.5' memory: 512M ``` ## Network Configuration ### Existing Networks The server has two pre-configured Docker networks: - **traefik** (172.20.0.0/16) - External-facing services - **internal** (172.21.0.0/16) - Backend services ### When to Create New Networks Generally, use existing networks. Create a new network only when: - Service requires strict isolation - Complex multi-container setup needs dedicated network - Testing/development environment separation ## Troubleshooting Configuration Issues ### Template Not Working ```bash # Validate docker-compose syntax docker compose -f template.yml config # Check for common issues # - Indentation (YAML is space-sensitive) # - Missing quotes around special characters # - Incorrect network references # - Typos in service names ``` ### Traefik Not Routing ```bash # Check container is on traefik network docker inspect CONTAINER_NAME | grep Networks -A 10 # Verify Traefik labels docker inspect CONTAINER_NAME | grep traefik. # Check Traefik dashboard # https://traefik.hyperthrive.app ``` ### Environment Variables Not Loading ```bash # Verify .env file exists in same directory as docker-compose.yml ls -la ~/services/SERVICENAME/.env # Check variable interpolation docker compose config ``` ## See Also - [Services Inventory](./services-inventory.md) - Currently deployed services - [WordPress Operations](./wordpress-operations.md) - WordPress-specific guides - [Documentation Maintenance](./documentation-maintenance.md) - Adding new templates - [CLAUDE.md](../CLAUDE.md) - Project overview and deployment workflow