# Docker & Coolify Deployment Guide ## Overview Nerd Monitor is optimized for containerized deployment using Docker and Coolify CI/CD. This guide covers setup with Coolify, local development with Docker Compose, and deployment options. ## Quick Start with Coolify ### Prerequisites - Gitea repository configured - Coolify instance running - Docker/container runtime available ### Setup Steps 1. **Connect Repository to Coolify** - In Coolify, add new application - Select "Git Repository" - Choose your Gitea instance - Select `nerd-monitor` repository 2. **Configure Build Settings** - **Build Pack**: Dockerfile - **Dockerfile Path**: `./Dockerfile` - **Build Context**: `.` (root) - **Docker Image**: `nerd-monitor-server:latest` 3. **Set Environment Variables** In Coolify environment configuration: ``` ADDR=0.0.0.0 PORT=8080 USERNAME=admin PASSWORD=secure_password_here ``` 4. **Enable Auto-Deploy** - Set **Watch** to: `master` - Enable **Auto-deploy on push** - Coolify will automatically build and deploy on every push to master 5. **Configure Ports** - **Container Port**: 8080 - **Public Port**: 8080 (or as needed) - **Protocol**: HTTP/HTTPS 6. **Set Resource Limits** (optional) - CPU: 500m - 1000m - Memory: 256MB - 512MB ## Docker Files Included ### Dockerfile - **Purpose**: Multi-stage build for the server - **Base Image**: Alpine (lightweight) - **Final Size**: ~40MB - **User**: Non-root (nerdmonitor) - **Health Check**: Enabled ### Dockerfile.agent - **Purpose**: Container for agent deployment - **Use Case**: Running agents in containerized environments - **Base Image**: Alpine - **Size**: ~15MB ### docker-compose.yml - **Purpose**: Local development and testing - **Services**: Server + Demo Agent - **Network**: Bridged (isolated) - **Volume**: Logs persistence ### .dockerignore - **Purpose**: Optimize build context - **Excludes**: Git files, IDE configs, documentation - **Benefit**: Faster builds, smaller context ## Local Development ### Using Docker Compose Start the full stack locally: ```bash # Build and start all services docker-compose up -d # View logs docker-compose logs -f server # Stop all services docker-compose down # Remove volumes (clean slate) docker-compose down -v ``` Access dashboard: - URL: http://localhost:8080 - Username: admin - Password: admin ### Manual Docker Commands Build server image: ```bash docker build -t nerd-monitor-server:latest -f Dockerfile . ``` Run server container: ```bash docker run -d \ --name nerd-monitor-server \ -p 8080:8080 \ -e USERNAME=admin \ -e PASSWORD=admin \ nerd-monitor-server:latest ``` Build agent image: ```bash docker build -t nerd-monitor-agent:latest -f Dockerfile.agent . ``` Run agent container: ```bash docker run -d \ --name nerd-monitor-agent \ -e SERVER=server-ip:8080 \ nerd-monitor-agent:latest ``` ## Coolify Deployment Flow ``` ┌─────────────────┐ │ Push to master │ │ (Git commit) │ └────────┬────────┘ │ ▼ ┌─────────────────────┐ │ Gitea Webhook │ │ notifies Coolify │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Coolify receives │ │ build trigger │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Coolify clones │ │ repository │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Docker build │ │ executes Dockerfile│ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Multi-stage build: │ │ 1. Build binaries │ │ 2. Create runtime │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Image pushed to │ │ registry (local) │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Coolify stops old │ │ container │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Coolify starts new │ │ container │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ Health check │ │ verifies service │ └────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ ✅ Deployment │ │ Complete │ └─────────────────────┘ ``` ## Image Specifications ### Server Image - **Name**: nerd-monitor-server - **Tag**: latest (or version-based) - **Size**: ~40MB - **Base**: alpine:latest - **User**: nerdmonitor (uid: 1000) - **Port**: 8080 - **Health Check**: Yes (30s interval) ### Agent Image - **Name**: nerd-monitor-agent - **Tag**: latest - **Size**: ~15MB - **Base**: alpine:latest - **User**: nerdmonitor (uid: 1000) - **Stateless**: Yes (no persistent storage) ## Environment Variables ### Server ``` ADDR=0.0.0.0 # Server bind address PORT=8080 # Server port USERNAME=admin # Admin username PASSWORD=admin # Admin password (change!) ``` ### Agent ``` SERVER=localhost:8080 # Server address:port INTERVAL=15s # Reporting interval ``` ## Build Optimization The Dockerfile uses several optimization techniques: 1. **Multi-stage Build** - Builder stage: Includes compiler toolchain - Runtime stage: Only includes runtime dependencies - Result: Minimal final image size 2. **Alpine Linux** - Lightweight base image (5-10MB) - Includes essentials only - Fast pull and startup 3. **Binary Optimization** - `-w -s` flags strip debug symbols - Reduces binary size by ~30% - No runtime impact 4. **Non-root User** - Improved security - Prevents privilege escalation - Best practice for containers 5. **Health Checks** - Automatic service monitoring - Coolify/Kubernetes aware - Allows orchestration decisions ## Production Checklist - [ ] Change USERNAME and PASSWORD in Coolify - [ ] Enable HTTPS/SSL certificate - [ ] Configure resource limits (CPU/Memory) - [ ] Set up logging aggregation - [ ] Configure backup strategy (if needed) - [ ] Enable monitoring/alerts - [ ] Test rollback procedure - [ ] Document deployment process - [ ] Set up redundancy if needed ## Troubleshooting ### Build Fails - Check Dockerfile syntax - Verify build context includes all files - Review build logs in Coolify - Ensure .dockerignore isn't excluding source files ### Container Won't Start - Check environment variables are set - Verify port isn't already in use - Check Docker logs: `docker logs container-name` - Verify health check endpoint is accessible ### Deployment Shows Unhealthy - Check network connectivity - Verify PORT environment variable matches exposed port - Review health check command - Check application logs ### Image Size Too Large - Remove unnecessary files from .dockerignore - Use `docker image inspect` to analyze layers - Consider multi-stage build optimization ## Performance Tips 1. **Caching** - Copy go.mod/go.sum first (cached layer) - Copy source code second - Docker reuses layers if unchanged 2. **Build Speed** - Use `docker buildx` for faster builds - Enable BuildKit: `DOCKER_BUILDKIT=1` - Parallelize stages if possible 3. **Runtime Performance** - Alpine is lightweight but bare-bones - Add tools only as needed - Monitor resource usage ## Advanced Configuration ### Private Container Registry If using private Docker registry: ```bash # In Coolify, set registry credentials docker login private-registry.example.com # In docker-compose, use: image: private-registry.example.com/nerd-monitor-server:latest ``` ### Multi-architecture Builds Build for multiple architectures: ```bash docker buildx build \ --platform linux/amd64,linux/arm64 \ -t nerd-monitor-server:latest \ -f Dockerfile . ``` ### Custom Base Images Modify Dockerfile FROM directive: ```dockerfile # Use different base image if needed FROM golang:1.23-bookworm # Debian-based FROM golang:1.23-bullseye # Another option ``` ## Support & Documentation - Review Dockerfile comments for details - Check Coolify documentation for advanced features - See README.md for general project info - Review AGENTS.md for development guidelines ## Next Steps 1. Commit Docker files: `git add Dockerfile*` 2. Push to master: `git push origin master` 3. Coolify will automatically detect and build 4. Monitor build progress in Coolify UI 5. Access deployed application once ready