From c8548570ca91319aef02f8deff74afa7d0695aa1 Mon Sep 17 00:00:00 2001 From: Ducky SSH User Date: Sat, 20 Dec 2025 05:05:36 +0000 Subject: [PATCH] Coolify CI/CD testing --- .coolify | 59 ++++++++ .dockerignore | 54 +++++++ DOCKER.md | 365 +++++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 60 ++++++++ Dockerfile.agent | 49 ++++++ docker-compose.yml | 57 +++++++ 6 files changed, 644 insertions(+) create mode 100644 .coolify create mode 100644 .dockerignore create mode 100644 DOCKER.md create mode 100644 Dockerfile create mode 100644 Dockerfile.agent create mode 100644 docker-compose.yml diff --git a/.coolify b/.coolify new file mode 100644 index 0000000..3e39cf9 --- /dev/null +++ b/.coolify @@ -0,0 +1,59 @@ +# Nerd Monitor - Coolify Configuration +# This file documents the Coolify setup for Nerd Monitor + +# Build Pack: Dockerfile (Custom) +# The project includes a Dockerfile optimized for Coolify + +# Build Configuration: +# - Base Image: golang:1.23-alpine (builder), alpine:latest (runtime) +# - Build Context: . (repository root) +# - Dockerfile: ./Dockerfile + +# Ports +# - Internal: 8080 +# - External: 8080 (configurable in Coolify UI) + +# Environment Variables (set in Coolify): +# ADDR=0.0.0.0 +# PORT=8080 +# USERNAME=admin (change in production) +# PASSWORD=admin (change in production) + +# Health Check: Enabled +# - Endpoint: http://localhost:8080/login +# - Interval: 30s +# - Timeout: 3s +# - Retries: 3 +# - Start Period: 5s + +# Auto-Deploy on Push: +# 1. Connect repository to Coolify (Gitea) +# 2. Set branch to: master +# 3. Enable auto-deploy on push +# 4. Coolify will automatically build on every push to master + +# Build Optimization: +# - Multi-stage build reduces final image size +# - Alpine-based for minimal footprint (~40MB final image) +# - Non-root user for security +# - Strip binaries (-w -s flags) to reduce size + +# CI/CD Pipeline Flow: +# Push to master → Gitea webhook → Coolify detects +# → Coolify builds Dockerfile → New image created +# → Coolify deploys container → Service available + +# Related Files: +# - Dockerfile: Server container definition +# - Dockerfile.agent: Agent container definition +# - docker-compose.yml: Local development setup +# - .dockerignore: Files excluded from Docker build context + +# For local testing before pushing: +# docker-compose up -d + +# For production deployment via Coolify: +# 1. Set USERNAME and PASSWORD in Coolify environment variables +# 2. Configure domain/SSL if needed +# 3. Set resource limits (CPU, Memory) +# 4. Configure auto-scaling if needed diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..97fdb62 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,54 @@ +# Git +.git +.gitignore +.gitmodules + +# Build artifacts +bin/ +dist/ +*.exe +*.dll +*.so +*.dylib + +# Generated code +views/*_templ.go + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store +*.iml + +# Go +vendor/ +.env +.env.local +*.test + +# OS +Thumbs.db +.DS_Store +*.log + +# Docker +Dockerfile +docker-compose.yml +.dockerignore + +# CI/CD +.github/ +.gitlab-ci.yml +.circleci/ + +# Node (if added in future) +node_modules/ +package-lock.json +yarn.lock + +# Documentation +*.md +CHANGELOG diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..71beb63 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,365 @@ +# 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 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..292475a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +# Multi-stage Dockerfile for Nerd Monitor +# Optimized for Coolify CI/CD pipeline +# Build stage +FROM golang:1.23-alpine AS builder + +WORKDIR /app + +# Install build dependencies +RUN apk add --no-cache git make + +# Copy go mod files +COPY go.mod go.sum ./ + +# Download dependencies +RUN go mod download + +# Copy source code +COPY . . + +# Generate Templ templates +RUN go run github.com/a-h/templ/cmd/templ@latest generate + +# Build the server +RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-server ./cmd/server + +# Runtime stage +FROM alpine:latest + +WORKDIR /app + +# Install runtime dependencies +RUN apk add --no-cache ca-certificates tzdata + +# Copy binary from builder +COPY --from=builder /app/bin/nerd-monitor-server /app/nerd-monitor-server + +# Create non-root user for security +RUN addgroup -g 1000 nerdmonitor && adduser -D -u 1000 -G nerdmonitor nerdmonitor + +# Change ownership +RUN chown -R nerdmonitor:nerdmonitor /app + +# Switch to non-root user +USER nerdmonitor + +# Expose port +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8080/login || exit 1 + +# Default environment variables +ENV ADDR=0.0.0.0 +ENV PORT=8080 +ENV USERNAME=admin +ENV PASSWORD=admin + +# Run the application +CMD ["/app/nerd-monitor-server", "-addr", "0.0.0.0", "-port", "8080", "-username", "admin", "-password", "admin"] diff --git a/Dockerfile.agent b/Dockerfile.agent new file mode 100644 index 0000000..e92530a --- /dev/null +++ b/Dockerfile.agent @@ -0,0 +1,49 @@ +# Dockerfile for Nerd Monitor Agent +# Multi-stage build optimized for minimal size + +FROM golang:1.23-alpine AS builder + +WORKDIR /app + +# Install build dependencies +RUN apk add --no-cache git make + +# Copy go mod files +COPY go.mod go.sum ./ + +# Download dependencies +RUN go mod download + +# Copy source code +COPY . . + +# Build the agent +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o bin/nerd-monitor-agent ./cmd/agent + +# Runtime stage +FROM alpine:latest + +WORKDIR /app + +# Install runtime dependencies (minimal) +RUN apk add --no-cache ca-certificates tzdata + +# Copy binary from builder +COPY --from=builder /app/bin/nerd-monitor-agent /app/nerd-monitor-agent + +# Create non-root user for security +RUN addgroup -g 1000 nerdmonitor && adduser -D -u 1000 -G nerdmonitor nerdmonitor + +# Change ownership +RUN chown -R nerdmonitor:nerdmonitor /app + +# Switch to non-root user +USER nerdmonitor + +# Default environment variables +ENV SERVER=localhost:8080 +ENV INTERVAL=15s + +# Run the agent +ENTRYPOINT ["/app/nerd-monitor-agent"] +CMD ["--server", "${SERVER}", "--interval", "${INTERVAL}"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..56c9612 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,57 @@ +version: '3.8' + +services: + # Nerd Monitor Server + server: + build: + context: . + dockerfile: Dockerfile + container_name: nerd-monitor-server + ports: + - "8080:8080" + environment: + ADDR: 0.0.0.0 + PORT: 8080 + USERNAME: admin + PASSWORD: admin + volumes: + - server-logs:/app/logs + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/login"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 5s + networks: + - nerd-monitor-net + labels: + - "com.example.description=Nerd Monitor Server" + + # Example Agent 1 (Alpine-based, simulated) + # In production, agents run on monitored machines + # This is for testing/demo purposes only + agent-demo: + build: + context: . + dockerfile: Dockerfile.agent + container_name: nerd-monitor-agent-demo + environment: + SERVER: http://server:8080 + INTERVAL: 15s + depends_on: + server: + condition: service_healthy + restart: unless-stopped + networks: + - nerd-monitor-net + labels: + - "com.example.description=Nerd Monitor Agent (Demo)" + +volumes: + server-logs: + driver: local + +networks: + nerd-monitor-net: + driver: bridge