# TankStopp Docker Guide ## Overview This guide covers Docker deployment for the TankStopp fuel tracking application. TankStopp can be deployed using Docker in multiple ways: - **Single container** deployment - **Docker Compose** for complete stack - **Production deployment** with optimizations - **Development environment** with live reload ## Table of Contents - [Requirements](#requirements) - [Quick Start](#quick-start) - [Building Images](#building-images) - [Running Containers](#running-containers) - [Docker Compose](#docker-compose) - [Configuration](#configuration) - [Data Persistence](#data-persistence) - [Production Deployment](#production-deployment) - [Backup and Restore](#backup-and-restore) - [Monitoring](#monitoring) - [Troubleshooting](#troubleshooting) - [Best Practices](#best-practices) ## Requirements ### System Requirements - **Docker**: 20.10+ (with BuildKit support) - **Docker Compose**: 2.0+ (or docker-compose 1.29+) - **Memory**: 512MB RAM minimum, 1GB recommended - **Storage**: 2GB for application and data ### Host System - **Linux**: All distributions supported - **macOS**: Docker Desktop - **Windows**: Docker Desktop with WSL2 ## Quick Start ### Option 1: Using Makefile (Recommended) ```bash # Build and run production container make docker-build make docker-run # Or use docker-compose make docker-compose-up ``` ### Option 2: Direct Docker Commands ```bash # Build the image docker build -t tankstopp:latest . # Run the container docker run -d --name tankstopp \ -p 8080:8080 \ -v tankstopp_data:/app/data \ tankstopp:latest ``` ### Option 3: Docker Compose ```bash # Start the application docker-compose up -d # View logs docker-compose logs -f ``` The application will be available at `http://localhost:8080` ## Building Images ### Production Build ```bash # Using build script (recommended) ./scripts/docker/build.sh --tag tankstopp:v1.0.0 --env production # Using Makefile make docker-build # Using Docker directly docker build -t tankstopp:latest . ``` ### Development Build ```bash # Development image with debugging enabled ./scripts/docker/build.sh --tag tankstopp:dev --env development # Using Makefile make docker-build-dev ``` ### Multi-platform Build ```bash # Build for multiple architectures ./scripts/docker/build.sh \ --tag tankstopp:latest \ --platform linux/amd64,linux/arm64 ``` ### Build Arguments ```bash # Custom build with version info ./scripts/docker/build.sh \ --tag tankstopp:v1.0.0 \ --build-arg VERSION=1.0.0 \ --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') ``` ## Running Containers ### Basic Container ```bash # Simple run docker run -d --name tankstopp -p 8080:8080 tankstopp:latest # With environment variables docker run -d --name tankstopp \ -p 8080:8080 \ -e TANKSTOPP_APP_DEBUG=false \ -e TANKSTOPP_DATABASE_PATH=/app/data/fuel_stops.db \ tankstopp:latest ``` ### With Volume Mounts ```bash # Persistent data docker run -d --name tankstopp \ -p 8080:8080 \ -v tankstopp_data:/app/data \ -v $(pwd)/config.production.yaml:/app/config.yaml:ro \ tankstopp:latest ``` ### Development Container ```bash # Development with live reload docker run -d --name tankstopp-dev \ -p 8081:8080 \ -v $(pwd):/app:ro \ -v tankstopp_dev_data:/app/data \ -e TANKSTOPP_APP_DEBUG=true \ -e TANKSTOPP_APP_ENVIRONMENT=development \ tankstopp:dev ``` ## Docker Compose ### Basic Deployment ```yaml # docker-compose.yml version: '3.8' services: tankstopp: build: . ports: - "8080:8080" volumes: - tankstopp_data:/app/data environment: - TANKSTOPP_APP_ENVIRONMENT=production volumes: tankstopp_data: ``` ### Production Deployment ```bash # Use production override docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d # With deployment script ./scripts/docker/deploy.sh deploy --env production ``` ### Development Environment ```bash # Start development services docker-compose --profile dev up -d # Or using deployment script ./scripts/docker/deploy.sh deploy --env development ``` ### Available Profiles - **default**: Production application - **dev**: Development environment - **proxy**: With reverse proxy (Traefik) - **backup**: Database backup service ```bash # Enable specific profiles docker-compose --profile dev --profile backup up -d ``` ## Configuration ### Environment Variables All configuration can be set via environment variables: ```bash # Application Configuration TANKSTOPP_APP_ENVIRONMENT=production TANKSTOPP_APP_DEBUG=false TANKSTOPP_APP_NAME=TankStopp # Server Configuration TANKSTOPP_SERVER_HOST=0.0.0.0 TANKSTOPP_SERVER_PORT=8080 TANKSTOPP_SERVER_READ_TIMEOUT=30s # Database Configuration TANKSTOPP_DATABASE_PATH=/app/data/fuel_stops.db TANKSTOPP_DATABASE_CONNECTION_POOL_MAX_IDLE_CONNECTIONS=25 TANKSTOPP_DATABASE_LOGGING_LEVEL=error # Security Configuration TANKSTOPP_SECURITY_SESSION_SECURE_COOKIES=true TANKSTOPP_SECURITY_SESSION_TIMEOUT=24h # External Services TANKSTOPP_EXTERNAL_SERVICES_OVERPASS_API_URL=https://overpass-api.de/api/interpreter ``` ### Configuration Files Mount configuration files as volumes: ```bash # Production config docker run -d --name tankstopp \ -v $(pwd)/config.production.yaml:/app/config.yaml:ro \ tankstopp:latest # Custom config docker run -d --name tankstopp \ -v /path/to/custom-config.yaml:/app/config.yaml:ro \ tankstopp:latest ``` ### Docker Compose Environment ```yaml # docker-compose.yml services: tankstopp: environment: - TANKSTOPP_APP_ENVIRONMENT=production - TANKSTOPP_DATABASE_PATH=/app/data/fuel_stops.db # Or use env_file env_file: - .env.production ``` ## Data Persistence ### Volume Management ```bash # Create named volume docker volume create tankstopp_data # Inspect volume docker volume inspect tankstopp_data # List volumes docker volume ls # Remove volume (WARNING: Data loss!) docker volume rm tankstopp_data ``` ### Backup Volume Data ```bash # Backup volume to tar file docker run --rm \ -v tankstopp_data:/data \ -v $(pwd):/backup \ alpine tar czf /backup/tankstopp_backup_$(date +%Y%m%d).tar.gz -C /data . # Restore from backup docker run --rm \ -v tankstopp_data:/data \ -v $(pwd):/backup \ alpine sh -c "cd /data && tar xzf /backup/tankstopp_backup_20241207.tar.gz" ``` ### Host Directory Mounts ```bash # Use host directory for data mkdir -p /var/lib/tankstopp/data chown 1001:1001 /var/lib/tankstopp/data docker run -d --name tankstopp \ -p 8080:8080 \ -v /var/lib/tankstopp/data:/app/data \ tankstopp:latest ``` ## Production Deployment ### Recommended Production Setup ```yaml # docker-compose.prod.yml version: '3.8' services: tankstopp: image: tankstopp:latest restart: always ports: - "8080:8080" environment: - TANKSTOPP_APP_ENVIRONMENT=production - TANKSTOPP_APP_DEBUG=false - TANKSTOPP_SECURITY_SESSION_SECURE_COOKIES=true - TANKSTOPP_DATABASE_LOGGING_LEVEL=error - TANKSTOPP_LOGGING_LEVEL=info - TANKSTOPP_LOGGING_FORMAT=json volumes: - /var/lib/tankstopp/data:/app/data - /var/log/tankstopp:/app/logs - ./config.production.yaml:/app/config.yaml:ro deploy: resources: limits: cpus: '1.0' memory: 512M reservations: cpus: '0.5' memory: 256M healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/"] interval: 30s timeout: 5s retries: 3 logging: driver: "json-file" options: max-size: "50m" max-file: "3" ``` ### Reverse Proxy Setup ```yaml # With Traefik services: tankstopp: labels: - "traefik.enable=true" - "traefik.http.routers.tankstopp.rule=Host(`tankstopp.yourdomain.com`)" - "traefik.http.routers.tankstopp.tls=true" - "traefik.http.routers.tankstopp.tls.certresolver=letsencrypt" ``` ### High Availability ```bash # Scale service docker-compose up -d --scale tankstopp=3 # With deployment script ./scripts/docker/deploy.sh scale --replicas 3 ``` ### Security Hardening ```bash # Run as non-root user docker run -d --name tankstopp \ --user 1001:1001 \ -p 8080:8080 \ tankstopp:latest # Limit capabilities docker run -d --name tankstopp \ --cap-drop=ALL \ --cap-add=NET_BIND_SERVICE \ -p 8080:8080 \ tankstopp:latest # Read-only filesystem docker run -d --name tankstopp \ --read-only \ --tmpfs /tmp \ -v tankstopp_data:/app/data \ -p 8080:8080 \ tankstopp:latest ``` ## Backup and Restore ### Automated Backup ```bash # Using deployment script ./scripts/docker/deploy.sh backup # Manual backup docker-compose exec tankstopp \ sqlite3 /app/data/fuel_stops.db \ ".backup /app/data/backup_$(date +%Y%m%d_%H%M%S).db" ``` ### Backup Service ```yaml # docker-compose.yml services: backup: image: alpine:3.18 volumes: - tankstopp_data:/data:ro - ./backups:/backups command: | sh -c ' apk add --no-cache sqlite DATE=$$(date +%Y%m%d_%H%M%S) sqlite3 /data/fuel_stops.db ".backup /backups/fuel_stops_$$DATE.db" find /backups -name "fuel_stops_*.db" -mtime +30 -delete ' profiles: - backup ``` ### Restore Process ```bash # Stop application docker-compose down # Restore database ./scripts/docker/deploy.sh restore # Start application docker-compose up -d ``` ## Monitoring ### Health Checks ```bash # Check container health docker ps --filter "health=unhealthy" # Manual health check curl -f http://localhost:8080/ || echo "Health check failed" # Container logs docker logs tankstopp --tail 50 ``` ### Metrics Collection ```yaml # Prometheus monitoring services: prometheus: image: prom/prometheus ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml grafana: image: grafana/grafana ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin ``` ### Log Management ```bash # View logs docker-compose logs -f tankstopp # Filter logs docker-compose logs tankstopp | grep ERROR # Export logs docker-compose logs --no-color tankstopp > tankstopp.log ``` ## Troubleshooting ### Common Issues #### Container Won't Start ```bash # Check logs docker logs tankstopp # Check configuration docker run --rm tankstopp:latest cat /app/config.yaml # Test with minimal config docker run --rm -it tankstopp:latest sh ``` #### Database Issues ```bash # Check database file docker exec tankstopp ls -la /app/data/ # Test database connection docker exec tankstopp sqlite3 /app/data/fuel_stops.db ".tables" # Check permissions docker exec tankstopp id docker exec tankstopp ls -la /app/data/fuel_stops.db ``` #### Network Issues ```bash # Check port binding docker port tankstopp # Test network connectivity docker exec tankstopp wget -qO- http://localhost:8080/ # Check DNS resolution docker exec tankstopp nslookup overpass-api.de ``` ### Performance Issues ```bash # Check resource usage docker stats tankstopp # Monitor container processes docker exec tankstopp top # Check disk usage docker exec tankstopp df -h ``` ### Debug Mode ```bash # Run with debug enabled docker run -d --name tankstopp-debug \ -p 8080:8080 \ -e TANKSTOPP_APP_DEBUG=true \ -e TANKSTOPP_LOGGING_LEVEL=debug \ tankstopp:latest # Interactive debugging docker run --rm -it tankstopp:latest sh ``` ## Best Practices ### Image Management ```bash # Tag images properly docker build -t tankstopp:v1.0.0 . docker tag tankstopp:v1.0.0 tankstopp:latest # Use multi-stage builds (already implemented) # Keep images small # Use specific base image versions ``` ### Security ```bash # Scan images for vulnerabilities docker scout cves tankstopp:latest # Use secrets for sensitive data echo "mysecret" | docker secret create db_password - # Keep base images updated docker pull alpine:3.18 ``` ### Resource Management ```yaml # Set resource limits services: tankstopp: deploy: resources: limits: cpus: '1.0' memory: 512M reservations: cpus: '0.5' memory: 256M ``` ### Data Management ```bash # Regular backups # Monitor disk usage # Use proper volume drivers for production # Implement retention policies ``` ### Deployment ```bash # Use blue-green deployments # Implement health checks # Monitor application metrics # Use configuration management # Automate with CI/CD ``` ## Deployment Automation ### CI/CD Pipeline Example ```yaml # .github/workflows/docker.yml name: Docker Build and Deploy on: push: branches: [main] tags: ['v*'] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Build Docker image run: | ./scripts/docker/build.sh \ --tag tankstopp:${{ github.sha }} \ --tag tankstopp:latest - name: Push to registry run: | docker push tankstopp:${{ github.sha }} docker push tankstopp:latest deploy: needs: build runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - name: Deploy to production run: | ./scripts/docker/deploy.sh deploy \ --env production \ --tag ${{ github.sha }} ``` ### Production Checklist - [ ] SSL/TLS certificates configured - [ ] Reverse proxy setup (Nginx/Traefik) - [ ] Database backups automated - [ ] Monitoring and alerting in place - [ ] Log aggregation configured - [ ] Resource limits set - [ ] Health checks enabled - [ ] Security scanning implemented - [ ] Secrets management configured - [ ] Disaster recovery plan tested ## Support ### Getting Help 1. **Check logs**: `docker-compose logs tankstopp` 2. **Verify configuration**: Review environment variables 3. **Test connectivity**: Check network and DNS 4. **Resource monitoring**: Check CPU, memory, disk usage 5. **GitHub Issues**: Report bugs and feature requests ### Useful Commands ```bash # Complete deployment status ./scripts/docker/deploy.sh status # Application logs make docker-logs # Restart services docker-compose restart # Update to latest ./scripts/docker/deploy.sh update # Emergency rollback ./scripts/docker/deploy.sh rollback ``` For additional help, see the main [README.md](README.md) and [CONFIG_DOCUMENTATION.md](CONFIG_DOCUMENTATION.md).