A containerized documentation server that automatically builds and serves MkDocs documentation from any Git repository. Originally designed for llajas/homelab, but configurable for any repository.
The llajas/homelab repository includes documentation that requires:
- Cloning the repository locally
- Installing Python dependencies (
mkdocs-material
) - Running
make docs
to serve on port8000
This container simplifies and automates that entire process:
- β Zero Setup: No local dependencies required
- β Auto-Updates: Watches for repository changes every 2 minutes
- β Production Ready: Includes health checks, logging, and security hardening
- β Flexible Deployment: Docker Compose, Kubernetes, or standalone Docker
This is a single-container solution based on nginx:alpine
that:
- Clones the specified Git repository
- Builds documentation using
mkdocs-material
- Serves via nginx on port 80
- Monitors for updates every 2 minutes (configurable)
- Rebuilds automatically when changes are detected
- π Continuous Updates: Automatically pulls and rebuilds on repository changes
- π Security Hardened: Runs as non-root user (UID 1001) with minimal privileges
- π Health Monitoring: Built-in health checks and structured logging
- ποΈ Highly Configurable: Repository URL and update interval via environment variables
- π Complete Logging: Application logs + nginx access logs with visitor IPs
- π Multiple Deployment Options: Docker Compose, Kubernetes Helm chart, or standalone
- β‘ Production Ready: Resource limits, anti-affinity, and autoscaling support
- π Cloudflare Integration: Helm chart optimized for Cloudflared tunnels
# Clone this repository
git clone <this-repo-url>
cd homelab-docs
# Run with default settings (llajas/homelab repo)
make run
# Or run in development mode (with logs)
make dev
# Stop when done
make stop
# Copy environment template
cp .env.example .env
# Edit .env to set your repository
vim .env # Set REPO_URL=https://github.com/yourusername/your-docs-repo
# Run with your custom repository
docker-compose up -d
# Install to Kubernetes cluster
make helm-install
# Upgrade existing deployment
make helm-upgrade
# Uninstall
make helm-uninstall
# Build and run directly
docker build -t homelab-docs --build-arg REPO_URL=https://github.com/yourusername/your-repo .
docker run -d -p 5000:80 homelab-docs
Variable | Default | Description |
---|---|---|
REPO_URL |
https://github.com/llajas/homelab |
Git repository to build docs from |
UPDATE_INTERVAL |
120 |
How often to check for updates (seconds) |
Variable | Default | Description |
---|---|---|
REGISTRY |
registry.lajas.tech |
Docker registry for pushing images |
REPO |
homelab-documenatation |
Repository name in registry |
REPO_URL |
https://github.com/llajas/homelab |
Git repository URL |
# Method 1: Environment variable
export REPO_URL=https://github.com/yourusername/your-docs-repo
make build
# Method 2: .env file
cp .env.example .env
# Edit .env with your settings
docker-compose up
# Method 3: Build argument
docker build --build-arg REPO_URL=https://github.com/yourusername/your-repo .
make run # Start in background
make dev # Start with logs visible
make stop # Stop and remove containers
make build # Build container image
make push # Push to registry
make all # Build and push
make helm-install # Install Helm chart
make helm-upgrade # Upgrade existing deployment
make helm-uninstall # Remove from cluster
make helm-template # Preview generated YAML
The included Helm chart provides production-ready Kubernetes deployment with:
- π Multiple Replicas: Run 2+ instances for high availability (default: 2)
- π Ingress Support: Easy setup for external access (perfect for Cloudflared)
- π Horizontal Pod Autoscaling: Automatically scale based on CPU usage (2-10 replicas)
- π― Pod Anti-Affinity: Spread replicas across different nodes for resilience
- π‘οΈ Security Hardened: Non-root execution (UID 1001) with dropped capabilities
- β€οΈ Health Checks: Kubernetes-native liveness and readiness probes
- π Resource Management: CPU/memory requests and limits configured
- π Rolling Updates: Zero-downtime deployments with configurable strategy
# Key configuration options
replicaCount: 2
config:
repoUrl: "https://github.com/llajas/homelab"
updateInterval: 120
# Resource limits
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
# High availability
affinity:
podAntiAffinity: enabled # Spreads pods across nodes
# Autoscaling (disabled by default)
autoscaling:
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# Deploy with custom repository
helm install homelab-docs ./helm/homelab-docs \
--set config.repoUrl=https://github.com/yourusername/your-docs \
--set replicaCount=3
# Enable ingress for external access via Cloudflared
helm upgrade homelab-docs ./helm/homelab-docs \
--set ingress.enabled=true \
--set ingress.hosts[0].host=docs.yourdomain.com \
--set ingress.annotations."external-dns\.alpha\.kubernetes\.io/target"=your-tunnel.example.com
# Enable autoscaling for traffic spikes
helm upgrade homelab-docs ./helm/homelab-docs \
--set autoscaling.enabled=true \
--set autoscaling.maxReplicas=5
# Production deployment with custom settings
helm install homelab-docs ./helm/homelab-docs \
--set config.repoUrl=https://github.com/company/docs \
--set config.updateInterval=300 \
--set replicaCount=3 \
--set resources.requests.memory=256Mi \
--set ingress.enabled=true
# Docker Compose
docker-compose logs -f
# Kubernetes
kubectl logs -f deployment/homelab-docs
The container produces two types of logs:
Application Logs (build/deployment activities):
[2025-07-06 10:30:15] Starting build process...
[2025-07-06 10:30:20] Build and deploy completed successfully
[2025-07-06 10:32:15] Updates detected, rebuilding...
Nginx Access Logs (visitor requests):
192.168.1.100 - - [06/Jul/2025:10:31:45 +0000] "GET / HTTP/1.1" 200 1234
192.168.1.101 - - [06/Jul/2025:10:32:12 +0000] "GET /docs/ HTTP/1.1" 200 5678
Build Fails: Check that your repository has a valid mkdocs.yml
file
# Check container logs
docker-compose logs homelab-docs
# Test build manually
docker exec -it homelab-docs_homelab-docs_1 /bin/sh
cd /tmp/repo && mkdocs build
Updates Not Detected: Verify the repository branch
# The container checks the 'master' branch by default
# If your repo uses 'main', you'll need to modify the entrypoint script
# Future versions will auto-detect the default branch
Permission Issues: The container runs as user 1001
# Ensure your repository is publicly accessible
# For private repos, you'll need to add SSH keys or tokens
Helm Template Errors: Validate your chart
# Test template rendering
make helm-template
# Debug with verbose output
helm template homelab-docs ./helm/homelab-docs --debug
Resource Limits: Adjust if builds fail due to memory/CPU constraints
# Increase resources in values.yaml or via --set
helm upgrade homelab-docs ./helm/homelab-docs \
--set resources.limits.memory=1Gi \
--set resources.limits.cpu=1000m
While GitHub Pages is excellent, this self-hosted approach provides:
- π Full Control: Host anywhere (homelab, VPS, cloud)
- π Real-time Updates: No GitHub Actions delay
- ποΈ Customization: Modify the build process as needed
- π Learning: Hands-on experience with containerization and Kubernetes
- π Independence: Not tied to GitHub's infrastructure
- Fork this repository
- Make your changes
- Test with your own documentation repository
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.