Files
finger/DOCKER.md
T
2025-07-02 17:11:31 -07:00

7.9 KiB

Docker Setup and Deployment

This document describes how to build, run, and deploy the finger service using Docker and GitHub Actions.

Quick Start

  1. Clone the repository:

    git clone https://github.com/waffle2k/finger.git
    cd finger
    
  2. Start the service:

    docker compose up -d
    
  3. Test the service:

    # Test with the example user
    finger john@localhost
    
    # Or using telnet
    telnet localhost 79
    # Then type: john
    
  4. Add your own users:

    # Create a status file for a user
    echo "Your status message here" > users/yourusername
    
    # Test it
    finger yourusername@localhost
    

Using Docker directly

  1. Build the image:

    docker build -t finger-service .
    
  2. Run the container:

    docker run -d \
      --name finger \
      -p 79:79 \
      -v $(pwd)/users:/var/finger/users \
      finger-service
    

Using Pre-built Images

You can also use the automatically built images from GitHub Container Registry:

docker run -d \
  --name finger \
  -p 79:79 \
  -v $(pwd)/users:/var/finger/users \
  ghcr.io/waffle2k/finger:latest

Docker Architecture

Multi-stage Build

The Dockerfile uses a multi-stage build approach:

  1. Builder Stage (Ubuntu 24.04):

    • Installs all build dependencies (meson, ninja, boost, gtest, etc.)
    • Compiles the C++20 source code
    • Runs all tests to ensure quality
    • Creates a statically linked binary
  2. Runtime Stage (Alpine Linux):

    • Minimal base image (~5MB)
    • Only includes runtime dependencies
    • Runs as non-root user for security
    • Includes health checks

Security Features

  • Non-root execution: Runs as user finger (UID 1000)
  • Minimal attack surface: Alpine Linux base with minimal packages
  • Health checks: Built-in container health monitoring
  • Read-only filesystem: Application doesn't write to filesystem

Image Size

  • Final image: ~15MB (Alpine + binary + minimal runtime deps)
  • Build image: ~2GB (includes all build tools, discarded after build)

GitHub Actions CI/CD

Automated Workflow

The repository includes a comprehensive GitHub Actions workflow (.github/workflows/docker-publish.yml) that:

  1. Build and Test:

    • Builds the project with meson
    • Runs all unit tests
    • Uploads test results as artifacts
  2. Multi-platform Docker Build:

    • Builds for linux/amd64 and linux/arm64
    • Uses Docker Buildx for cross-platform support
    • Implements build caching for faster builds
  3. Container Registry Publishing:

    • Publishes to GitHub Container Registry (ghcr.io)
    • Tags with multiple strategies:
      • latest for main branch
      • v1.2.3 for semantic version tags
      • main-abc1234 for commit SHA
      • pr-123 for pull requests
  4. Security Scanning:

    • Runs Trivy vulnerability scanner
    • Uploads results to GitHub Security tab
    • Fails on high-severity vulnerabilities
  5. Supply Chain Security:

    • Generates SLSA build provenance attestations
    • Signs container images
    • Provides build transparency

Triggering Builds

The workflow triggers on:

  • Push to main branch: Builds and publishes latest tag
  • Version tags: Builds and publishes semantic version tags (v1.0.0)
  • Pull requests: Builds but doesn't publish (security)

Using Published Images

Images are available at: ghcr.io/waffle2k/finger

Available tags:

  • latest - Latest stable build from main branch
  • v1.0.0 - Specific version releases
  • main-abc1234 - Specific commit builds

Configuration

Environment Variables

The container supports these environment variables:

  • FINGER_PORT: Port to listen on (default: 79)
  • FINGER_DATA_DIR: Directory for user files (default: /var/finger/users)

Volume Mounts

  • /var/finger/users: Directory containing user status files
    • Mount your local users/ directory here
    • Each file represents a user (filename = username)
    • File contents = user's status message

Health Checks

The container includes built-in health checks:

  • Check: TCP connection to port 79
  • Interval: Every 30 seconds
  • Timeout: 10 seconds
  • Retries: 3 attempts
  • Start period: 40 seconds

Development

Local Development with Docker

  1. Build development image:

    docker build --target builder -t finger-dev .
    
  2. Run tests in container:

    docker run --rm finger-dev meson test -C builddir
    
  3. Interactive development:

    docker run -it --rm \
      -v $(pwd):/app \
      -w /app \
      finger-dev bash
    

Debugging

  1. View container logs:

    docker logs finger
    
  2. Execute into running container:

    docker exec -it finger sh
    
  3. Check health status:

    docker inspect finger | grep -A 10 Health
    

Production Deployment

Docker Swarm

version: '3.8'
services:
  finger:
    image: ghcr.io/waffle2k/finger:latest
    ports:
      - "79:79"
    volumes:
      - finger_data:/var/finger/users
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure
    healthcheck:
      test: ["CMD", "nc", "-z", "localhost", "79"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  finger_data:

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: finger-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: finger
  template:
    metadata:
      labels:
        app: finger
    spec:
      containers:
      - name: finger
        image: ghcr.io/waffle2k/finger:latest
        ports:
        - containerPort: 79
        volumeMounts:
        - name: user-data
          mountPath: /var/finger/users
        livenessProbe:
          tcpSocket:
            port: 79
          initialDelaySeconds: 30
          periodSeconds: 10
      volumes:
      - name: user-data
        configMap:
          name: finger-users
---
apiVersion: v1
kind: Service
metadata:
  name: finger-service
spec:
  selector:
    app: finger
  ports:
  - port: 79
    targetPort: 79
  type: LoadBalancer

Troubleshooting

Common Issues

  1. Permission denied on user files:

    # Fix file permissions
    chmod 644 users/*
    
  2. Port 79 requires root:

    # Use a different port
    docker run -p 8079:79 finger-service
    
  3. Container won't start:

    # Check logs
    docker logs finger
    
    # Check if port is available
    netstat -ln | grep :79
    
  4. Health check failing:

    # Test manually
    docker exec finger nc -z localhost 79
    
    # Check if service is running
    docker exec finger ps aux
    

Performance Tuning

  1. Resource limits:

    services:
      finger:
        deploy:
          resources:
            limits:
              memory: 64M
              cpus: '0.1'
    
  2. Connection limits:

    • The service handles concurrent connections efficiently
    • Default OS limits should be sufficient for most use cases
    • Monitor with docker stats for resource usage

Security Considerations

  1. Network Security:

    • Finger protocol sends data in plain text
    • Consider using behind a reverse proxy with TLS
    • Restrict access with firewall rules
  2. Data Security:

    • User files are readable by the finger user
    • Don't store sensitive information in status files
    • Consider file permissions on the host
  3. Container Security:

    • Runs as non-root user
    • Uses minimal base image
    • Regular security scanning in CI/CD
    • Keep images updated

Contributing

When contributing Docker-related changes:

  1. Test locally with docker build
  2. Ensure all tests pass in the container
  3. Update this documentation if needed
  4. The CI/CD pipeline will automatically test your changes

For more information, see the main README.md.