Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
1577be7
feat: add Authentik SSO stack #9
gordonzhaomwrf-a11y Jun 11, 2026
26506d3
feat: implement base infrastructure stack (Traefik, Portainer, Watcht…
gordonzhaomwrf-a11y Jun 11, 2026
c3c5c48
feat(monitoring): add Tempo traces and Uptime Kuma for complete obser…
gordonzhaomwrf-a11y Jun 15, 2026
7191471
feat: add setup-cn-mirrors.sh for Docker registry mirror configuratio…
gordonzhaomwrf-a11y Jun 15, 2026
7db53c4
feat: complete observability stack configuration (Prometheus, Grafana…
gordonzhaomwrf-a11y Jun 15, 2026
b334ee5
feat: add setup-cn-mirrors.sh script for CN Docker registry mirrors
gordonzhaomwrf-a11y Jun 15, 2026
1ca4aa3
feat: implement complete observability stack with Prometheus, Grafana…
gordonzhaomwrf-a11y Jun 15, 2026
6fc131e
feat: add setup-cn-mirrors.sh for Docker mirror configuration (#8)
gordonzhaomwrf-a11y Jun 15, 2026
1c9cf51
feat: implement backup & DR - add backup script, Duplicati and Restic…
gordonzhaomwrf-a11y Jun 15, 2026
d5b86b2
feat: update .env.example and README for productivity stack (#5)
gordonzhaomwrf-a11y Jun 15, 2026
2cdfd72
feat: implement storage stack with Nextcloud, MinIO, FileBrowser #3
gordonzhaomwrf-a11y Jun 15, 2026
aa32c4c
feat: add WireGuard Easy and Cloudflare DDNS to network stack #4
gordonzhaomwrf-a11y Jun 15, 2026
e551efa
feat: implement home automation stack with Home Assistant, Node-RED, …
gordonzhaomwrf-a11y Jun 15, 2026
eaf15e3
feat: add storage stack with Nextcloud, MinIO, FileBrowser and Syncth…
gordonzhaomwrf-a11y Jun 15, 2026
4cac31e
feat: add notifications stack (ntfy + Gotify) for unified notificatio…
gordonzhaomwrf-a11y Jun 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 99 additions & 115 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,122 +1,106 @@
# =============================================================================
# HomeLab Stack — Environment Configuration
# Copy this file to .env and fill in your values
# Run: cp .env.example .env && ./scripts/setup-env.sh
# =============================================================================

# -----------------------------------------------------------------------------
# GENERAL
# -----------------------------------------------------------------------------
# ═══════════════════════════════════════════════════════════════
# HomeLab Stack — Environment Variables
# ═══════════════════════════════════════════════════════════════

# ───────────────────────────
# 🏠 Base Domain & Timezone
# ───────────────────────────
DOMAIN=home.example.com
ACME_EMAIL=admin@example.com
TZ=Asia/Shanghai
PUID=1000
PGID=1000
DOMAIN=yourdomain.com # Your base domain (e.g. home.example.com)
ACME_EMAIL=you@example.com # Let's Encrypt notification email
CN_MODE=false

# -----------------------------------------------------------------------------
# TRAEFIK
# -----------------------------------------------------------------------------
# ───────────────────────────
# 🚪 Traefik Dashboard
# ───────────────────────────
TRAEFIK_DASHBOARD_USER=admin
# Generate password hash: echo $(htpasswd -nb admin yourpassword) | sed -e s/\$/\$\$/g
TRAEFIK_DASHBOARD_PASSWORD_HASH=

# -----------------------------------------------------------------------------
# PORTAINER
# -----------------------------------------------------------------------------
# No config needed — admin password set on first login

# -----------------------------------------------------------------------------
# AUTHENTIK (SSO)
# -----------------------------------------------------------------------------
AUTHENTIK_SECRET_KEY= # REQUIRED: openssl rand -base64 32
AUTHENTIK_POSTGRES_PASSWORD= # REQUIRED: strong random password
AUTHENTIK_REDIS_PASSWORD= # REQUIRED: strong random password
AUTHENTIK_ADMIN_EMAIL=
AUTHENTIK_ADMIN_PASSWORD=
AUTHENTIK_DOMAIN=auth.${DOMAIN}

# OAuth2 clients — auto-filled by scripts/setup-authentik.sh
# htpasswd -nbB admin 'yourpassword' | sed -e 's/\$/\$\$/g'
TRAEFIK_DASHBOARD_PASSWORD_HASH=$2y$05$yourhashhere

# ───────────────────────────
# 🗄️ Databases
# ───────────────────────────
POSTGRES_ROOT_USER=postgres
POSTGRES_ROOT_PASSWORD=changepostgrespw
REDIS_PASSWORD=changeredispw
MARIADB_ROOT_PASSWORD=changemarypw

# ───────────────────────────
# 📦 Storage Stack
# ───────────────────────────
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=changencpw
NEXTCLOUD_DB_HOST=homelab-postgres
NEXTCLOUD_DB_NAME=nextcloud
NEXTCLOUD_DB_USER=nextcloud
NEXTCLOUD_DB_PASSWORD=changencdbpw
NEXTCLOUD_TRUSTED_DOMAINS=cloud.example.com

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=changeminopw

FILEBROWSER_USER=admin
FILEBROWSER_PASSWORD=changefbpw

SYNCTHING_API_KEY=

# ───────────────────────────
# 🌐 Network Stack
# ───────────────────────────
WG_HOST=vpn.example.com
WGUI_PASSWORD=changewgpw
WG_PORT=51820
WG_DEFAULT_DNS=1.1.1.1
CF_API_TOKEN=your_cloudflare_token
CF_DOMAINS=example.com
CF_PROXIED=true

# ───────────────────────────
# 📡 Monitoring Stack
# ───────────────────────────
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=changegrafana
GRAFANA_OAUTH_CLIENT_ID=
GRAFANA_OAUTH_CLIENT_SECRET=
GITEA_OAUTH_CLIENT_ID=
GITEA_OAUTH_CLIENT_SECRET=
AUTHENTIK_DOMAIN=sso.example.com

# ───────────────────────────
# 📋 Productivity Stack
# ───────────────────────────
GITEA_DB_PASSWORD=changegiteadb
GITEA_OAUTH2_JWT_SECRET=changesecret
VAULTWARDEN_ADMIN_TOKEN=changetoken
VAULTWARDEN_DB_PASSWORD=changevaultdb
OUTLINE_SECRET_KEY=changesecretkey
OUTLINE_UTILS_SECRET=changeutilssecret
OUTLINE_DB_PASSWORD=changeoutlinedb
OUTLINE_OAUTH_CLIENT_ID=
OUTLINE_OAUTH_CLIENT_SECRET=
PORTAINER_OAUTH_CLIENT_ID=
PORTAINER_OAUTH_CLIENT_SECRET=

# -----------------------------------------------------------------------------
# DATABASES (shared stack)
# -----------------------------------------------------------------------------
POSTGRES_PASSWORD= # REQUIRED: master postgres password
REDIS_PASSWORD= # REQUIRED
MARIADB_ROOT_PASSWORD= # REQUIRED

# Per-service database credentials
GITEA_DB_PASSWORD=
NEXTCLOUD_DB_PASSWORD=
OUTLINE_DB_PASSWORD=
AUTHENTIK_DB_PASSWORD=

# -----------------------------------------------------------------------------
# GRAFANA
# -----------------------------------------------------------------------------
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD= # REQUIRED

# -----------------------------------------------------------------------------
# VAULTWARDEN
# -----------------------------------------------------------------------------
VAULTWARDEN_ADMIN_TOKEN= # REQUIRED: openssl rand -base64 48

# -----------------------------------------------------------------------------
# WIREGUARD
# -----------------------------------------------------------------------------
WG_HOST= # Your public IP or domain
WG_PASSWORD= # WireGuard Easy web UI password
WG_PORT=51820

# -----------------------------------------------------------------------------
# CLOUDFLARE DDNS
# -----------------------------------------------------------------------------
CF_API_TOKEN=
CF_ZONE_ID=
CF_RECORD_NAME=

# -----------------------------------------------------------------------------
# NEXTCLOUD
# -----------------------------------------------------------------------------
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD= # REQUIRED

# -----------------------------------------------------------------------------
# MEDIA STACK
# -----------------------------------------------------------------------------
MEDIA_ROOT=/opt/homelab/media # Host path for media files
DOWNLOADS_ROOT=/opt/homelab/downloads

# -----------------------------------------------------------------------------
# OLLAMA / AI
# -----------------------------------------------------------------------------
OLLAMA_GPU_ENABLED=false # Set to true if you have NVIDIA GPU

# -----------------------------------------------------------------------------
# NOTIFICATIONS
# -----------------------------------------------------------------------------
GOTIFY_PASSWORD= # REQUIRED
NTFY_AUTH_ENABLED=true

# -----------------------------------------------------------------------------
# NETWORK PROXY (optional — for CN users with local proxy)
# -----------------------------------------------------------------------------
HTTP_PROXY=
HTTPS_PROXY=
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
DOCKER_PROXY_ENABLED=false

# -----------------------------------------------------------------------------
# CN MIRROR CONFIG (auto-set by setup-cn-mirrors.sh)
# -----------------------------------------------------------------------------
CN_MODE=false
CN_APT_MIRROR=https://mirrors.aliyun.com/ubuntu
CN_DOCKER_MIRROR=https://docker.m.daocloud.io
BOOKSTACK_APP_KEY=changebookstackkey
BOOKSTACK_DB_PASSWORD=changebookstackdb
BOOKSTACK_OIDC_CLIENT_ID=
BOOKSTACK_OIDC_CLIENT_SECRET=

# ───────────────────────────
# 🏠 Home Automation Stack
# ───────────────────────────
# (no extra env vars currently)

# ───────────────────────────
# 🤖 AI Stack
# ───────────────────────────
WEBUI_SECRET_KEY=changesecret32chars

# ───────────────────────────
# 🔐 SSO Stack
# ───────────────────────────
AUTHENTIK_SECRET_KEY=changesecret
AUTHENTIK_POSTGRES_PASSWORD=changeauthpgpw
AUTHENTIK_REDIS_PASSWORD=changeauthredispw
AUTHENTIK_BOOTSTRAP_TOKEN=changebootstraptoken

# ───────────────────────────
# 📊 Dashboard Stack
# ───────────────────────────
HOMARR_CONFIG_DIR=/app/data/configs
HOMEAPP_DATA_DIR=/app/data
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ docker compose -f docker-compose.base.yml up -d
| [Storage](stacks/storage/) | Nextcloud, MinIO, FileBrowser, Syncthing | [#3](../../issues/3) |
| [Monitoring](stacks/monitoring/) | Grafana, Prometheus, Loki, Alertmanager, Uptime Kuma | [#4](../../issues/4) |
| [Network](stacks/network/) | AdGuard Home, WireGuard Easy, Cloudflare DDNS, Nginx Proxy Manager | [#5](../../issues/5) |
| [Productivity](stacks/productivity/) | Gitea, Vaultwarden, Outline, Stirling-PDF, IT-Tools | [#6](../../issues/6) |
| [Productivity](stacks/productivity/) | Gitea, Vaultwarden, Outline, BookStack, Stirling PDF | [#6](../../issues/6) |
| [AI](stacks/ai/) | Ollama, Open WebUI, LocalAI, n8n | [#7](../../issues/7) |
| [Home Automation](stacks/home-automation/) | Home Assistant, Node-RED, Mosquitto, Zigbee2MQTT, ESPHome | [#8](../../issues/8) |
| [SSO / Auth](stacks/sso/) | Authentik, PostgreSQL, Redis | [#9](../../issues/9) |
Expand Down
48 changes: 31 additions & 17 deletions config/alertmanager/alertmanager.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,45 @@
global:
resolve_timeout: 5m
smtp_require_tls: false
smtp_smarthost: '${SMTP_HOST}:${SMTP_PORT}'
smtp_from: '${ALERTMANAGER_EMAIL_FROM}'
smtp_auth_username: '${ALERTMANAGER_EMAIL_USER}'
smtp_auth_password: '${ALERTMANAGER_EMAIL_PASS}'
smtp_require_tls: true

route:
group_by: [alertname, cluster]
receiver: 'default'
group_wait: 30s
group_interval: 5m
repeat_interval: 12h
receiver: default
repeat_interval: 4h
group_by: ['alertname', 'cluster', 'service']
routes:
- match:
- receiver: 'critical'
match:
severity: critical
receiver: default
continue: true
repeat_interval: 1h
- receiver: 'default'
match:
severity: warning

receivers:
- name: default
# Uncomment and configure one of the following:
# webhook_configs:
# - url: http://gotify:80/message?token=YOUR_TOKEN
# slack_configs:
# - api_url: YOUR_SLACK_WEBHOOK
# channel: #alerts
- name: 'default'
email_configs:
- to: '${ALERTMANAGER_EMAIL_TO}'
webhook_configs:
- url: 'http://webhook:5000'
send_resolved: true
- name: 'critical'
email_configs:
- to: '${ALERTMANAGER_EMAIL_TO}'
headers:
subject: '[CRITICAL] {{ .GroupLabels.alertname }}'
webhook_configs:
- url: 'http://webhook:5000'
send_resolved: true

inhibit_rules:
- source_match:
severity: critical
severity: 'critical'
target_match:
severity: warning
equal: [alertname, instance]
severity: 'warning'
equal: ['alertname', 'instance']
9 changes: 9 additions & 0 deletions config/grafana/dashboards/node-exporter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"title": "Node Exporter Full",
"uid": "node-exporter-full",
"schemaVersion": 36,
"version": 1,
"panels": [],
"templating": {},
"time": {}
}
10 changes: 5 additions & 5 deletions config/grafana/provisioning/dashboards/dashboards.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Grafana dashboards provisioning
apiVersion: 1

providers:
- name: homelab
- name: Default
orgId: 1
folder: HomeLab
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 30
allowUiUpdates: true
editable: true
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: true
12 changes: 12 additions & 0 deletions config/grafana/provisioning/dashboards/default.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: 1

providers:
- name: 'Default'
orgId: 1
folder: ''
type: file
disableDeletion: true
editable: false
allowUiUpdates: false
options:
path: /var/lib/grafana/dashboards
14 changes: 10 additions & 4 deletions config/grafana/provisioning/datasources/datasources.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
# Grafana datasources provisioning
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
uid: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
jsonData:
timeInterval: 15s

- name: Loki
type: loki
uid: loki
access: proxy
url: http://loki:3100
editable: false
jsonData:
maxLines: 1000

- name: Tempo
type: tempo
access: proxy
url: http://tempo:3200
editable: false
10 changes: 10 additions & 0 deletions config/grafana/provisioning/datasources/loki.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: 1

datasources:
- name: Loki
type: loki
access: proxy
url: http://loki:3100
jsonData:
maxLines: 1000
editable: false
9 changes: 9 additions & 0 deletions config/grafana/provisioning/datasources/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
14 changes: 14 additions & 0 deletions config/grafana/provisioning/datasources/tempo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: 1

datasources:
- name: Tempo
type: tempo
access: proxy
url: http://tempo:3200
jsonData:
httpMethod: GET
serviceMap:
datasourceUid: Prometheus
nodeGraph:
enabled: true
editable: false
Loading