Skip to content

fabricesemti80/project-dockerlab

Repository files navigation

Project DockerLab

A comprehensive on-premises homelab running Docker Swarm on Proxmox VE.

πŸ—οΈ Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Proxmox VE On-Premises                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚  Managers:                                                              β”‚
β”‚       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚       β”‚   dkr-srv-1   β”‚    β”‚   dkr-srv-2   β”‚    β”‚   dkr-srv-3   β”‚      β”‚
β”‚       β”‚   (Manager)   │◄──►│   (Manager)   │◄──►│   (Manager)   β”‚      β”‚
β”‚       β”‚  10.0.30.21   β”‚    β”‚  10.0.30.22   β”‚    β”‚  10.0.30.23   β”‚      β”‚
β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚                                                                         β”‚
β”‚  Workers:                                                               β”‚
β”‚       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚       β”‚  dkr-wrkr-1   β”‚    β”‚  dkr-wrkr-2   β”‚    β”‚  dkr-wrkr-3   β”‚      β”‚
β”‚       β”‚   (Worker)    β”‚    β”‚   (Worker)    β”‚    β”‚   (Worker)    β”‚      β”‚
β”‚       β”‚  10.0.30.31   β”‚    β”‚  10.0.30.32   β”‚    β”‚  10.0.30.33   β”‚      β”‚
β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚                                                                         β”‚
β”‚                         Docker Swarm Cluster                            β”‚
β”‚                        (3 Managers + 3 Workers)                         β”‚
β”‚                                                                         β”‚
β”‚       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚       β”‚                    Shared Storage                        β”‚      β”‚
β”‚       β”‚                  CephFS (/mnt/cephfs)                   β”‚      β”‚
β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Component Technology
Virtualization Proxmox VE
Container Orchestration Docker Swarm
Shared Storage CephFS
Configuration Management Ansible
Infrastructure as Code Terraform
Secrets Management Doppler
Task Runner Taskfile
DNS Management Cloudflare
Reverse Proxy Traefik

πŸ“ Project Structure

project-dockerlab/
β”œβ”€β”€ ansible/                  # Configuration management
β”‚   β”œβ”€β”€ group_vars/          # Variable definitions
β”‚   β”œβ”€β”€ inventory/           # Host inventory
β”‚   β”œβ”€β”€ roles/               # Ansible roles
β”‚   β”‚   β”œβ”€β”€ fresh_install/   # Base OS config, users, SSH, packages
β”‚   β”‚   β”œβ”€β”€ docker_swarm/    # Docker Swarm initialization
β”‚   β”‚   β”œβ”€β”€ portainer/       # Portainer deployment
β”‚   β”‚   β”œβ”€β”€ geerlingguy.docker/  # External role: Docker installation
β”‚   β”‚   └── geerlingguy.pip/     # External role: pip/Python dependencies
β”‚   └── *.yml                # Playbooks
β”œβ”€β”€ terraform_infra/         # Core infrastructure (Proxmox, Hetzner, networks)
β”œβ”€β”€ terraform_apps/          # App-level IaC (DNS, Portainer stacks)
β”œβ”€β”€ docker/                  # Swarm stacks and app configs
β”‚   β”œβ”€β”€ traefik/             # Traefik reverse proxy stack
β”‚   β”œβ”€β”€ socket-proxy/        # Docker socket proxy stack
β”‚   β”œβ”€β”€ homepage/            # Homepage dashboard stack
β”‚   β”œβ”€β”€ beszel/              # Beszel monitoring stack
β”‚   β”œβ”€β”€ backup/              # Restic backup stack
β”‚   β”œβ”€β”€ cloudflared/         # Cloudflare tunnel stack
β”‚   └── ...                  # Other stacks
β”œβ”€β”€ docs/                    # Detailed documentation
β”‚   β”œβ”€β”€ ansible.md           # Ansible documentation
β”‚   β”œβ”€β”€ terraform.md         # Terraform documentation
β”‚   β”œβ”€β”€ doppler.md           # Doppler documentation
β”‚   └── taskfile.md          # Taskfile documentation
β”œβ”€β”€ archive/                 # Deprecated/backup files
β”œβ”€β”€ taskfile/                # Task definitions
└── Taskfile.yml             # Main task runner config

πŸš€ Quick Start

Prerequisites

  • Doppler CLI - Secrets management
  • Task - Task runner
  • Terraform - Infrastructure provisioning
  • Ansible - Configuration management
  • SSH access to Proxmox and target nodes

1. Configure Secrets

# Login to Doppler
doppler login

# Setup project
doppler setup
# Select: project-dockerlab / dev

2. Initialize Dependencies

# Initialize Terraform
task tf:init

# Install Ansible dependencies
task ansible:init

3. Deploy Infrastructure

# Preview infrastructure changes
task tf:plan

# Apply infrastructure
task tf:apply

4. Configure Systems

# Preview configuration changes
task ansible:site:plan

# Apply full configuration
task ansible:site:apply

5. Deploy Applications

# Deploy app stacks via Terraform (Portainer)
task tfa:apply

# Or deploy individual stacks manually
cd docker/traefik
docker stack deploy -c traefik-stack.yml traefik

πŸ“‹ Infrastructure

Nodes

Node IP Address Role Purpose
dkr-srv-1 10.0.30.21 Manager Swarm management, core services
dkr-srv-2 10.0.30.22 Manager Swarm management, core services
dkr-srv-3 10.0.30.23 Manager Swarm management, core services
dkr-wrkr-1 10.0.30.31 Worker Application workloads
dkr-wrkr-2 10.0.30.32 Worker Application workloads
dkr-wrkr-3 10.0.30.33 Worker Application workloads

Network Configuration

  • VLAN 30: Docker/Container network (10.0.30.0/24)
  • VLAN 40: Proxmox management (10.0.40.0/24)

πŸ”§ Common Tasks

# List all available tasks
task --list-all

# Terraform
task tf:plan            # Preview infrastructure changes
task tf:apply           # Apply infrastructure
task tf:destroy         # Destroy all infrastructure

# Ansible
task ansible:site:apply       # Full site deployment
task ansible:preflight:apply  # System updates
task ansible:docker:apply     # Docker installation only
task ansible:tailscale:apply  # Tailscale setup only

πŸ“š Documentation

Detailed documentation for each component:

Document Description
Ansible Playbooks, roles, and configuration
Terraform Infrastructure provisioning
Doppler Secrets management
Taskfile Task runner commands
Cloudflare Tunnel Setup Secure remote access without opening external ports
Dockpeek Setup Simple Docker container explorer
Glance Setup Self-hosted dashboard
Monitoring Setup Docker Swarm monitoring solution
Traefik Setup Traefik Ingress Controller

πŸ–ΌοΈ Base Image Creation

Creating a Debian 13 VM Template

  1. Access Proxmox Community Scripts

  2. Run the Script

    • Open Proxmox Shell
    • Copy and execute the community script
  3. Convert to Template

    • Right-click VM β†’ "Convert to Template"
    • Template ID: 9008 (used in Terraform)
  4. Template Naming

    • Recommended: debian13-docker-template

πŸ” Secrets Management

All secrets are managed through Doppler. See Doppler Documentation for setup details.

🐳 Applications

Swarm stacks are in the docker/ directory:

whoami

A simple Traefik whoami service for testing Swarm deployments:

cd docker/traefik
docker stack deploy -c whoami-stack.yml whoami

Cloudflare Tunnel

Secure remote access without opening external ports. See Cloudflare Tunnel Setup for details.

Dockpeek

A simple Docker container explorer. See Dockpeek Setup for details.

Glance

A self-hosted dashboard that puts all your feeds in one place. See Glance Setup for details.

Monitoring (Prometheus & Grafana)

A complete monitoring solution for Docker Swarm. See Monitoring Setup for details.

Traefik

Traefik Ingress Controller. See Traefik Setup for details.

Ghost

Ghost is a powerful open-source blogging and publishing platform. See Ghost Setup for details.

Backup

Automated backup solution using Restic with support for Backblaze B2, AWS S3, or SFTP storage. See Backup Setup for details.

Features:

  • Pre-backup database dumps (MySQL, Postgres)
  • Incremental, deduplicated, encrypted backups
  • Automatic retention (7 daily, 4 weekly, 3 monthly)
  • Discord notifications

OtterWiki

A minimal, self-hosted wiki with Markdown and Git version control.

Required Doppler Secrets: None (first registered user becomes admin)

Linkwarden

A collaborative bookmark manager that preserves webpages. Deployed on worker nodes.

URL: https://links.yourdomain.com

Required Doppler Secrets:

Secret Description
LINKWARDEN_POSTGRES_PASSWORD PostgreSQL password for database
LINKWARDEN_NEXTAUTH_SECRET Secret for session encryption (generate with openssl rand -base64 32)
LINKWARDEN_MEILI_KEY Meilisearch master key for search (generate with openssl rand -base64 32)

Jellyfin

Open-source media server. Deployed on worker nodes with access to shared media library.

URL: https://jelly.yourdomain.com

Required Doppler Secrets: None (first user becomes admin)

Plex (QNAP Secondary Environment)

Media server running on QNAP NAS, routed through Traefik on the primary swarm.

Required Doppler Secrets:

Secret Description
PLEX_CLAIM Claim token from https://plex.tv/claim (expires in 4 minutes)

Grafana Alloy

Metrics and logs collector for Grafana Cloud. Runs globally on all swarm nodes.

Required Doppler Secrets:

Secret Description Where to find
GRAFANA_CLOUD_PROMETHEUS_URL Remote write URL (e.g., https://prometheus-prod-xx-xxx.grafana.net/api/prom/push) Grafana Cloud β†’ Connections β†’ Hosted Prometheus β†’ Details
GRAFANA_CLOUD_PROMETHEUS_USERNAME Numeric username/ID Same page as above
GRAFANA_CLOUD_LOKI_URL Loki push URL (e.g., https://logs-prod-xxx.grafana.net/loki/api/v1/push) Grafana Cloud β†’ Connections β†’ Hosted Logs β†’ Details
GRAFANA_CLOUD_LOKI_USERNAME Numeric username/ID Same page as above
GRAFANA_CLOUD_API_KEY API key with MetricsPublisher and LogsPublisher permissions Grafana Cloud β†’ Administration β†’ API Keys β†’ Add API Key

How to get Grafana Cloud credentials:

  1. Go to grafana.com β†’ Sign in
  2. Navigate to My Account β†’ Your Grafana Cloud stack
  3. Click Connections β†’ Hosted Prometheus β†’ Copy the Remote Write URL and Username
  4. Click Connections β†’ Hosted Logs β†’ Copy the Push URL and Username
  5. Go to Administration β†’ API Keys β†’ Add API Key
    • Name: alloy-homelab
    • Role: MetricsPublisher (create another for LogsPublisher or use Admin)
  6. Add all values to Doppler

πŸ” Required Doppler Secrets

Secret Purpose
PROXMOX_AUTH_TOKEN Proxmox VE API
CLOUDFLARE_API_TOKEN Cloudflare DNS
GHOST_DB_PASSWORD MySQL password for Ghost database user
GHOST_DB_ROOT_PASSWORD MySQL root password for Ghost database
GHOST_MAIL_TRANSPORT Mail transport (e.g., SMTP) - optional
GHOST_MAIL_HOST SMTP host - optional
GHOST_MAIL_PORT SMTP port - optional
GHOST_MAIL_USER SMTP username - optional
GHOST_MAIL_PASSWORD SMTP password - optional
GHOST_MAIL_FROM From address for emails - optional
PLEX_CLAIM Plex claim token (get from https://plex.tv/claim)
GRAFANA_CLOUD_PROMETHEUS_URL Grafana Cloud Prometheus remote write URL
GRAFANA_CLOUD_PROMETHEUS_USERNAME Grafana Cloud Prometheus username
GRAFANA_CLOUD_LOKI_URL Grafana Cloud Loki push URL
GRAFANA_CLOUD_LOKI_USERNAME Grafana Cloud Loki username
GRAFANA_CLOUD_API_KEY Grafana Cloud API key
BESZEL_AGENT_KEY Beszel agent key (get from Beszel hub UI)
LINKWARDEN_POSTGRES_PASSWORD PostgreSQL password for Linkwarden
LINKWARDEN_NEXTAUTH_SECRET NextAuth session secret for Linkwarden
LINKWARDEN_MEILI_KEY Meilisearch master key for Linkwarden

πŸ”„ Deployment Workflow

graph LR
    A[Terraform] -->|Provision VMs| B[Ansible Preflight]
    B -->|System Updates| C[Base Config]
    C -->|Hostname, Packages| D[Tailscale]
    D -->|Mesh Network| E[Docker]
    E -->|Install Docker| F[Swarm]
    F -->|Form Cluster| G[Deploy Apps]
Loading

πŸš€ Bonus: Automated Deployment Pipeline

For those who want to loosely couple the deployment stages without a full CI/CD server, we've added automated pipeline options:

  • One-command deployment: task deploy runs the full Terraform β†’ Ansible β†’ Terraform pipeline sequentially
  • Enhanced scripting: ./scripts/deploy.sh provides detailed logging and error handling
  • Event-driven options: Webhook receiver for external triggering

See Deployment Pipeline Plan for detailed implementation options and comparisons.

πŸ› οΈ Troubleshooting

SSH Connection Issues

# Test connectivity
ansible -i ansible/inventory/hosts all -m ping

Tailscale Issues

# Check Tailscale status on a node
tailscale status
tailscale ip -4

Docker Swarm Issues

# Check swarm status
docker node ls
docker service ls

πŸ“ License

This project is for personal homelab use.

πŸ™ Acknowledgments

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •