This repository contains a personal home server setup using Docker Compose. Each service has its own folder under services/ with individual docker-compose.yml and .env.template files.
All services run in a shared Docker network called proxy. Routing and TLS are handled via Traefik using ACME DNS challenge.
-
Clone the repository:
git clone https://github.com/joshuawiebe/homelab.git cd homelab -
Run configuration:
./.automations/config.sh
- Set the base domain (e.g.,
example.com) - Set subdomains for each service
- Provide ACME email and IPv64 DNS API token
- Optionally generate passwords automatically
- Set the base domain (e.g.,
-
Start all services:
./.automations/start.sh
-
Stop services:
./.automations/stop.sh
/homelab/
├── .automations/
│ ├── config.sh
│ ├── start.sh
│ └── stop.sh
├── services/
│ ├── adguard_home/
│ ├── gotify/
│ ├── nextcloud/
│ ├── traefik/
│ ├── uptime_kuma/
│ ├── vaultwarden/
│ ├── watchtower/
│ └── zoraxy/
├── auto_backup/
│ ├── backup_setup.sh
│ ├── backup_start.sh
│ ├── backup_remove.sh
│ └── .env.sample
├── .gitignore
├── LICENSE
└── README.md
- Nextcloud – personal cloud storage (HSTS enabled)
- Vaultwarden – password manager (Bitwarden-compatible)
- Traefik – reverse proxy, HTTPS, ACME DNS challenge
- AdGuard Home – network-wide ad blocking
- Gotify – push notifications
- Uptime Kuma – uptime monitoring
- Watchtower – automatic container updates
- Zoraxy - alternative reverse proxy, HTTPS, ACME DNS challenge
- Generates
.envfiles from templates - Configures base domain, subdomains, ACME email, and IPv64 token
- Generates secure passwords
- Generates hashed Vaultwarden admin token
- Optionally starts services
- Starts services in correct order
- Detects reverse proxy automatically (Traefik or Zoraxy)
- New: Accepts
--proxyflag for automated runs (used by backup scripts)
- Stops all services safely in reverse order
- Detects reverse proxy automatically
The auto_backup/ folder provides a fully automated daily backup system using Borg.
Backups run on a USB drive, prune old archives, and log activity.
No user interaction is required — services are stopped, backup is taken, then services are restarted automatically.
auto_backup/
├── backup_setup.sh # Interactive setup, generates .env, systemd service/timer
├── backup_start.sh # Runs the backup based on .env config
├── backup_remove.sh # Removes backup automation
├── .env.sample # Example config for manual setup
- Automated service stop/start (reverse proxy detected automatically)
- Automated proxy selection: uses
DEFAULT_PROXYfrom.envor--proxyflag - USB mount/unmount handled automatically
- Daily Borg backups with pruning (default: keep last 7 archives)
- Detailed logging to file
- Systemd timer ensures execution without user interaction
- Manual removal with
backup_remove.sh
Note: You can also use a remote Borg repo (over SSH), e.g. user@host:/path/to/repo.
-
Run setup (recommended):
cd auto_backup sudo ./backup_setup.shThis generates
.env, a systemd service, and a timer. During setup you can choose the default proxy (traefikorzoraxy) for automated runs. -
Manual setup (optional):
If you don’t want to use the script, copy
.env.sampleto.envand edit values, then configure systemd manually (see below). -
Test a backup manually:
sudo systemctl start auto_backup.service sudo journalctl -u auto_backup.service -n 50
-
Remove automation:
sudo ./backup_remove.sh
If you prefer not to run backup_setup.sh, you can manually add the systemd service and timer:
-
Copy service file to
/etc/systemd/system/auto_backup.service:[Unit] Description=Automatic Borg Backup [Service] Type=oneshot EnvironmentFile=/full/path/to/auto_backup/.env ExecStart=/full/path/to/auto_backup/backup_start.sh
-
Copy timer file to
/etc/systemd/system/auto_backup.timer:[Unit] Description=Run automatic backup daily at 02:00:00 [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true [Install] WantedBy=timers.target
-
Enable timer:
sudo systemctl daemon-reload sudo systemctl enable --now auto_backup.timer -
Check status:
sudo systemctl status auto_backup.timer sudo journalctl -u auto_backup.service -n 50
-
Manually run backup:
sudo systemctl start auto_backup.service
.env.templatefiles hold placeholdersconfig.shcreates.envfiles with secure valuesauto_backup/.envstores backup-specific config (USB, repo, schedule, passphrase)DEFAULT_PROXYadded for automated backup runs- Do not commit
.envfiles containing secrets
- All services communicate via Docker network
proxy - Traefik handles HTTPS and routing
- Services are not directly exposed
- Nextcloud:
nextcloud/,db/ - Vaultwarden:
vw-data/ - AdGuard Home:
conf/,work/ - Gotify:
data/ - Uptime Kuma:
data/ - Traefik:
acme.json(certificates) - Backups: stored on USB in
borgrepofolder
docker run --rm -it vaultwarden/server /vaultwarden hash- Enter password twice
- Copy PHC string into
services/vaultwarden/.envunderADMIN_TOKEN=
- Nextcloud:
https://nextcloud.BASE_DOMAIN - Vaultwarden:
https://vault.BASE_DOMAIN - Traefik Dashboard:
https://traefik.BASE_DOMAIN - Other services follow their configured subdomains
- No secrets are committed; only
.env.templateand.env.sampleare included - Modular design allows easy addition of new services
- Traefik handles all HTTPS termination and routing
- Internal services communicate via proxy network
- Auto backup is fully automated, integrates reverse proxy detection, and supports
DEFAULT_PROXYfor non-interactive runs
MIT — free to use, adapt, and learn from. Do not commit live credentials.