bb50bd75afb961caf252db4aa54cd477361831ce
Homelab Setup (Vaultwarden + 2FAuth + Caddy + DuckDNS)
This repository contains the configuration for my personal homelab stack, including:
- Vaultwarden – self-hosted password manager (Bitwarden-compatible)
- 2FAuth – self-hosted two-factor authentication manager
- Caddy – reverse proxy with automatic HTTPS via DuckDNS (DNS-01)
- DuckDNS Updater – updates my dynamic IP address automatically
The setup is built with Docker Compose and is designed to be simple, secure, and easy to maintain.
Directory Structure
.
├── duckdns
│ ├── duck.log # Log file for DuckDNS updates
│ └── duck.sh # DuckDNS update script (runs via cron)
└── homelab
├── Caddyfile # Reverse proxy configuration for Caddy
└── compose.yml # Docker Compose stack for Vaultwarden + 2FAuth + Caddy
Secrets and Environment Variables
Before deploying, you must replace all placeholder values in the config files.
https://vault.example.comandvault.example.com→ your Vaultwarden domainhttps://auth.example.comandauth.example.com→ your 2FAuth domainadmin@example.com→ your email address (used by Caddy / Let’s Encrypt and 2FAuth)TOKEN→ your DuckDNS tokenSomeRandomStringOf32CharsExactly→ a 32-character random string forAPP_KEY
DuckDNS Dynamic DNS Updater
The duckdns/duck.sh script updates all DuckDNS domains used by the homelab. It always logs to duckdns/duck.log.
Run manually
cd duckdns
./duck.sh
Cron to run periodically (recommended)
cd duckdns
chmod 700 duck.sh
crontab -e
Add:
*/5 * * * * /path/to/duckdns/duck.sh >/dev/null 2>&1
This ensures your DuckDNS domains always point to your current IP.
Homelab Stack (Docker Compose)
The homelab/ folder contains:
compose.yml– runs Vaultwarden, 2FAuth, and CaddyCaddyfile– defines routing for:https://<vault-domain>→ Vaultwardenhttps://<auth-domain>→ 2FAuth
Start the stack
cd homelab
docker compose up -d
Stop the stack
cd homelab
docker compose down
View logs
docker logs caddy -f
docker logs vaultwarden -f
docker logs 2fauth -f
Auto-start on system boot
The containers already use:
restart: always
But remember to enable Docker on startup:
sudo systemctl enable docker
Set correct permissions for volumes (optional)
Run:
sudo chown -R 1000:1000 homelab/vaultwarden
sudo chmod -R 755 homelab/vaultwarden
sudo chown -R 1000:1000 homelab/2fauth
sudo chmod -R 755 homelab/2fauth
Then restart the containers:
cd homelab
docker compose restart vaultwarden 2fauth
Updating
To update to the latest versions:
cd homelab
docker compose pull
docker compose up -d
This will refresh all Docker images with zero downtime.
Description
Languages
Shell
74.1%
Dockerfile
25.9%