Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion BOUNTY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
| 2 | [Media Stack — Jellyfin + Sonarr + Radarr + qBittorrent](https://github.com/illbnm/homelab-stack/issues/2) | 🟡 Medium | $160 | 🟢 Open |
| 3 | [Storage Stack — Nextcloud + MinIO + FileBrowser](https://github.com/illbnm/homelab-stack/issues/3) | 🟡 Medium | $150 | 🟢 Open |
| 4 | [Network Stack — AdGuard + WireGuard + Nginx Proxy Manager](https://github.com/illbnm/homelab-stack/issues/4) | 🟡 Medium | $140 | 🟢 Open |
| 5 | [Productivity Stack — Gitea + Vaultwarden + Outline + BookStack](https://github.com/illbnm/homelab-stack/issues/5) | 🟡 Medium | $170 | 🟢 Open |
| 5 | [Productivity Stack — Gitea + Vaultwarden + Outline + Stirling PDF + Excalidraw](https://github.com/illbnm/homelab-stack/issues/5) | 🟡 Medium | $170 | 🟢 Open |
| 6 | [AI Stack — Ollama + Open WebUI + Stable Diffusion](https://github.com/illbnm/homelab-stack/issues/6) | 🔴 Hard | $220 | 🟢 Open |
| 7 | [Home Automation — Home Assistant + Node-RED + Zigbee2MQTT](https://github.com/illbnm/homelab-stack/issues/7) | 🟡 Medium | $130 | 🟢 Open |
| 8 | [Robustness — 国内网络适配 + 环境鲁棒性](https://github.com/illbnm/homelab-stack/issues/8) | 🔴 Hard | $250 | 🟢 Open |
Expand Down
26 changes: 14 additions & 12 deletions homelab.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ homelab-redis
Outline/Nextcloud cache")]
MariaDB[("MariaDB 11.4
homelab-mariadb
BookStack")]
")\]
end

subgraph ObsLayer["Observability -- monitoring Stack"]
Expand Down Expand Up @@ -112,8 +112,10 @@ git.DOMAIN"]
vault.DOMAIN"]
Outline["Outline 0.80.2
docs.DOMAIN"]
BookStack["BookStack 24.10
books.DOMAIN"]
StirlingPDF["Stirling PDF 0.30.2
pdf.DOMAIN"]
Excalidraw["Excalidraw latest-sha
draw.DOMAIN"]
end

subgraph StorageLayer["Storage Stack"]
Expand Down Expand Up @@ -177,7 +179,8 @@ home.DOMAIN"]
Traefik --> Gitea
Traefik --> Vault
Traefik --> Outline
Traefik --> BookStack
Traefik --> StirlingPDF
Traefik --> Excalidraw
Traefik --> Nextcloud
Traefik --> Jellyfin
Traefik --> Ollama
Expand All @@ -193,14 +196,12 @@ home.DOMAIN"]

Grafana -->|OIDC| Authentik
Outline -->|OIDC| Authentik
BookStack -->|OIDC| Authentik
Gitea -->|OAuth2| Authentik

Gitea --- PG
Vault --- PG
Outline --- PG
Outline --- Redis
BookStack --- MariaDB
Nextcloud --- PG
Nextcloud --- Redis

Expand Down Expand Up @@ -261,11 +262,11 @@ databases ───────────────────────
└─ creates: databases network │
└─ homelab-postgres:5432 ───────────────┼─> gitea, vaultwarden, outline, nextcloud
└─ homelab-redis:6379 ──────────────────┼─> outline, nextcloud
└─ homelab-mariadb:3306 ────────────────┼─> bookstack
└─ homelab-mariadb:3306 ────────────────┼─>
sso (Authentik) ────────────────────────────┤
└─ own postgres + redis (isolated) │
└─ OIDC provider ───────────────────────┼─> grafana, outline, bookstack
└─ OIDC provider ───────────────────────┼─> grafana, outline
└─ OAuth2 provider ─────────────────────┼─> gitea
└─ ForwardAuth middleware ──────────────┼─> traefik (all routes)
Expand Down Expand Up @@ -323,7 +324,6 @@ sequenceDiagram
|---------|-----------|-------|---------------|
| Grafana | Generic OAuth2 | openid profile email | Yes (role via groups) |
| Outline | OIDC | openid profile email | Yes |
| BookStack | OIDC | openid profile email | Yes |
| Gitea | OAuth2 provider | openid profile email | Yes |
| Portainer | ForwardAuth | N/A | Manual first login |
| Vaultwarden | ForwardAuth (admin only) | N/A | N/A |
Expand Down Expand Up @@ -411,7 +411,7 @@ CN mirror: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/goauthentik/server:2
|---------|---------------|------|---------|
| PostgreSQL | homelab-postgres | 5432 | Gitea, Vaultwarden, Outline, Nextcloud |
| Redis | homelab-redis | 6379 | Outline, Nextcloud |
| MariaDB | homelab-mariadb | 3306 | BookStack |
| MariaDB | homelab-mariadb | 3306 | - |

### monitoring
| Service | Image | URL |
Expand All @@ -430,7 +430,8 @@ CN mirror: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/goauthentik/server:2
| Gitea | gitea/gitea:1.22.3 | git.DOMAIN | homelab-postgres | OAuth2 |
| Vaultwarden | vaultwarden/server:1.32.0 | vault.DOMAIN | homelab-postgres | ForwardAuth |
| Outline | outlinewiki/outline:0.80.2 | docs.DOMAIN | homelab-postgres+redis | OIDC |
| BookStack | linuxserver/bookstack:24.10 | books.DOMAIN | homelab-mariadb | OIDC |
| Stirling PDF | frooodle/s-pdf:0.30.2 | pdf.DOMAIN | - | ForwardAuth |
| Excalidraw | excalidraw/excalidraw:latest-sha | draw.DOMAIN | - | ForwardAuth |

Networks: proxy + databases

Expand Down Expand Up @@ -522,7 +523,8 @@ Integrations: Alertmanager/Node-RED -> ntfy; Apprise -> multi-channel
| git.DOMAIN | Gitea | productivity |
| vault.DOMAIN | Vaultwarden | productivity |
| docs.DOMAIN | Outline | productivity |
| books.DOMAIN | BookStack | productivity |
| pdf.DOMAIN | Stirling PDF | productivity |
| draw.DOMAIN | Excalidraw | productivity |
| nextcloud.DOMAIN | Nextcloud | storage |
| minio.DOMAIN | MinIO | storage |
| files.DOMAIN | FileBrowser | storage |
Expand Down
2 changes: 1 addition & 1 deletion stacks/databases/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ NEXTCLOUD_DB_PASSWORD=CHANGE_ME
GITEA_DB_PASSWORD=CHANGE_ME
OUTLINE_DB_PASSWORD=CHANGE_ME
VAULTWARDEN_DB_PASSWORD=CHANGE_ME
BOOKSTACK_DB_PASSWORD=CHANGE_ME

4 changes: 1 addition & 3 deletions stacks/databases/initdb-mysql/01-init-databases.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
-- HomeLab MariaDB init
-- Creates databases for services that prefer MySQL/MariaDB

CREATE DATABASE IF NOT EXISTS `bookstack` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'bookstack'@'%' IDENTIFIED BY '${BOOKSTACK_DB_PASSWORD:-changeme}';
GRANT ALL PRIVILEGES ON `bookstack`.* TO 'bookstack'@'%';


CREATE DATABASE IF NOT EXISTS `nextcloud_mysql` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'nextcloud'@'%' IDENTIFIED BY '${NEXTCLOUD_DB_PASSWORD:-changeme}';
Expand Down
5 changes: 1 addition & 4 deletions stacks/databases/initdb/01-init-databases.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E
CREATE DATABASE vaultwarden OWNER vaultwarden ENCODING 'UTF8';
GRANT ALL PRIVILEGES ON DATABASE vaultwarden TO vaultwarden;

-- BookStack
CREATE USER bookstack WITH PASSWORD '${BOOKSTACK_DB_PASSWORD:-changeme_bookstack}';
CREATE DATABASE bookstack OWNER bookstack ENCODING 'UTF8';
GRANT ALL PRIVILEGES ON DATABASE bookstack TO bookstack;

EOSQL

echo "[init-postgres] All databases created successfully"
25 changes: 13 additions & 12 deletions stacks/productivity/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Productivity Stack �� Environment Variables
# Productivity Stack - Environment Variables
# Copy to .env and fill ALL values before running.

DOMAIN=yourdomain.com
Expand All @@ -11,28 +11,29 @@ AUTHENTIK_DOMAIN=auth.yourdomain.com
GITEA_DB_PASSWORD=
VAULTWARDEN_DB_PASSWORD=
OUTLINE_DB_PASSWORD=
BOOKSTACK_DB_PASSWORD=

# Redis password (must match databases stack .env)
REDIS_PASSWORD=

# Secrets �� generate with: openssl rand -hex 32
# Secrets - generate with: openssl rand -hex 32
VAULTWARDEN_ADMIN_TOKEN=
OUTLINE_SECRET_KEY=
OUTLINE_UTILS_SECRET=
GITEA_OAUTH2_JWT_SECRET=
GITEA_RUNNER_TOKEN=

# BookStack �� generate APP_KEY with: echo "base64:$(openssl rand -base64 32)"
BOOKSTACK_APP_KEY=
# Set to 'oidc' to enable SSO (requires OIDC vars below)
BOOKSTACK_AUTH_METHOD=standard
# MinIO S3 credentials for Outline
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=changeme-minio

# OAuth2 client credentials �� filled by scripts/setup-authentik.sh
GRAFANA_OAUTH_CLIENT_ID=
GRAFANA_OAUTH_CLIENT_SECRET=
# SMTP configuration for Vaultwarden
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=

# OAuth2 client credentials - filled by scripts/setup-authentik.sh
GITEA_OAUTH_CLIENT_ID=
GITEA_OAUTH_CLIENT_SECRET=
OUTLINE_OAUTH_CLIENT_ID=
OUTLINE_OAUTH_CLIENT_SECRET=
BOOKSTACK_OIDC_CLIENT_ID=
BOOKSTACK_OIDC_CLIENT_SECRET=
112 changes: 73 additions & 39 deletions stacks/productivity/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
services:
gitea:
image: gitea/gitea:1.22.3
image: gitea/gitea:1.22.2
# CN mirror fallback (uncomment if inaccessible):
# image: docker.m.daocloud.io/gitea/gitea:1.22.2
container_name: gitea
restart: unless-stopped
networks:
Expand All @@ -18,6 +20,7 @@ services:
- GITEA__server__ROOT_URL=https://git.${DOMAIN}
- GITEA__server__HTTP_PORT=3000
- GITEA__security__INSTALL_LOCK=true
- GITEA__service__DISABLE_REGISTRATION=true
- GITEA__mailer__ENABLED=false
- GITEA__oauth2__ENABLE=true
- GITEA__oauth2__JWT_SECRET=${GITEA_OAUTH2_JWT_SECRET}
Expand All @@ -36,8 +39,27 @@ services:
retries: 3
start_period: 60s

gitea-runner:
image: gitea/act_runner:nightly
# CN mirror fallback (uncomment if inaccessible):
# image: docker.m.daocloud.io/gitea/act_runner:nightly
container_name: gitea-runner
restart: unless-stopped
networks:
- proxy
- databases
environment:
- GITEA_INSTANCE_URL=https://git.${DOMAIN}
- GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN}
- GITEA_RUNNER_NAME=homelab-runner
volumes:
- gitea-runner-data:/data
- /var/run/docker.sock:/var/run/docker.sock

vaultwarden:
image: vaultwarden/server:1.32.0
# CN mirror fallback (uncomment if inaccessible):
# image: docker.m.daocloud.io/vaultwarden/server:1.32.0
container_name: vaultwarden
restart: unless-stopped
networks:
Expand All @@ -50,6 +72,13 @@ services:
- DATABASE_URL=postgresql://vaultwarden:${VAULTWARDEN_DB_PASSWORD}@homelab-postgres:5432/vaultwarden
- LOG_LEVEL=warn
- TZ=${TZ}
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_SECURITY=starttls
- SMTP_USERNAME=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASS}
- SMTP_FROM=vaultwarden@${DOMAIN}
- SMTP_FROM_NAME=Vaultwarden
volumes:
- vaultwarden-data:/data
labels:
Expand All @@ -67,6 +96,8 @@ services:

outline:
image: outlinewiki/outline:0.80.2
# CN mirror fallback (uncomment if inaccessible):
# image: docker.m.daocloud.io/outlinewiki/outline:0.80.2
container_name: outline
restart: unless-stopped
networks:
Expand All @@ -88,11 +119,14 @@ services:
- OIDC_LOGOUT_URI=https://${AUTHENTIK_DOMAIN}/application/o/outline/end-session/
- OIDC_DISPLAY_NAME=Authentik
- OIDC_SCOPES=openid profile email
- FILE_STORAGE=local
- FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
- FILE_STORAGE_UPLOAD_MAX_SIZE=26214400
volumes:
- outline-data:/var/lib/outline/data
- FILE_STORAGE=s3
- AWS_ACCESS_KEY_ID=${MINIO_ROOT_USER:-minioadmin}
- AWS_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD:-changeme-minio}
- AWS_REGION=us-east-1
- AWS_S3_UPLOAD_BUCKET_URL=https://s3.${DOMAIN}
- AWS_S3_UPLOAD_BUCKET_NAME=outline
- AWS_S3_FORCE_PATH_STYLE=true
- AWS_S3_ACL=private
labels:
- traefik.enable=true
- "traefik.http.routers.outline.rule=Host(`docs.${DOMAIN}`)"
Expand All @@ -106,44 +140,42 @@ services:
retries: 3
start_period: 60s

bookstack:
image: lscr.io/linuxserver/bookstack:24.10.20241031
container_name: bookstack
stirling-pdf:
image: frooodle/s-pdf:0.30.2
# CN mirror fallback (uncomment if inaccessible):
# image: docker.m.daocloud.io/frooodle/s-pdf:0.30.2
container_name: stirling-pdf
restart: unless-stopped
networks:
- proxy
- databases
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ}
- APP_URL=https://wiki.${DOMAIN}
- APP_KEY=${BOOKSTACK_APP_KEY}
- DB_HOST=homelab-mariadb
- DB_PORT=3306
- DB_DATABASE=bookstack
- DB_USERNAME=bookstack
- DB_PASSWORD=${BOOKSTACK_DB_PASSWORD}
- AUTH_METHOD=${BOOKSTACK_AUTH_METHOD:-standard}
- OIDC_CLIENT_ID=${BOOKSTACK_OIDC_CLIENT_ID}
- OIDC_CLIENT_SECRET=${BOOKSTACK_OIDC_CLIENT_SECRET}
- OIDC_ISSUER=https://${AUTHENTIK_DOMAIN}/application/o/bookstack/
- OIDC_NAME=Authentik
- OIDC_DUMP_USER_DETAILS=false
- DOCKER_ENABLE_SECURITY=false
- TZ=${TZ:-Asia/Shanghai}
volumes:
- bookstack-data:/config
- stirling-pdf-trainingData:/usr/share/tesseract-ocr/4.00/tessdata
- stirling-pdf-extraConfigs:/configs
- stirling-pdf-customFiles:/customFiles
labels:
- traefik.enable=true
- "traefik.http.routers.bookstack.rule=Host(`wiki.${DOMAIN}`)"
- traefik.http.routers.bookstack.entrypoints=websecure
- traefik.http.routers.bookstack.tls=true
- traefik.http.services.bookstack.loadbalancer.server.port=80
healthcheck:
test: [CMD, wget, -qO-, http://localhost:80/login]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
- "traefik.http.routers.stirling-pdf.rule=Host(`pdf.${DOMAIN}`)"
- traefik.http.routers.stirling-pdf.entrypoints=websecure
- traefik.http.routers.stirling-pdf.tls=true
- traefik.http.services.stirling-pdf.loadbalancer.server.port=8080

excalidraw:
image: excalidraw/excalidraw:latest-sha
# CN mirror fallback (uncomment if inaccessible):
# image: docker.m.daocloud.io/excalidraw/excalidraw:latest-sha
container_name: excalidraw
restart: unless-stopped
networks:
- proxy
labels:
- traefik.enable=true
- "traefik.http.routers.excalidraw.rule=Host(`draw.${DOMAIN}`)"
- traefik.http.routers.excalidraw.entrypoints=websecure
- traefik.http.routers.excalidraw.tls=true
- traefik.http.services.excalidraw.loadbalancer.server.port=80

networks:
proxy:
Expand All @@ -153,6 +185,8 @@ networks:

volumes:
gitea-data:
gitea-runner-data:
vaultwarden-data:
outline-data:
bookstack-data:
stirling-pdf-trainingData:
stirling-pdf-extraConfigs:
stirling-pdf-customFiles: