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
Using Docker Compose (Recommended)
-
Clone the repository:
git clone https://github.com/waffle2k/finger.git cd finger -
Start the service:
docker compose up -d -
Test the service:
# Test with the example user finger john@localhost # Or using telnet telnet localhost 79 # Then type: john -
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
-
Build the image:
docker build -t finger-service . -
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:
-
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
-
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:
-
Build and Test:
- Builds the project with meson
- Runs all unit tests
- Uploads test results as artifacts
-
Multi-platform Docker Build:
- Builds for
linux/amd64andlinux/arm64 - Uses Docker Buildx for cross-platform support
- Implements build caching for faster builds
- Builds for
-
Container Registry Publishing:
- Publishes to GitHub Container Registry (
ghcr.io) - Tags with multiple strategies:
latestfor main branchv1.2.3for semantic version tagsmain-abc1234for commit SHApr-123for pull requests
- Publishes to GitHub Container Registry (
-
Security Scanning:
- Runs Trivy vulnerability scanner
- Uploads results to GitHub Security tab
- Fails on high-severity vulnerabilities
-
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
latesttag - 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 branchv1.0.0- Specific version releasesmain-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
- Mount your local
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
-
Build development image:
docker build --target builder -t finger-dev . -
Run tests in container:
docker run --rm finger-dev meson test -C builddir -
Interactive development:
docker run -it --rm \ -v $(pwd):/app \ -w /app \ finger-dev bash
Debugging
-
View container logs:
docker logs finger -
Execute into running container:
docker exec -it finger sh -
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
-
Permission denied on user files:
# Fix file permissions chmod 644 users/* -
Port 79 requires root:
# Use a different port docker run -p 8079:79 finger-service -
Container won't start:
# Check logs docker logs finger # Check if port is available netstat -ln | grep :79 -
Health check failing:
# Test manually docker exec finger nc -z localhost 79 # Check if service is running docker exec finger ps aux
Performance Tuning
-
Resource limits:
services: finger: deploy: resources: limits: memory: 64M cpus: '0.1' -
Connection limits:
- The service handles concurrent connections efficiently
- Default OS limits should be sufficient for most use cases
- Monitor with
docker statsfor resource usage
Security Considerations
-
Network Security:
- Finger protocol sends data in plain text
- Consider using behind a reverse proxy with TLS
- Restrict access with firewall rules
-
Data Security:
- User files are readable by the finger user
- Don't store sensitive information in status files
- Consider file permissions on the host
-
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:
- Test locally with
docker build - Ensure all tests pass in the container
- Update this documentation if needed
- The CI/CD pipeline will automatically test your changes
For more information, see the main README.md.