Refactor docker-compose structure to folder-based organization
- Remove redundant .yml files from main docker-compose folder - Update deploy script to use folder-based structure for all stacks - Update documentation to reflect new folder-based organization - Standardize all stacks to use docker-compose.yml in individual folders This eliminates confusion between file-based and folder-based structures, making the repository more maintainable and consistent.
This commit is contained in:
23
Install script testing results.md
Normal file
23
Install script testing results.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
Install script testing results
|
||||||
|
|
||||||
|
Installed debian to start from scratch.
|
||||||
|
|
||||||
|
Install Nvidia driver failed in setup-homelab.scratch
|
||||||
|
Attempted to follow manual directions, manual directions missing how to generate the authelia secrets
|
||||||
|
script didn't generate
|
||||||
|
AUTHELIA_JWT_SECRET=generate-with-openssl-rand-hex-64
|
||||||
|
AUTHELIA_SESSION_SECRET=generate-with-openssl-rand-hex-64
|
||||||
|
AUTHELIA_STORAGE_ENCRYPTION_KEY=generate-with-openssl-rand-hex-64
|
||||||
|
|
||||||
|
in setup-homelab.sh
|
||||||
|
commented out the apt install nvidia lines
|
||||||
|
script completed successfully, but still missing authelia secrets
|
||||||
|
|
||||||
|
ran deploy script, it completed successfully as well.
|
||||||
|
however missing authelia secrets prevents proxy access
|
||||||
|
|
||||||
|
Fix setup and deploy scripts to ensure an effortless install from scratch for the user experience.
|
||||||
|
Confirm they work as intended, and services are available by proxy url.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,15 +1,22 @@
|
|||||||
# Docker Compose Stacks
|
# Docker Compose Stacks
|
||||||
|
|
||||||
This directory contains Docker Compose files for managing your homelab services. Each file is organized by functional area to maintain clarity and organization.
|
This directory contains Docker Compose files for managing your homelab services. Each stack is organized in its own folder for better organization and maintainability.
|
||||||
|
|
||||||
## Structure
|
## Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
docker-compose/
|
docker-compose/
|
||||||
├── infrastructure.yml # Core services (reverse proxy, DNS, etc.)
|
├── core/ # Core infrastructure (Traefik, Authelia, DuckDNS)
|
||||||
├── media.yml # Media server services (Plex, Jellyfin, etc.)
|
├── infrastructure/ # Additional infrastructure (Pi-hole, Dockge, etc.)
|
||||||
├── monitoring.yml # Observability stack (Prometheus, Grafana, etc.)
|
├── dashboards/ # Dashboard services (Homepage, Homarr)
|
||||||
├── development.yml # Development tools and services
|
├── vpn/ # VPN services (Gluetun, qBittorrent)
|
||||||
|
├── media/ # Media services (Plex, Jellyfin, etc.)
|
||||||
|
├── monitoring/ # Observability stack (Prometheus, Grafana, etc.)
|
||||||
|
├── alternatives/ # Alternative services (Authentik, etc.)
|
||||||
|
├── homeassistant/ # Home Assistant stack
|
||||||
|
├── nextcloud/ # Nextcloud stack
|
||||||
|
├── productivity/ # Productivity tools
|
||||||
|
├── utilities/ # Utility services
|
||||||
└── README.md # This file
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -17,31 +24,26 @@ docker-compose/
|
|||||||
|
|
||||||
### Starting Services
|
### Starting Services
|
||||||
|
|
||||||
Start all services in a compose file:
|
Start all services in a stack:
|
||||||
```bash
|
```bash
|
||||||
docker compose -f docker-compose/infrastructure.yml up -d
|
cd docker-compose/core && docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Start a specific service:
|
Start a specific service:
|
||||||
```bash
|
```bash
|
||||||
docker compose -f docker-compose/media.yml up -d plex
|
cd docker-compose/vpn && docker compose up -d gluetun
|
||||||
```
|
|
||||||
|
|
||||||
Start multiple compose files together:
|
|
||||||
```bash
|
|
||||||
docker compose -f docker-compose/infrastructure.yml -f docker-compose/media.yml up -d
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Stopping Services
|
### Stopping Services
|
||||||
|
|
||||||
Stop all services in a compose file:
|
Stop all services in a stack:
|
||||||
```bash
|
```bash
|
||||||
docker compose -f docker-compose/infrastructure.yml down
|
cd docker-compose/core && docker compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
Stop a specific service:
|
Stop a specific service:
|
||||||
```bash
|
```bash
|
||||||
docker compose -f docker-compose/media.yml stop plex
|
cd docker-compose/vpn && docker compose stop qbittorrent
|
||||||
```
|
```
|
||||||
|
|
||||||
### Viewing Status
|
### Viewing Status
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
# Core Infrastructure Stack
|
|
||||||
# Essential services required for the homelab to function
|
|
||||||
# Deploy this stack FIRST before any other services
|
|
||||||
# Place in /opt/stacks/core/docker-compose.yml
|
|
||||||
|
|
||||||
services:
|
|
||||||
# DuckDNS - Dynamic DNS updater
|
|
||||||
# Updates your public IP automatically for Let's Encrypt SSL
|
|
||||||
duckdns:
|
|
||||||
image: lscr.io/linuxserver/duckdns:latest
|
|
||||||
container_name: duckdns
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
- SUBDOMAINS=${DUCKDNS_SUBDOMAINS} # Your subdomain(s), comma separated
|
|
||||||
- TOKEN=${DUCKDNS_TOKEN} # Your DuckDNS token
|
|
||||||
- UPDATE_IP=ipv4 # or ipv6, or both
|
|
||||||
volumes:
|
|
||||||
- /opt/stacks/core/duckdns:/config
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=Dynamic DNS updater"
|
|
||||||
|
|
||||||
# Traefik - Reverse proxy with automatic SSL
|
|
||||||
# Routes all traffic and manages Let's Encrypt certificates
|
|
||||||
traefik:
|
|
||||||
image: traefik:v2.11
|
|
||||||
container_name: traefik
|
|
||||||
restart: unless-stopped
|
|
||||||
security_opt:
|
|
||||||
- no-new-privileges:true
|
|
||||||
networks:
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "80:80" # HTTP
|
|
||||||
- "443:443" # HTTPS
|
|
||||||
- "8080:8080" # Dashboard (protected with Authelia)
|
|
||||||
volumes:
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
- /opt/stacks/core/traefik/traefik.yml:/traefik.yml:ro
|
|
||||||
- /opt/stacks/core/traefik/dynamic:/dynamic:ro
|
|
||||||
- /opt/stacks/core/traefik/acme.json:/acme.json
|
|
||||||
environment:
|
|
||||||
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN} # If using Cloudflare DNS challenge
|
|
||||||
- DUCKDNS_TOKEN=${DUCKDNS_TOKEN} # If using DuckDNS
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
# Dashboard
|
|
||||||
- "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.traefik.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.traefik.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.routers.traefik.service=api@internal"
|
|
||||||
# Global HTTP to HTTPS redirect
|
|
||||||
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
|
|
||||||
- "traefik.http.routers.http-catchall.entrypoints=web"
|
|
||||||
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
|
|
||||||
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
|
|
||||||
depends_on:
|
|
||||||
- duckdns
|
|
||||||
|
|
||||||
# Authelia - SSO authentication
|
|
||||||
# Protects all admin services with single sign-on
|
|
||||||
authelia:
|
|
||||||
image: authelia/authelia:4.37
|
|
||||||
container_name: authelia
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- /opt/stacks/core/authelia/configuration.yml:/config/configuration.yml:ro
|
|
||||||
- /opt/stacks/core/authelia/users_database.yml:/config/users_database.yml
|
|
||||||
- authelia-data:/config
|
|
||||||
environment:
|
|
||||||
- TZ=${TZ}
|
|
||||||
- AUTHELIA_JWT_SECRET=${AUTHELIA_JWT_SECRET}
|
|
||||||
- AUTHELIA_SESSION_SECRET=${AUTHELIA_SESSION_SECRET}
|
|
||||||
- AUTHELIA_STORAGE_ENCRYPTION_KEY=${AUTHELIA_STORAGE_ENCRYPTION_KEY}
|
|
||||||
- AUTHELIA_NOTIFIER_SMTP_PASSWORD=${SMTP_PASSWORD} # If using email notifications
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.authelia.rule=Host(`auth.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.authelia.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.authelia.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.services.authelia.loadbalancer.server.port=9091"
|
|
||||||
# Authelia middleware for other services
|
|
||||||
- "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.${DOMAIN}"
|
|
||||||
- "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"
|
|
||||||
- "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"
|
|
||||||
depends_on:
|
|
||||||
- traefik
|
|
||||||
|
|
||||||
# Gluetun - VPN client (Surfshark WireGuard)
|
|
||||||
# Routes download clients through VPN for security
|
|
||||||
gluetun:
|
|
||||||
image: qmcgaw/gluetun:latest
|
|
||||||
container_name: gluetun
|
|
||||||
restart: unless-stopped
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
devices:
|
|
||||||
- /dev/net/tun:/dev/net/tun
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "8888:8888/tcp" # HTTP proxy
|
|
||||||
- "8388:8388/tcp" # Shadowsocks
|
|
||||||
- "8388:8388/udp" # Shadowsocks
|
|
||||||
- "8081:8080" # qBittorrent web UI (mapped to 8081 to avoid Traefik conflict)
|
|
||||||
- "6881:6881" # qBittorrent
|
|
||||||
- "6881:6881/udp" # qBittorrent
|
|
||||||
volumes:
|
|
||||||
- /opt/stacks/core/gluetun:/gluetun
|
|
||||||
environment:
|
|
||||||
- VPN_SERVICE_PROVIDER=surfshark
|
|
||||||
- VPN_TYPE=wireguard
|
|
||||||
- WIREGUARD_PRIVATE_KEY=${SURFSHARK_PRIVATE_KEY}
|
|
||||||
- WIREGUARD_ADDRESSES=${SURFSHARK_ADDRESSES}
|
|
||||||
- SERVER_COUNTRIES=${VPN_SERVER_COUNTRIES:-Netherlands}
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=VPN client for secure downloads"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
authelia-data:
|
|
||||||
driver: local
|
|
||||||
|
|
||||||
networks:
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
# Dashboard Services
|
|
||||||
# Homepage and Homarr for homelab dashboards
|
|
||||||
# Place in /opt/stacks/dashboards/docker-compose.yml
|
|
||||||
|
|
||||||
# Service Access URLs:
|
|
||||||
# - Homepage: https://home.${DOMAIN}
|
|
||||||
# - Homarr: https://homarr.${DOMAIN}
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Homepage - Application dashboard (AI-configurable via YAML)
|
|
||||||
# Access at: https://home.${DOMAIN}
|
|
||||||
homepage:
|
|
||||||
image: ghcr.io/gethomepage/homepage:latest
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '0.50'
|
|
||||||
memory: 256M
|
|
||||||
pids: 512
|
|
||||||
reservations:
|
|
||||||
cpus: '0.25'
|
|
||||||
memory: 128M
|
|
||||||
container_name: homepage
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
- dockerproxy-network
|
|
||||||
volumes:
|
|
||||||
- ./homepage:/app/config
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock # For Docker integration do not mount RO
|
|
||||||
- /opt/stacks:/opt/stacks # To discover other stacks
|
|
||||||
environment:
|
|
||||||
- PUID=995 # Must be set to the docker user ID
|
|
||||||
- PGID=995 # Must be set to the docker group ID
|
|
||||||
- TZ=${TZ}
|
|
||||||
- HOMEPAGE_ALLOWED_HOSTS=home.${DOMAIN}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=dashboard"
|
|
||||||
- "homelab.description=Application dashboard (AI-configurable)"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.homepage.rule=Host(`home.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.homepage.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.homepage.tls=true"
|
|
||||||
- "traefik.http.routers.homepage.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.homepage.loadbalancer.server.port=3000"
|
|
||||||
|
|
||||||
# Homarr - Modern dashboard
|
|
||||||
# Access at: https://homarr.${DOMAIN}
|
|
||||||
homarr:
|
|
||||||
image: ghcr.io/ajnart/homarr:latest
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '0.50'
|
|
||||||
memory: 256M
|
|
||||||
pids: 512
|
|
||||||
reservations:
|
|
||||||
cpus: '0.25'
|
|
||||||
memory: 128M
|
|
||||||
container_name: homarr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./homarr/config:/app/config/configs
|
|
||||||
- ./homarr/data:/data
|
|
||||||
- ./homarr/icons:/app/public/icons
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
environment:
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=dashboard"
|
|
||||||
- "homelab.description=Modern homelab dashboard"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.homarr.rule=Host(`homarr.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.homarr.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.homarr.tls=true"
|
|
||||||
- "traefik.http.routers.homarr.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.homarr.loadbalancer.server.port=7575"
|
|
||||||
- "x-dockge.url=https://homarr.${DOMAIN}"
|
|
||||||
- "x-dockge.url=https://homarr.${DOMAIN}"
|
|
||||||
|
|
||||||
networks:
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
dockerproxy-network:
|
|
||||||
external: true
|
|
||||||
@@ -1,267 +0,0 @@
|
|||||||
# Infrastructure Services
|
|
||||||
# Core services that other services depend on
|
|
||||||
# Place in /opt/stacks/infrastructure/docker-compose.yml
|
|
||||||
# NOTE: Traefik, Authelia, DuckDNS, and Gluetun have their own separate stacks
|
|
||||||
# See /opt/stacks/traefik/, /opt/stacks/authelia/, etc.
|
|
||||||
|
|
||||||
# Service Access URLs:
|
|
||||||
# - Dockge: https://dockge.${DOMAIN}
|
|
||||||
# - Portainer: https://portainer.${DOMAIN}
|
|
||||||
# - Pi-hole: https://pihole.${DOMAIN}
|
|
||||||
# - Dozzle: https://dozzle.${DOMAIN}
|
|
||||||
# - Glances: https://glances.${DOMAIN}
|
|
||||||
# - Netdata: https://netdata.${DOMAIN}
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Dockge - Docker Compose Stack Manager (PRIMARY - preferred over Portainer)
|
|
||||||
# Access at: https://dockge.${DOMAIN}
|
|
||||||
dockge:
|
|
||||||
image: louislam/dockge:1
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '0.50'
|
|
||||||
memory: 256M
|
|
||||||
pids: 512
|
|
||||||
reservations:
|
|
||||||
cpus: '0.25'
|
|
||||||
memory: 128M
|
|
||||||
container_name: dockge
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "5001:5001" # Optional: direct access
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
- /opt/stacks:/opt/stacks # Dockge manages stacks in this directory
|
|
||||||
- /opt/dockge/data:/app/data
|
|
||||||
environment:
|
|
||||||
- DOCKGE_STACKS_DIR=/opt/stacks
|
|
||||||
- DOCKGE_ENABLE_CONSOLE=true
|
|
||||||
# Proxy Authentication for SSO integration with Authelia
|
|
||||||
- DOCKGE_AUTH_PROXY_HEADER=Remote-User
|
|
||||||
- DOCKGE_AUTH_PROXY_AUTO_CREATE=true
|
|
||||||
- DOCKGE_AUTH_PROXY_LOGOUT_URL=https://auth.${DOMAIN}/logout
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=Docker Compose stack manager (PRIMARY)"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.dockge.rule=Host(`dockge.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.dockge.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.dockge.tls=true"
|
|
||||||
- "traefik.http.routers.dockge.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.dockge.loadbalancer.server.port=5001"
|
|
||||||
- "x-dockge.url=https://dockge.${DOMAIN}"
|
|
||||||
- "x-dockge.url=https://dockge.${DOMAIN}"
|
|
||||||
|
|
||||||
# Pi-hole - Network-wide ad blocker and DNS server
|
|
||||||
# Access at: https://pihole.${DOMAIN}
|
|
||||||
pihole:
|
|
||||||
image: pihole/pihole:2024.01.0
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '0.25'
|
|
||||||
memory: 128M
|
|
||||||
pids: 256
|
|
||||||
reservations:
|
|
||||||
cpus: '0.10'
|
|
||||||
memory: 64M
|
|
||||||
container_name: pihole
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "53:53/tcp" # DNS TCP
|
|
||||||
- "53:53/udp" # DNS UDP
|
|
||||||
volumes:
|
|
||||||
- ./pihole/etc-pihole:/etc/pihole
|
|
||||||
- ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d
|
|
||||||
environment:
|
|
||||||
- TZ=${TZ:-America/New_York}
|
|
||||||
- WEBPASSWORD=${PIHOLE_PASSWORD:-changeme}
|
|
||||||
- FTLCONF_LOCAL_IPV4=${SERVER_IP}
|
|
||||||
dns:
|
|
||||||
- 127.0.0.1
|
|
||||||
- 1.1.1.1
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=Network-wide ad blocking and DNS"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.pihole.rule=Host(`pihole.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.pihole.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.pihole.tls=true"
|
|
||||||
- "traefik.http.routers.pihole.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.pihole.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.pihole.loadbalancer.server.port=80"
|
|
||||||
|
|
||||||
# Watchtower - Automatic container updates
|
|
||||||
# TEMPORARILY DISABLED: Docker API version incompatibility with Docker 29.x
|
|
||||||
# Watchtower versions have API compatibility issues:
|
|
||||||
# - v1.7.1: Uses API v1.25 (too old for Docker 29.x which requires min v1.44)
|
|
||||||
# - v1.7.2+/latest: Has issues with API negotiation
|
|
||||||
# Issue tracked for resolution in future release
|
|
||||||
# To enable: Uncomment service below and run: docker compose up -d watchtower
|
|
||||||
#
|
|
||||||
# Watchtower - Automatic container updates
|
|
||||||
# Monitors and updates Docker containers to latest versions
|
|
||||||
# Runs daily at 4 AM
|
|
||||||
watchtower:
|
|
||||||
image: containrrr/watchtower:latest
|
|
||||||
container_name: watchtower
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
environment:
|
|
||||||
- DOCKER_API_VERSION=1.52
|
|
||||||
- WATCHTOWER_CLEANUP=true
|
|
||||||
- WATCHTOWER_INCLUDE_RESTARTING=true
|
|
||||||
- WATCHTOWER_SCHEDULE=0 0 4 * * * # 4 AM daily
|
|
||||||
- WATCHTOWER_NOTIFICATIONS=shoutrrr
|
|
||||||
- WATCHTOWER_NOTIFICATION_URL=${WATCHTOWER_NOTIFICATION_URL:-}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=Automatic Docker container updates"
|
|
||||||
|
|
||||||
# Dozzle - Real-time Docker log viewer
|
|
||||||
# Access at: https://dozzle.${DOMAIN}
|
|
||||||
dozzle:
|
|
||||||
image: amir20/dozzle:latest
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '0.50'
|
|
||||||
memory: 256M
|
|
||||||
pids: 512
|
|
||||||
reservations:
|
|
||||||
cpus: '0.25'
|
|
||||||
memory: 128M
|
|
||||||
container_name: dozzle
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
environment:
|
|
||||||
- DOZZLE_LEVEL=info
|
|
||||||
- DOZZLE_TAILSIZE=300
|
|
||||||
- DOZZLE_FILTER=status=running
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=Real-time Docker log viewer"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.dozzle.rule=Host(`dozzle.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.dozzle.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.dozzle.tls=true"
|
|
||||||
- "traefik.http.routers.dozzle.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.dozzle.loadbalancer.server.port=8080"
|
|
||||||
|
|
||||||
# Docker Proxy - Socket proxy for security
|
|
||||||
# Used by services that need Docker socket access
|
|
||||||
dockerproxy:
|
|
||||||
image: tecnativa/docker-socket-proxy:latest
|
|
||||||
container_name: dockerproxy
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- dockerproxy-network
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:2375:2375"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
environment:
|
|
||||||
- CONTAINERS=1
|
|
||||||
- SERVICES=1
|
|
||||||
- TASKS=1
|
|
||||||
- NETWORKS=1
|
|
||||||
- NODES=1
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=Docker socket proxy for security"
|
|
||||||
|
|
||||||
# Glances - System monitoring
|
|
||||||
# Access at: https://glances.${DOMAIN}
|
|
||||||
glances:
|
|
||||||
image: nicolargo/glances:latest-full
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '0.50'
|
|
||||||
memory: 256M
|
|
||||||
pids: 512
|
|
||||||
reservations:
|
|
||||||
cpus: '0.25'
|
|
||||||
memory: 128M
|
|
||||||
container_name: glances
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
pid: host
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
- ./glances/config:/glances/conf
|
|
||||||
environment:
|
|
||||||
- GLANCES_OPT=-w
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=System and Docker monitoring"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.glances.rule=Host(`glances.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.glances.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.glances.tls=true"
|
|
||||||
- "traefik.http.routers.glances.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.glances.loadbalancer.server.port=61208"
|
|
||||||
|
|
||||||
# Code Server - VS Code in browser
|
|
||||||
# Access at: https://code.${DOMAIN}
|
|
||||||
code-server:
|
|
||||||
image: lscr.io/linuxserver/code-server:latest
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '1.5'
|
|
||||||
memory: 1G
|
|
||||||
pids: 2048
|
|
||||||
reservations:
|
|
||||||
cpus: '0.75'
|
|
||||||
memory: 512M
|
|
||||||
container_name: code-server
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./code-server/config:/config
|
|
||||||
- /opt/stacks:/opt/stacks # Access to all stacks
|
|
||||||
- /mnt:/mnt:ro # Read-only access to data
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
- PASSWORD=${CODE_SERVER_PASSWORD}
|
|
||||||
- SUDO_PASSWORD=${CODE_SERVER_SUDO_PASSWORD}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=infrastructure"
|
|
||||||
- "homelab.description=VS Code in browser"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.code-server.rule=Host(`code.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.code-server.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.code-server.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.code-server.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.code-server.loadbalancer.server.port=8443"
|
|
||||||
|
|
||||||
networks:
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
dockerproxy-network:
|
|
||||||
external: true
|
|
||||||
@@ -1,341 +0,0 @@
|
|||||||
# Media Management Services
|
|
||||||
# Content automation and library management (*arr apps, transcoders, etc.)
|
|
||||||
# Place in /opt/stacks/media-management/docker-compose.yml
|
|
||||||
|
|
||||||
# Service Access URLs:
|
|
||||||
# - Sonarr: https://sonarr.${DOMAIN}
|
|
||||||
# - Radarr: https://radarr.${DOMAIN}
|
|
||||||
# - Prowlarr: https://prowlarr.${DOMAIN}
|
|
||||||
# - Readarr: https://readarr.${DOMAIN}
|
|
||||||
# - Lidarr: https://lidarr.${DOMAIN}
|
|
||||||
# - LazyLibrarian: https://lazylibrarian.${DOMAIN}
|
|
||||||
# - Mylar3: https://mylar.${DOMAIN}
|
|
||||||
# - Jellyseerr: https://jellyseerr.${DOMAIN}
|
|
||||||
# - Tdarr: https://tdarr.${DOMAIN}
|
|
||||||
# - Unmanic: https://unmanic.${DOMAIN}
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Sonarr - TV show automation
|
|
||||||
# Access at: https://sonarr.yourdomain.duckdns.org
|
|
||||||
sonarr:
|
|
||||||
image: linuxserver/sonarr:4.0.0
|
|
||||||
container_name: sonarr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./sonarr/config:/config
|
|
||||||
- /mnt/media:/media
|
|
||||||
- /mnt/downloads:/downloads # Large downloads on separate drive
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ:-America/New_York}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=TV show management and automation
|
|
||||||
# Traefik labels with Authelia
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.sonarr.rule=Host(`sonarr.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.sonarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.sonarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.sonarr.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.sonarr.loadbalancer.server.port=8989
|
|
||||||
# Radarr - Movie automation
|
|
||||||
# Access at: https://radarr.yourdomain.duckdns.org
|
|
||||||
radarr:
|
|
||||||
image: linuxserver/radarr:5.2.6
|
|
||||||
container_name: radarr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./radarr/config:/config
|
|
||||||
- /mnt/media:/media
|
|
||||||
- /mnt/downloads:/downloads # Large downloads on separate drive
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ:-America/New_York}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Movie management and automation
|
|
||||||
# Traefik labels with Authelia
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.radarr.rule=Host(`radarr.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.radarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.radarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.radarr.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.radarr.loadbalancer.server.port=7878
|
|
||||||
# Prowlarr - Indexer manager
|
|
||||||
# Access at: https://prowlarr.yourdomain.duckdns.org
|
|
||||||
prowlarr:
|
|
||||||
image: linuxserver/prowlarr:1.11.4
|
|
||||||
container_name: prowlarr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./prowlarr/config:/config
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ:-America/New_York}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Indexer manager for Sonarr/Radarr
|
|
||||||
# Traefik labels with Authelia
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.prowlarr.rule=Host(`prowlarr.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.prowlarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.prowlarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.prowlarr.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.prowlarr.loadbalancer.server.port=9696
|
|
||||||
# Readarr - Ebook and audiobook management
|
|
||||||
# Access at: https://readarr.${DOMAIN}
|
|
||||||
readarr:
|
|
||||||
image: linuxserver/readarr:0.4.19-nightly
|
|
||||||
container_name: readarr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./readarr/config:/config
|
|
||||||
- /mnt/media/books:/books
|
|
||||||
- /mnt/downloads:/downloads
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Ebook and audiobook management
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.readarr.rule=Host(`readarr.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.readarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.readarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.readarr.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.readarr.loadbalancer.server.port=8787
|
|
||||||
# Lidarr - Music collection manager
|
|
||||||
# Access at: https://lidarr.${DOMAIN}
|
|
||||||
lidarr:
|
|
||||||
image: linuxserver/lidarr:2.0.7
|
|
||||||
container_name: lidarr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./lidarr/config:/config
|
|
||||||
- /mnt/media/music:/music
|
|
||||||
- /mnt/downloads:/downloads
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Music collection manager
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.lidarr.rule=Host(`lidarr.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.lidarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.lidarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.lidarr.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.lidarr.loadbalancer.server.port=8686
|
|
||||||
# Lazy Librarian - Book manager
|
|
||||||
# Access at: https://lazylibrarian.${DOMAIN}
|
|
||||||
lazylibrarian:
|
|
||||||
image: linuxserver/lazylibrarian:latest
|
|
||||||
container_name: lazylibrarian
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./lazylibrarian/config:/config
|
|
||||||
- /mnt/media/books:/books
|
|
||||||
- /mnt/downloads:/downloads
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
- DOCKER_MODS=linuxserver/mods:lazylibrarian-ffmpeg
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Book download automation
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.lazylibrarian.rule=Host(`lazylibrarian.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.lazylibrarian.entrypoints=websecure
|
|
||||||
- traefik.http.routers.lazylibrarian.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.lazylibrarian.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.lazylibrarian.loadbalancer.server.port=5299
|
|
||||||
# Mylar3 - Comic book manager
|
|
||||||
# Access at: https://mylar.${DOMAIN}
|
|
||||||
mylar3:
|
|
||||||
image: linuxserver/mylar3:latest
|
|
||||||
container_name: mylar3
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./mylar3/config:/config
|
|
||||||
- /mnt/media/comics:/comics
|
|
||||||
- /mnt/downloads:/downloads
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Comic book collection manager
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.mylar.rule=Host(`mylar.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.mylar.entrypoints=websecure
|
|
||||||
- traefik.http.routers.mylar.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.mylar.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.mylar.loadbalancer.server.port=8090
|
|
||||||
# Jellyseerr - Request management for Jellyfin/Plex
|
|
||||||
# Access at: https://jellyseerr.${DOMAIN}
|
|
||||||
jellyseerr:
|
|
||||||
image: fallenbagel/jellyseerr:latest
|
|
||||||
container_name: jellyseerr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./jellyseerr/config:/app/config
|
|
||||||
environment:
|
|
||||||
- LOG_LEVEL=info
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Media request management
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.jellyseerr.rule=Host(`jellyseerr.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.jellyseerr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.jellyseerr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.jellyseerr.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.jellyseerr.loadbalancer.server.port=5055
|
|
||||||
- "x-dockge.url=https://jellyseerr.${DOMAIN}"
|
|
||||||
- "x-dockge.url=https://jellyseerr.${DOMAIN}"
|
|
||||||
# FlareSolverr - Cloudflare bypass for Prowlarr
|
|
||||||
# No web UI - used by Prowlarr
|
|
||||||
flaresolverr:
|
|
||||||
image: flaresolverr/flaresolverr:latest
|
|
||||||
container_name: flaresolverr
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
environment:
|
|
||||||
- LOG_LEVEL=info
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Cloudflare bypass for indexers
|
|
||||||
# Tdarr Server - Distributed transcoding server
|
|
||||||
# Access at: https://tdarr.${DOMAIN}
|
|
||||||
tdarr-server:
|
|
||||||
image: ghcr.io/haveagitgat/tdarr:latest
|
|
||||||
container_name: tdarr-server
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- 8266:8266 # Server port
|
|
||||||
volumes:
|
|
||||||
- ./tdarr/server:/app/server
|
|
||||||
- ./tdarr/configs:/app/configs
|
|
||||||
- ./tdarr/logs:/app/logs
|
|
||||||
- /mnt/media:/media
|
|
||||||
- /mnt/tdarr-transcode:/temp # Transcode cache on separate drive
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
- serverIP=0.0.0.0
|
|
||||||
- serverPort=8266
|
|
||||||
- webUIPort=8265
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Distributed transcoding server
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.tdarr.rule=Host(`tdarr.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.tdarr.entrypoints=websecure
|
|
||||||
- traefik.http.routers.tdarr.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.tdarr.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.tdarr.loadbalancer.server.port=8265
|
|
||||||
# Tdarr Node - Transcoding worker
|
|
||||||
# No web UI - controlled by server
|
|
||||||
tdarr-node:
|
|
||||||
image: ghcr.io/haveagitgat/tdarr_node:latest
|
|
||||||
container_name: tdarr-node
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
volumes:
|
|
||||||
- ./tdarr/configs:/app/configs
|
|
||||||
- ./tdarr/logs:/app/logs
|
|
||||||
- /mnt/media:/media
|
|
||||||
- /mnt/tdarr-transcode:/temp
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
- nodeID=MainNode
|
|
||||||
- nodeIP=0.0.0.0
|
|
||||||
- nodePort=8267
|
|
||||||
- serverIP=tdarr-server
|
|
||||||
- serverPort=8266
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Tdarr transcoding worker node
|
|
||||||
# Unmanic - Another transcoding option
|
|
||||||
# Access at: https://unmanic.${DOMAIN}
|
|
||||||
unmanic:
|
|
||||||
image: josh5/unmanic:latest
|
|
||||||
container_name: unmanic
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./unmanic/config:/config
|
|
||||||
- /mnt/media:/library
|
|
||||||
- /mnt/unmanic-cache:/tmp/unmanic # Transcode cache on separate drive
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- homelab.category=media
|
|
||||||
- homelab.description=Library optimization and transcoding
|
|
||||||
- traefik.enable=true
|
|
||||||
- traefik.http.routers.unmanic.rule=Host(`unmanic.${DOMAIN}`)
|
|
||||||
- traefik.http.routers.unmanic.entrypoints=websecure
|
|
||||||
- traefik.http.routers.unmanic.tls.certresolver=letsencrypt
|
|
||||||
- traefik.http.routers.unmanic.middlewares=authelia@docker
|
|
||||||
- traefik.http.services.unmanic.loadbalancer.server.port=8888
|
|
||||||
networks:
|
|
||||||
media-network:
|
|
||||||
external: true
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
# Media Services
|
|
||||||
# Default Services for media management and streaming
|
|
||||||
# Place in /opt/stacks/media/docker-compose.yml
|
|
||||||
|
|
||||||
|
|
||||||
# Service Access URLs:
|
|
||||||
# - Jellyfin: https://jellyfin.${DOMAIN} (no SSO - app access)
|
|
||||||
# - Plex: https://plex.${DOMAIN} (no SSO - app access)
|
|
||||||
# - qBittorrent: https://qbit.${DOMAIN} (routed through Gluetun VPN)
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Jellyfin - Open-source media streaming server
|
|
||||||
# Access at: https://jellyfin.yourdomain.duckdns.org
|
|
||||||
# NOTE: No Authelia - allows app access from Roku, Fire TV, mobile, etc.
|
|
||||||
jellyfin:
|
|
||||||
image: jellyfin/jellyfin:10.8.13
|
|
||||||
container_name: jellyfin
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./jellyfin/config:/config
|
|
||||||
- ./jellyfin/cache:/cache
|
|
||||||
- /mnt/media:/media:ro # Large media files on separate drive
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ:-America/New_York}
|
|
||||||
# Uncomment for hardware transcoding
|
|
||||||
# devices:
|
|
||||||
# - /dev/dri:/dev/dri
|
|
||||||
labels:
|
|
||||||
- "homelab.category=media"
|
|
||||||
- "homelab.description=Open-source media streaming server"
|
|
||||||
# Traefik labels - NO Authelia for app access
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.jellyfin.rule=Host(`jellyfin.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.jellyfin.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.jellyfin.tls=true"
|
|
||||||
- "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
|
|
||||||
- "x-dockge.url=https://jellyfin.${DOMAIN}"
|
|
||||||
- "x-dockge.url=https://jellyfin.${DOMAIN}"
|
|
||||||
|
|
||||||
# Calibre-Web - Ebook reader and server
|
|
||||||
# Access at: https://calibre.${DOMAIN}
|
|
||||||
calibre-web:
|
|
||||||
image: lscr.io/linuxserver/calibre-web:latest
|
|
||||||
container_name: calibre-web
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- media-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./calibre-web/config:/config
|
|
||||||
- /mnt/media/books:/books
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ:-America/New_York}
|
|
||||||
- DOCKER_MODS=linuxserver/mods:universal-calibre
|
|
||||||
labels:
|
|
||||||
- "homelab.category=media"
|
|
||||||
- "homelab.description=Ebook reader and library management"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.calibre.rule=Host(`calibre.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.calibre.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.calibre.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.calibre.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.calibre.loadbalancer.server.port=8083"
|
|
||||||
|
|
||||||
networks:
|
|
||||||
media-network:
|
|
||||||
driver: bridge
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
@@ -1,227 +0,0 @@
|
|||||||
# Monitoring and Observability Services
|
|
||||||
# Services for monitoring your homelab infrastructure
|
|
||||||
# Place in /opt/stacks/monitoring/docker-compose.yml
|
|
||||||
|
|
||||||
# Service Access URLs:
|
|
||||||
# - Prometheus: http://server-ip:9090 (or configure Traefik)
|
|
||||||
# - Grafana: http://server-ip:3000 (or configure Traefik)
|
|
||||||
# - Uptime Kuma: https://status.${DOMAIN}
|
|
||||||
# - Node Exporter: http://server-ip:9100/metrics
|
|
||||||
# - cAdvisor: http://server-ip:8082
|
|
||||||
# - Loki: http://server-ip:3100
|
|
||||||
# NOTE: Prometheus, Grafana, Loki use ports because they need to be accessible to other services
|
|
||||||
# Add Traefik labels if you want https://prometheus.${DOMAIN} access
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Prometheus - Metrics collection and storage
|
|
||||||
# Access at: http://server-ip:9090
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:v2.48.1
|
|
||||||
container_name: prometheus
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitoring-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "9090:9090"
|
|
||||||
volumes:
|
|
||||||
- ./config/prometheus:/etc/prometheus
|
|
||||||
- prometheus-data:/prometheus
|
|
||||||
command:
|
|
||||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
|
||||||
- '--storage.tsdb.path=/prometheus'
|
|
||||||
- '--storage.tsdb.retention.time=30d'
|
|
||||||
- '--web.console.libraries=/etc/prometheus/console_libraries'
|
|
||||||
- '--web.console.templates=/etc/prometheus/consoles'
|
|
||||||
- '--web.enable-lifecycle'
|
|
||||||
user: "${PUID:-1000}:${PGID:-1000}"
|
|
||||||
labels:
|
|
||||||
- "homelab.category=monitoring"
|
|
||||||
- "homelab.description=Metrics collection and time-series database"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.prometheus.rule=Host(`prometheus.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.prometheus.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.prometheus.tls=true"
|
|
||||||
- "traefik.http.routers.prometheus.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.prometheus.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
|
|
||||||
|
|
||||||
# Grafana - Metrics visualization
|
|
||||||
# Access at: http://server-ip:3000
|
|
||||||
# Default credentials: admin / admin (change on first login)
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:10.2.3
|
|
||||||
container_name: grafana
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitoring-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
volumes:
|
|
||||||
- grafana-data:/var/lib/grafana
|
|
||||||
- ./config/grafana/provisioning:/etc/grafana/provisioning
|
|
||||||
environment:
|
|
||||||
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
|
|
||||||
- GF_USERS_ALLOW_SIGN_UP=false
|
|
||||||
- GF_SERVER_ROOT_URL=https://grafana.${DOMAIN}
|
|
||||||
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource,grafana-piechart-panel
|
|
||||||
user: "${PUID:-1000}:${PGID:-1000}"
|
|
||||||
depends_on:
|
|
||||||
- prometheus
|
|
||||||
labels:
|
|
||||||
- "homelab.category=monitoring"
|
|
||||||
- "homelab.description=Metrics visualization and dashboards"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.grafana.rule=Host(`grafana.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.grafana.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.grafana.tls=true"
|
|
||||||
- "traefik.http.routers.grafana.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.grafana.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
|
|
||||||
|
|
||||||
# Node Exporter - Host metrics exporter
|
|
||||||
# Metrics at: http://server-ip:9100/metrics
|
|
||||||
node-exporter:
|
|
||||||
image: prom/node-exporter:v1.7.0
|
|
||||||
container_name: node-exporter
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitoring-network
|
|
||||||
ports:
|
|
||||||
- "9100:9100"
|
|
||||||
volumes:
|
|
||||||
- /proc:/host/proc:ro
|
|
||||||
- /sys:/host/sys:ro
|
|
||||||
- /:/rootfs:ro
|
|
||||||
command:
|
|
||||||
- '--path.procfs=/host/proc'
|
|
||||||
- '--path.rootfs=/rootfs'
|
|
||||||
- '--path.sysfs=/host/sys'
|
|
||||||
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
|
|
||||||
labels:
|
|
||||||
- "homelab.category=monitoring"
|
|
||||||
- "homelab.description=Hardware and OS metrics exporter"
|
|
||||||
|
|
||||||
# cAdvisor - Container metrics exporter
|
|
||||||
# Access at: http://server-ip:8082
|
|
||||||
cadvisor:
|
|
||||||
image: gcr.io/cadvisor/cadvisor:v0.47.2
|
|
||||||
container_name: cadvisor
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitoring-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "8082:8080"
|
|
||||||
volumes:
|
|
||||||
- /:/rootfs:ro
|
|
||||||
- /var/run:/var/run:ro
|
|
||||||
- /sys:/sys:ro
|
|
||||||
- /var/lib/docker:/var/lib/docker:ro
|
|
||||||
- /dev/disk:/dev/disk:ro
|
|
||||||
privileged: true
|
|
||||||
devices:
|
|
||||||
- /dev/kmsg
|
|
||||||
labels:
|
|
||||||
- "homelab.category=monitoring"
|
|
||||||
- "homelab.description=Container metrics and performance monitoring"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.cadvisor.rule=Host(`cadvisor.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.cadvisor.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.cadvisor.tls=true"
|
|
||||||
- "traefik.http.routers.cadvisor.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.cadvisor.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.cadvisor.loadbalancer.server.port=8080"
|
|
||||||
|
|
||||||
# Uptime Kuma - Uptime monitoring
|
|
||||||
# Access at: https://uptime-kuma.${DOMAIN}
|
|
||||||
uptime-kuma:
|
|
||||||
image: louislam/uptime-kuma:1
|
|
||||||
container_name: uptime-kuma
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitoring-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- uptime-kuma-data:/app/data
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
labels:
|
|
||||||
- "homelab.category=monitoring"
|
|
||||||
- "homelab.description=Service uptime monitoring and alerts"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.uptime-kuma.rule=Host(`uptime-kuma.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.uptime-kuma.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.uptime-kuma.tls=true"
|
|
||||||
- "traefik.http.routers.uptime-kuma.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.uptime-kuma.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
|
|
||||||
|
|
||||||
# Loki - Log aggregation
|
|
||||||
# Access at: http://server-ip:3100
|
|
||||||
loki:
|
|
||||||
image: grafana/loki:2.9.3
|
|
||||||
container_name: loki
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitoring-network
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
ports:
|
|
||||||
- "3100:3100"
|
|
||||||
volumes:
|
|
||||||
- ./config/loki:/etc/loki
|
|
||||||
- loki-data:/loki
|
|
||||||
command: -config.file=/etc/loki/loki-config.yml
|
|
||||||
user: "${PUID:-1000}:${PGID:-1000}"
|
|
||||||
labels:
|
|
||||||
- "homelab.category=monitoring"
|
|
||||||
- "homelab.description=Log aggregation system"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.loki.rule=Host(`loki.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.loki.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.loki.tls=true"
|
|
||||||
- "traefik.http.routers.loki.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.loki.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.loki.loadbalancer.server.port=3100"
|
|
||||||
|
|
||||||
# Promtail - Log shipper for Loki
|
|
||||||
# Ships Docker container logs to Loki
|
|
||||||
promtail:
|
|
||||||
image: grafana/promtail:2.9.3
|
|
||||||
container_name: promtail
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- monitoring-network
|
|
||||||
volumes:
|
|
||||||
- ./config/promtail:/etc/promtail
|
|
||||||
- /var/log:/var/log:ro
|
|
||||||
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
|
||||||
command: -config.file=/etc/promtail/promtail-config.yml
|
|
||||||
depends_on:
|
|
||||||
- loki
|
|
||||||
labels:
|
|
||||||
- "homelab.category=monitoring"
|
|
||||||
- "homelab.description=Log collector for Loki"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
prometheus-data:
|
|
||||||
driver: local
|
|
||||||
grafana-data:
|
|
||||||
driver: local
|
|
||||||
uptime-kuma-data:
|
|
||||||
driver: local
|
|
||||||
loki-data:
|
|
||||||
driver: local
|
|
||||||
|
|
||||||
networks:
|
|
||||||
monitoring-network:
|
|
||||||
driver: bridge
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
# Productivity and Content Management Services
|
|
||||||
# Place in /opt/stacks/productivity/docker-compose.yml
|
|
||||||
|
|
||||||
# Service Access URLs:
|
|
||||||
# - Nextcloud: https://nextcloud.${DOMAIN}
|
|
||||||
# - Mealie: https://mealie.${DOMAIN}
|
|
||||||
# - WordPress: https://blog.${DOMAIN}
|
|
||||||
# - Gitea: https://git.${DOMAIN}
|
|
||||||
# - DokuWiki: https://wiki.${DOMAIN}
|
|
||||||
# - BookStack: https://docs.${DOMAIN}
|
|
||||||
# - MediaWiki: https://mediawiki.${DOMAIN}
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Nextcloud - File sync and collaboration
|
|
||||||
# Access at: https://nextcloud.${DOMAIN}
|
|
||||||
nextcloud:
|
|
||||||
image: nextcloud:28
|
|
||||||
container_name: nextcloud
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
- nextcloud-network
|
|
||||||
volumes:
|
|
||||||
- ./nextcloud/html:/var/www/html
|
|
||||||
- /mnt/nextcloud-data:/var/www/html/data # Large data on separate drive
|
|
||||||
environment:
|
|
||||||
- MYSQL_HOST=nextcloud-db
|
|
||||||
- MYSQL_DATABASE=nextcloud
|
|
||||||
- MYSQL_USER=nextcloud
|
|
||||||
- MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
|
|
||||||
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER:-admin}
|
|
||||||
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
|
|
||||||
- NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.${DOMAIN}
|
|
||||||
- TRUSTED_PROXIES=172.18.0.0/16
|
|
||||||
- OVERWRITEPROTOCOL=https
|
|
||||||
- OVERWRITEHOST=nextcloud.${DOMAIN}
|
|
||||||
depends_on:
|
|
||||||
- nextcloud-db
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=File sync and collaboration"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.nextcloud.rule=Host(`nextcloud.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.nextcloud.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.nextcloud.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
|
|
||||||
|
|
||||||
nextcloud-db:
|
|
||||||
image: mariadb:10.11
|
|
||||||
container_name: nextcloud-db
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- nextcloud-network
|
|
||||||
volumes:
|
|
||||||
- nextcloud-db-data:/var/lib/mysql
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD=${NEXTCLOUD_DB_ROOT_PASSWORD}
|
|
||||||
- MYSQL_DATABASE=nextcloud
|
|
||||||
- MYSQL_USER=nextcloud
|
|
||||||
- MYSQL_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
|
|
||||||
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=Nextcloud database"
|
|
||||||
|
|
||||||
# Mealie - Recipe manager
|
|
||||||
# Access at: https://mealie.${DOMAIN}
|
|
||||||
mealie:
|
|
||||||
image: ghcr.io/mealie-recipes/mealie:latest
|
|
||||||
container_name: mealie
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./mealie/data:/app/data
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
- BASE_URL=https://mealie.${DOMAIN}
|
|
||||||
- DB_ENGINE=sqlite
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=Recipe manager and meal planner"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.mealie.rule=Host(`mealie.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.mealie.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.mealie.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.services.mealie.loadbalancer.server.port=9000"
|
|
||||||
# No Authelia - family members should access easily
|
|
||||||
|
|
||||||
# WordPress - Blog/website platform
|
|
||||||
# Access at: https://blog.${DOMAIN}
|
|
||||||
wordpress:
|
|
||||||
image: wordpress:latest
|
|
||||||
container_name: wordpress
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
- wordpress-network
|
|
||||||
volumes:
|
|
||||||
- ./wordpress/html:/var/www/html
|
|
||||||
environment:
|
|
||||||
- WORDPRESS_DB_HOST=wordpress-db
|
|
||||||
- WORDPRESS_DB_USER=wordpress
|
|
||||||
- WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD}
|
|
||||||
- WORDPRESS_DB_NAME=wordpress
|
|
||||||
depends_on:
|
|
||||||
- wordpress-db
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=Blog and website platform"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.wordpress.rule=Host(`wordpress.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.wordpress.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.wordpress.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.services.wordpress.loadbalancer.server.port=80"
|
|
||||||
# No Authelia - public blog
|
|
||||||
|
|
||||||
wordpress-db:
|
|
||||||
image: mariadb:10.11
|
|
||||||
container_name: wordpress-db
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- wordpress-network
|
|
||||||
volumes:
|
|
||||||
- wordpress-db-data:/var/lib/mysql
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD=${WORDPRESS_DB_ROOT_PASSWORD}
|
|
||||||
- MYSQL_DATABASE=wordpress
|
|
||||||
- MYSQL_USER=wordpress
|
|
||||||
- MYSQL_PASSWORD=${WORDPRESS_DB_PASSWORD}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=WordPress database"
|
|
||||||
|
|
||||||
# Gitea - Self-hosted Git service
|
|
||||||
# Access at: https://git.${DOMAIN}
|
|
||||||
gitea:
|
|
||||||
image: gitea/gitea:latest
|
|
||||||
container_name: gitea
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
- gitea-network
|
|
||||||
volumes:
|
|
||||||
- ./gitea/data:/data
|
|
||||||
- /etc/timezone:/etc/timezone:ro
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
environment:
|
|
||||||
- USER_UID=${PUID:-1000}
|
|
||||||
- USER_GID=${PGID:-1000}
|
|
||||||
- GITEA__database__DB_TYPE=postgres
|
|
||||||
- GITEA__database__HOST=gitea-db:5432
|
|
||||||
- GITEA__database__NAME=gitea
|
|
||||||
- GITEA__database__USER=gitea
|
|
||||||
- GITEA__database__PASSWD=${GITEA_DB_PASSWORD}
|
|
||||||
depends_on:
|
|
||||||
- gitea-db
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=Self-hosted Git service"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.gitea.rule=Host(`gitea.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.gitea.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.gitea.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.gitea.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
|
||||||
|
|
||||||
gitea-db:
|
|
||||||
image: postgres:14-alpine
|
|
||||||
container_name: gitea-db
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- gitea-network
|
|
||||||
volumes:
|
|
||||||
- gitea-db-data:/var/lib/postgresql/data
|
|
||||||
environment:
|
|
||||||
- POSTGRES_USER=gitea
|
|
||||||
- POSTGRES_PASSWORD=${GITEA_DB_PASSWORD}
|
|
||||||
- POSTGRES_DB=gitea
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=Gitea database"
|
|
||||||
|
|
||||||
# DokuWiki - Wiki without database
|
|
||||||
# Access at: https://wiki.${DOMAIN}
|
|
||||||
dokuwiki:
|
|
||||||
image: lscr.io/linuxserver/dokuwiki:latest
|
|
||||||
container_name: dokuwiki
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./dokuwiki/config:/config
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=File-based wiki"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.dokuwiki.rule=Host(`dokuwiki.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.dokuwiki.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.dokuwiki.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.dokuwiki.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.dokuwiki.loadbalancer.server.port=80"
|
|
||||||
|
|
||||||
# BookStack - Documentation platform
|
|
||||||
# Access at: https://docs.${DOMAIN}
|
|
||||||
bookstack:
|
|
||||||
image: lscr.io/linuxserver/bookstack:latest
|
|
||||||
container_name: bookstack
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
- bookstack-network
|
|
||||||
volumes:
|
|
||||||
- ./bookstack/config:/config
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- APP_URL=https://bookstack.${DOMAIN}
|
|
||||||
- DB_HOST=bookstack-db
|
|
||||||
- DB_PORT=3306
|
|
||||||
- DB_DATABASE=bookstack
|
|
||||||
- DB_USERNAME=bookstack
|
|
||||||
- DB_PASSWORD=${BOOKSTACK_DB_PASSWORD}
|
|
||||||
- APP_KEY=base64:NsYD8+8MAvtBhK8xw9p8pxQDy4x8aOQi/78M3CsseAw=
|
|
||||||
depends_on:
|
|
||||||
- bookstack-db
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=Documentation and wiki platform"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.bookstack.rule=Host(`bookstack.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.bookstack.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.bookstack.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.bookstack.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.bookstack.loadbalancer.server.port=80"
|
|
||||||
- "x-dockge.url=https://bookstack.${DOMAIN}"
|
|
||||||
- "x-dockge.url=https://bookstack.${DOMAIN}"
|
|
||||||
|
|
||||||
bookstack-db:
|
|
||||||
image: mariadb:10.11
|
|
||||||
container_name: bookstack-db
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- bookstack-network
|
|
||||||
volumes:
|
|
||||||
- bookstack-db-data:/var/lib/mysql
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD=${BOOKSTACK_DB_ROOT_PASSWORD}
|
|
||||||
- MYSQL_DATABASE=bookstack
|
|
||||||
- MYSQL_USER=bookstack
|
|
||||||
- MYSQL_PASSWORD=${BOOKSTACK_DB_PASSWORD}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=BookStack database"
|
|
||||||
|
|
||||||
# MediaWiki - Wiki platform
|
|
||||||
# Access at: https://mediawiki.${DOMAIN}
|
|
||||||
mediawiki:
|
|
||||||
image: mediawiki:latest
|
|
||||||
container_name: mediawiki
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
- mediawiki-network
|
|
||||||
volumes:
|
|
||||||
- ./mediawiki/images:/var/www/html/images
|
|
||||||
- ./mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php
|
|
||||||
environment:
|
|
||||||
- MEDIAWIKI_DB_HOST=mediawiki-db
|
|
||||||
- MEDIAWIKI_DB_NAME=mediawiki
|
|
||||||
- MEDIAWIKI_DB_USER=mediawiki
|
|
||||||
- MEDIAWIKI_DB_PASSWORD=${MEDIAWIKI_DB_PASSWORD}
|
|
||||||
depends_on:
|
|
||||||
- mediawiki-db
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=MediaWiki platform"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.mediawiki.rule=Host(`mediawiki.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.mediawiki.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.mediawiki.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.mediawiki.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.mediawiki.loadbalancer.server.port=80"
|
|
||||||
|
|
||||||
mediawiki-db:
|
|
||||||
image: mariadb:10.11
|
|
||||||
container_name: mediawiki-db
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- mediawiki-network
|
|
||||||
volumes:
|
|
||||||
- mediawiki-db-data:/var/lib/mysql
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD=${MEDIAWIKI_DB_ROOT_PASSWORD}
|
|
||||||
- MYSQL_DATABASE=mediawiki
|
|
||||||
- MYSQL_USER=mediawiki
|
|
||||||
- MYSQL_PASSWORD=${MEDIAWIKI_DB_PASSWORD}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=productivity"
|
|
||||||
- "homelab.description=MediaWiki database"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
nextcloud-db-data:
|
|
||||||
wordpress-db-data:
|
|
||||||
gitea-db-data:
|
|
||||||
bookstack-db-data:
|
|
||||||
mediawiki-db-data:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
nextcloud-network:
|
|
||||||
driver: bridge
|
|
||||||
wordpress-network:
|
|
||||||
driver: bridge
|
|
||||||
gitea-network:
|
|
||||||
driver: bridge
|
|
||||||
bookstack-network:
|
|
||||||
driver: bridge
|
|
||||||
mediawiki-network:
|
|
||||||
driver: bridge
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
# Backup and Utility Services
|
|
||||||
# Place in /opt/stacks/utilities/docker-compose.yml
|
|
||||||
|
|
||||||
# Service Access URLs:
|
|
||||||
# - Backrest: https://backrest.${DOMAIN}
|
|
||||||
# - Duplicati: https://duplicati.${DOMAIN}
|
|
||||||
# - Form.io: https://forms.${DOMAIN}
|
|
||||||
# - Vaultwarden (Bitwarden): https://vault.${DOMAIN}
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Backrest - Backup solution for restic
|
|
||||||
# Access at: https://backrest.${DOMAIN}
|
|
||||||
backrest:
|
|
||||||
image: garethgeorge/backrest:latest
|
|
||||||
container_name: backrest
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./backrest/data:/data
|
|
||||||
- ./backrest/config:/config
|
|
||||||
- /opt/stacks:/opt/stacks:ro # Backup source
|
|
||||||
- /mnt:/mnt:ro # Backup additional drives
|
|
||||||
- backrest-cache:/cache
|
|
||||||
environment:
|
|
||||||
- BACKREST_DATA=/data
|
|
||||||
- BACKREST_CONFIG=/config/config.json
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=utilities"
|
|
||||||
- "homelab.description=Backup management with restic"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.backrest.rule=Host(`backrest.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.backrest.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.backrest.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.backrest.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.backrest.loadbalancer.server.port=9898"
|
|
||||||
- "x-dockge.url=https://backrest.${DOMAIN}"
|
|
||||||
- "x-dockge.url=https://backrest.${DOMAIN}"
|
|
||||||
|
|
||||||
# Duplicati - Backup solution
|
|
||||||
# Access at: https://duplicati.${DOMAIN}
|
|
||||||
duplicati:
|
|
||||||
image: lscr.io/linuxserver/duplicati:2.0.7
|
|
||||||
container_name: duplicati
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./duplicati/config:/config
|
|
||||||
- /opt/stacks:/source/stacks:ro
|
|
||||||
- /mnt:/source/mnt:ro
|
|
||||||
- /mnt/backups:/backups
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID:-1000}
|
|
||||||
- PGID=${PGID:-1000}
|
|
||||||
- TZ=${TZ}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=utilities"
|
|
||||||
- "homelab.description=Backup software with encryption"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.duplicati.rule=Host(`duplicati.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.duplicati.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.duplicati.tls.certresolver=letsencrypt"
|
|
||||||
- "traefik.http.routers.duplicati.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.duplicati.loadbalancer.server.port=8200"
|
|
||||||
|
|
||||||
# Form.io - Form builder (DISABLED - image not available)
|
|
||||||
# Uncomment and configure if formio/formio image becomes available
|
|
||||||
# formio:
|
|
||||||
# image: formio/formio:latest
|
|
||||||
# container_name: formio
|
|
||||||
# restart: unless-stopped
|
|
||||||
# networks:
|
|
||||||
# - homelab-network
|
|
||||||
# - traefik-network
|
|
||||||
# - formio-network
|
|
||||||
# environment:
|
|
||||||
# - MONGO_URL=mongodb://formio-mongo:27017/formio
|
|
||||||
# - JWT_SECRET=${FORMIO_JWT_SECRET}
|
|
||||||
# - DB_SECRET=${FORMIO_DB_SECRET}
|
|
||||||
# depends_on:
|
|
||||||
# - formio-mongo
|
|
||||||
# labels:
|
|
||||||
# - "homelab.category=utilities"
|
|
||||||
# - "homelab.description=Form builder platform"
|
|
||||||
# - "traefik.enable=true"
|
|
||||||
# - "traefik.http.routers.formio.rule=Host(`forms.${DOMAIN}`)"
|
|
||||||
# - "traefik.http.routers.formio.entrypoints=websecure"
|
|
||||||
# - "traefik.http.routers.formio.tls.certresolver=letsencrypt"
|
|
||||||
# - "traefik.http.routers.formio.middlewares=authelia@docker"
|
|
||||||
# - "traefik.http.services.formio.loadbalancer.server.port=3000"
|
|
||||||
|
|
||||||
# formio-mongo:
|
|
||||||
# image: mongo:6.0
|
|
||||||
# container_name: formio-mongo
|
|
||||||
# restart: unless-stopped
|
|
||||||
# networks:
|
|
||||||
# - formio-network
|
|
||||||
# volumes:
|
|
||||||
# - formio-mongo-data:/data/db
|
|
||||||
# labels:
|
|
||||||
# - "homelab.category=utilities"
|
|
||||||
# - "homelab.description=Form.io database"
|
|
||||||
|
|
||||||
# Bitwarden (Vaultwarden) - Password manager
|
|
||||||
# Access at: https://vault.${DOMAIN}
|
|
||||||
# Note: SSO disabled for browser extension and mobile app compatibility
|
|
||||||
vaultwarden:
|
|
||||||
image: vaultwarden/server:1.30.1
|
|
||||||
container_name: vaultwarden
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
- traefik-network
|
|
||||||
volumes:
|
|
||||||
- ./vaultwarden/data:/data
|
|
||||||
environment:
|
|
||||||
- DOMAIN=https://vault.${DOMAIN}
|
|
||||||
- SIGNUPS_ALLOWED=${BITWARDEN_SIGNUPS_ALLOWED:-true}
|
|
||||||
- INVITATIONS_ALLOWED=${BITWARDEN_INVITATIONS_ALLOWED:-true}
|
|
||||||
- ADMIN_TOKEN=${BITWARDEN_ADMIN_TOKEN}
|
|
||||||
# SMTP disabled - uncomment and configure to enable email
|
|
||||||
# - SMTP_HOST=${SMTP_HOST}
|
|
||||||
# - SMTP_FROM=${SMTP_FROM}
|
|
||||||
# - SMTP_PORT=${SMTP_PORT:-587}
|
|
||||||
# - SMTP_SECURITY=${SMTP_SECURITY:-starttls}
|
|
||||||
# - SMTP_USERNAME=${SMTP_USERNAME}
|
|
||||||
# - SMTP_PASSWORD=${SMTP_PASSWORD}
|
|
||||||
labels:
|
|
||||||
- "homelab.category=utilities"
|
|
||||||
- "homelab.description=Self-hosted password manager (Bitwarden)"
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.vaultwarden.rule=Host(`vault.${DOMAIN}`)"
|
|
||||||
- "traefik.http.routers.vaultwarden.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.vaultwarden.tls=true"
|
|
||||||
- "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"
|
|
||||||
# SSO disabled for browser extension and mobile app compatibility
|
|
||||||
# - "traefik.http.routers.vaultwarden.middlewares=authelia@docker"
|
|
||||||
- "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
|
|
||||||
|
|
||||||
# Authelia Redis - Session storage for Authelia
|
|
||||||
# No web UI - backend service
|
|
||||||
authelia-redis:
|
|
||||||
image: redis:7-alpine
|
|
||||||
container_name: authelia-redis
|
|
||||||
restart: unless-stopped
|
|
||||||
networks:
|
|
||||||
- homelab-network
|
|
||||||
volumes:
|
|
||||||
- authelia-redis-data:/data
|
|
||||||
command: redis-server --save 60 1 --loglevel warning
|
|
||||||
labels:
|
|
||||||
- "homelab.category=utilities"
|
|
||||||
- "homelab.description=Session storage for Authelia"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
backrest-cache:
|
|
||||||
formio-mongo-data:
|
|
||||||
authelia-redis-data:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
homelab-network:
|
|
||||||
external: true
|
|
||||||
traefik-network:
|
|
||||||
external: true
|
|
||||||
formio-network:
|
|
||||||
driver: bridge
|
|
||||||
@@ -114,7 +114,7 @@ users:
|
|||||||
```bash
|
```bash
|
||||||
# Deploy core infrastructure
|
# Deploy core infrastructure
|
||||||
sudo mkdir -p /opt/stacks/core
|
sudo mkdir -p /opt/stacks/core
|
||||||
cp docker-compose/core.yml /opt/stacks/core/docker-compose.yml
|
cp docker-compose/core/docker-compose.yml /opt/stacks/core/docker-compose.yml
|
||||||
cp -r config-templates/traefik /opt/stacks/core/
|
cp -r config-templates/traefik /opt/stacks/core/
|
||||||
cp .env /opt/stacks/core/
|
cp .env /opt/stacks/core/
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ docker compose up -d
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo mkdir -p /opt/stacks/infrastructure
|
sudo mkdir -p /opt/stacks/infrastructure
|
||||||
cp docker-compose/infrastructure.yml /opt/stacks/infrastructure/docker-compose.yml
|
cp docker-compose/infrastructure/docker-compose.yml /opt/stacks/infrastructure/docker-compose.yml
|
||||||
cp .env /opt/stacks/infrastructure/
|
cp .env /opt/stacks/infrastructure/
|
||||||
cd /opt/stacks/infrastructure
|
cd /opt/stacks/infrastructure
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
@@ -139,7 +139,7 @@ docker compose up -d
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo mkdir -p /opt/stacks/dashboards
|
sudo mkdir -p /opt/stacks/dashboards
|
||||||
cp docker-compose/dashboards.yml /opt/stacks/dashboards/docker-compose.yml
|
cp docker-compose/dashboards/docker-compose.yml /opt/stacks/dashboards/docker-compose.yml
|
||||||
cp -r config-templates/homepage /opt/stacks/dashboards/
|
cp -r config-templates/homepage /opt/stacks/dashboards/
|
||||||
cp .env /opt/stacks/dashboards/
|
cp .env /opt/stacks/dashboards/
|
||||||
|
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ deploy:
|
|||||||
|
|
||||||
### Create a new stack
|
### Create a new stack
|
||||||
1. Create directory: `mkdir /opt/stacks/new-stack`
|
1. Create directory: `mkdir /opt/stacks/new-stack`
|
||||||
2. Copy compose file: `cp docker-compose/template.yml /opt/stacks/new-stack/docker-compose.yml`
|
2. Copy compose file: `cp docker-compose/core/docker-compose.yml /opt/stacks/new-stack/docker-compose.yml`
|
||||||
3. Copy env: `cp .env /opt/stacks/new-stack/`
|
3. Copy env: `cp .env /opt/stacks/new-stack/`
|
||||||
4. Edit configuration
|
4. Edit configuration
|
||||||
5. Deploy: `cd /opt/stacks/new-stack && docker compose up -d`
|
5. Deploy: `cd /opt/stacks/new-stack && docker compose up -d`
|
||||||
@@ -542,7 +542,7 @@ nano .env
|
|||||||
|
|
||||||
# Deploy core only
|
# Deploy core only
|
||||||
mkdir -p /opt/stacks/core
|
mkdir -p /opt/stacks/core
|
||||||
cp docker-compose/core.yml /opt/stacks/core/docker-compose.yml
|
cp docker-compose/core/docker-compose.yml /opt/stacks/core/docker-compose.yml
|
||||||
cp -r config-templates/traefik /opt/stacks/core/
|
cp -r config-templates/traefik /opt/stacks/core/
|
||||||
cp -r config-templates/authelia /opt/stacks/core/
|
cp -r config-templates/authelia /opt/stacks/core/
|
||||||
cp .env /opt/stacks/core/
|
cp .env /opt/stacks/core/
|
||||||
@@ -554,9 +554,9 @@ cd /opt/stacks/core && docker compose up -d
|
|||||||
# After core is running, deploy all stacks
|
# After core is running, deploy all stacks
|
||||||
# Use Dockge UI at https://dockge.yourdomain.duckdns.org
|
# Use Dockge UI at https://dockge.yourdomain.duckdns.org
|
||||||
# Or deploy manually:
|
# Or deploy manually:
|
||||||
docker compose -f docker-compose/infrastructure.yml up -d
|
cd /opt/stacks/infrastructure && docker compose up -d
|
||||||
docker compose -f docker-compose/dashboards.yml up -d
|
cd /opt/stacks/dashboards && docker compose up -d
|
||||||
docker compose -f docker-compose/media.yml up -d
|
cd /opt/stacks/media && docker compose up -d
|
||||||
# etc.
|
# etc.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ if [ -f "/opt/stacks/core/docker-compose.yml" ]; then
|
|||||||
log_info "Creating backup: docker-compose.yml.backup.$(date +%Y%m%d_%H%M%S)"
|
log_info "Creating backup: docker-compose.yml.backup.$(date +%Y%m%d_%H%M%S)"
|
||||||
cp /opt/stacks/core/docker-compose.yml /opt/stacks/core/docker-compose.yml.backup.$(date +%Y%m%d_%H%M%S)
|
cp /opt/stacks/core/docker-compose.yml /opt/stacks/core/docker-compose.yml.backup.$(date +%Y%m%d_%H%M%S)
|
||||||
fi
|
fi
|
||||||
cp "$REPO_DIR/docker-compose/core.yml" /opt/stacks/core/docker-compose.yml
|
cp "$REPO_DIR/docker-compose/core/docker-compose.yml" /opt/stacks/core/docker-compose.yml
|
||||||
|
|
||||||
if [ -d "/opt/stacks/core/traefik" ]; then
|
if [ -d "/opt/stacks/core/traefik" ]; then
|
||||||
log_warning "Traefik configuration already exists in /opt/stacks/core/"
|
log_warning "Traefik configuration already exists in /opt/stacks/core/"
|
||||||
@@ -178,7 +178,7 @@ log_info " - Docker Proxy (Security)"
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Copy infrastructure stack
|
# Copy infrastructure stack
|
||||||
cp "$REPO_DIR/docker-compose/infrastructure.yml" /opt/stacks/infrastructure/docker-compose.yml
|
cp "$REPO_DIR/docker-compose/infrastructure/docker-compose.yml" /opt/stacks/infrastructure/docker-compose.yml
|
||||||
cp "$REPO_DIR/.env" /opt/stacks/infrastructure/.env
|
cp "$REPO_DIR/.env" /opt/stacks/infrastructure/.env
|
||||||
|
|
||||||
# Deploy infrastructure stack
|
# Deploy infrastructure stack
|
||||||
|
|||||||
Reference in New Issue
Block a user