added nginx to traefik migration changes and docs

This commit is contained in:
rezayaghobi-dev
2026-08-27 12:07:31 +03:30
parent 6f1431ad30
commit 00836e5b7c
36 changed files with 1229 additions and 74 deletions

View File

@@ -1,9 +1,48 @@
# ELK + Fleet — sized for: Phenom II X4, 8GB DDR3, 120GB SSD
#
# Scope right now = what the course has actually covered: Elasticsearch,
# Logstash, Kibana, Fleet Server. Filebeat/auditbeat/metricbeat/packetbeat/
# apm-server are deliberately NOT in here yet — add them as their own
# service blocks (same pattern as elasticsearch/kibana below) when you
# reach that lesson, so you're not paying RAM for services you can't use
# yet.
#
# Services are grouped with Compose "profiles" so you can turn whole
# lesson-chunks on/off without editing this file — just edit
# COMPOSE_PROFILES in .env. Core (elasticsearch + kibana) has no profile,
# so it's always included.
#
# Rough memory budget on this box (no swap):
# elasticsearch ~1.5 GB
# logstash ~0.9 GB
# kibana ~0.9 GB
# fleet-server ~0.4 GB
# ---------------------------------
# total ~3.7 GB (you have ~5.9 GB free right now)
#
# That leaves headroom for Docker/Traefik/host overhead and for the first
# enrolled Elastic Agent once you get there (~0.25-0.3 GB more).
#
# REGISTRY: docker.elastic.co sits behind Amazon CloudFront, which
# geo-blocks a handful of sanctioned countries (confirmed pattern for
# Russia/Belarus, same CloudFront-based mechanism affects Iran) — that's
# what "context deadline exceeded" against docker.elastic.co/v2/ almost
# always means, not a real network fault. These images pull instead from
# Docker Hub (elasticsearch, kibana, logstash under the official
# library/ namespace, elastic-agent under elastic/) — Elastic pushes the
# exact same images there and keeps them current (checked: 8.19.19
# present on all four as of this writing). Different CDN, so it isn't
# guaranteed to be reachable either — test with
# `docker pull elasticsearch:${ELK_VERSION}` before assuming it works.
services:
elasticsearch:
image: elasticsearch:8.19.19
image: elasticsearch:${ELK_VERSION}
container_name: elasticsearch
restart: unless-stopped
environment:
- node.name=elasticsearch
- cluster.name=elk-lab
- discovery.type=single-node
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
- xpack.security.enabled=true
@@ -13,19 +52,37 @@ services:
- ES_JAVA_OPTS=-Xms1g -Xmx1g
mem_limit: 1500m
cpus: 1.5
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es-data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
restart: unless-stopped
- "9200:9200" # keep for now, drop once you trust Traefik routing
networks:
- elk
- web_net
healthcheck:
test: ["CMD-SHELL", "curl -s -u elastic:${ELASTIC_PASSWORD} http://localhost:9200 | grep -q cluster_name"]
interval: 10s
timeout: 10s
retries: 30
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.elasticsearch.rule=Host(`elasticsearch.home.server`)"
- "traefik.http.routers.elasticsearch.entrypoints=websecure"
- "traefik.http.routers.elasticsearch.tls=true"
- "traefik.http.routers.elasticsearch.service=elasticsearch"
- "traefik.http.routers.elasticsearch.middlewares=security-headers@file"
- "traefik.http.routers.elasticsearch-http.rule=Host(`elasticsearch.home.server`)"
- "traefik.http.routers.elasticsearch-http.entrypoints=web"
- "traefik.http.routers.elasticsearch-http.middlewares=redirect-to-https@file"
- "traefik.http.services.elasticsearch.loadbalancer.server.port=9200"
kibana-setup:
image: elasticsearch:8.19.19
image: elasticsearch:${ELK_VERSION}
container_name: kibana-setup
depends_on:
elasticsearch:
@@ -43,13 +100,16 @@ services:
- "Content-Type: application/json"
- "-d"
- "{\"password\":\"${KIBANA_PASSWORD}\"}"
networks:
- elk
kibana:
image: kibana:8.19.19
image: kibana:${ELK_VERSION}
container_name: kibana
depends_on:
kibana-setup:
condition: service_completed_successfully
restart: unless-stopped
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=kibana_system
@@ -57,12 +117,125 @@ services:
- XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=${KIBANA_ENCRYPTION_KEY}
- XPACK_SECURITY_ENCRYPTIONKEY=${KIBANA_ENCRYPTION_KEY}
- XPACK_REPORTING_ENCRYPTIONKEY=${KIBANA_ENCRYPTION_KEY}
- NODE_OPTIONS=--max-old-space-size=1024
mem_limit: 1200m
- XPACK_FLEET_ENABLED=true
- SERVER_PUBLICBASEURL=https://kibana.home.server
- NODE_OPTIONS=--max-old-space-size=896
mem_limit: 900m
cpus: 1
ports:
- "5601:5601"
- "5601:5601" # keep for now
networks:
- elk
- web_net
healthcheck:
test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status | grep -q '\"level\":\"available\"'"]
interval: 10s
timeout: 10s
retries: 30
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.kibana.rule=Host(`kibana.home.server`)"
- "traefik.http.routers.kibana.entrypoints=websecure"
- "traefik.http.routers.kibana.tls=true"
- "traefik.http.routers.kibana.service=kibana"
- "traefik.http.routers.kibana.middlewares=security-headers@file"
- "traefik.http.routers.kibana-http.rule=Host(`kibana.home.server`)"
- "traefik.http.routers.kibana-http.entrypoints=web"
- "traefik.http.routers.kibana-http.middlewares=redirect-to-https@file"
- "traefik.http.services.kibana.loadbalancer.server.port=5601"
logstash:
image: logstash:${ELK_VERSION}
container_name: logstash
profiles: ["logstash"]
depends_on:
elasticsearch:
condition: service_healthy
restart: unless-stopped
environment:
- LS_JAVA_OPTS=-Xms512m -Xmx512m
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
mem_limit: 900m
cpus: 1
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
ports:
- "5044:5044" # beats input
- "9600:9600" # monitoring API
networks:
- elk
healthcheck:
test: ["CMD-SHELL", "curl -s http://localhost:9600 | grep -q ok"]
interval: 10s
timeout: 10s
retries: 30
fleet-server:
image: elastic/elastic-agent:${ELK_VERSION}
container_name: fleet-server
profiles: ["fleet"]
depends_on:
kibana:
condition: service_healthy
restart: unless-stopped
environment:
# No service token here on purpose — the agent bootstraps Fleet
# Server itself (creates the policy, mints its own token) as long
# as it can log into Kibana with real credentials. Without these
# two it silently falls back to elastic/changeme and fails auth.
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
- FLEET_SERVER_ENABLE=true
- FLEET_SERVER_ELASTICSEARCH_HOST=http://elasticsearch:9200
- FLEET_SERVER_INSECURE_HTTP=true
- FLEET_SERVER_HOST=0.0.0.0
- FLEET_SERVER_PORT=8220
- KIBANA_HOST=http://kibana:5601
- KIBANA_FLEET_HOST=http://kibana:5601
mem_limit: 400m
cpus: 0.5
volumes:
- fleet-server-state:/usr/share/elastic-agent/state
ports:
- "8220:8220"
networks:
- elk
- web_net
healthcheck:
test: ["CMD-SHELL", "curl -sf http://127.0.0.1:8220/api/status | grep -q HEALTHY"]
interval: 10s
timeout: 5s
retries: 30
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.fleet.rule=Host(`fleet.home.server`)"
- "traefik.http.routers.fleet.entrypoints=websecure"
- "traefik.http.routers.fleet.tls=true"
- "traefik.http.routers.fleet.service=fleet"
- "traefik.http.routers.fleet.middlewares=security-headers@file"
- "traefik.http.routers.fleet-http.rule=Host(`fleet.home.server`)"
- "traefik.http.routers.fleet-http.entrypoints=web"
- "traefik.http.routers.fleet-http.middlewares=redirect-to-https@file"
- "traefik.http.services.fleet.loadbalancer.server.port=8220"
# --- Next lesson, not started yet ---
# Once you reach filebeat.yml / auditbeat.yml etc, add each beat here as
# its own service (profiles: ["beats"]), same pattern as logstash above:
# mount its .yml under ./<beat-name>/, point ELASTICSEARCH_HOSTNAME etc
# at elasticsearch/kibana over the `elk` network, and give it a named
# volume for its data dir. No Traefik labels needed for beats — they're
# agents, not web UIs.
volumes:
es-data:
fleet-server-state:
networks:
elk:
driver: bridge
web_net:
external: true

View File

@@ -0,0 +1,24 @@
input {
beats {
port => 5044
}
}
filter {
# Add your grok/mutate/etc filters here as you get to that lesson.
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
user => "elastic"
password => "${ELASTICSEARCH_PASSWORD}"
index => "logstash-%{+YYYY.MM.dd}"
}
# Comment this out once you trust the pipeline — it's just here so you
# can see events flowing while you're learning.
stdout {
codec => rubydebug
}
}

View File

@@ -1,18 +1,28 @@
services:
semaphore:
image: semaphoreui/semaphore:latest
container_name: semaphore
ports:
- "3001:3000"
environment:
SEMAPHORE_DB_DIALECT: sqlite
SEMAPHORE_DB_PATH: /var/lib/semaphore/database.db
SEMAPHORE_ADMIN: admin
SEMAPHORE_ADMIN_PASSWORD: rezayaghobi1386
SEMAPHORE_ADMIN_EMAIL: rezay5639@gmail.com
SEMAPHORE_ADMIN_NAME: Admin
SEMAPHORE_SECRET_KEY: cc4b3a5a90d31b963bee48a9dee089472bef5e0461f934db7891fc68161d36f7
dockscope:
image: ghcr.io/manuelr-t/dockscope:latest
container_name: dockscope
volumes:
- ./data:/var/lib/semaphore
- ./playbooks:/playbooks
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.dockscope.rule=Host(`dockscope.home.server`)"
- "traefik.http.routers.dockscope.entrypoints=websecure"
- "traefik.http.routers.dockscope.tls=true"
- "traefik.http.routers.dockscope.service=dockscope"
- "traefik.http.routers.dockscope.middlewares=security-headers@file,dockscope-auth@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.dockscope-http.rule=Host(`dockscope.home.server`)"
- "traefik.http.routers.dockscope-http.entrypoints=web"
- "traefik.http.routers.dockscope-http.middlewares=redirect-to-https@file"
# Internal port
- "traefik.http.services.dockscope.loadbalancer.server.port=4681"
networks:
web_net:
external: true

View File

@@ -2,18 +2,41 @@ services:
filebrowser:
image: filebrowser/filebrowser:latest
container_name: filebrowser
ports:
- "8085:80"
restart: unless-stopped
user: "1000:1000"
ports:
- "8085:80" # keep for now (fallback)
volumes:
- /srv/samba/games:/games
- /mnt/storage:/storage
- /home/rezayaghobi/docker/filebrowser/config:/config
- filebrowser_db:/database
- filebrowser_srv:/srv
restart: unless-stopped
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.filebrowser.rule=Host(`filebrowser.home.server`)"
- "traefik.http.routers.filebrowser.entrypoints=websecure"
- "traefik.http.routers.filebrowser.tls=true"
- "traefik.http.routers.filebrowser.service=filebrowser"
- "traefik.http.routers.filebrowser.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.filebrowser-http.rule=Host(`filebrowser.home.server`)"
- "traefik.http.routers.filebrowser-http.entrypoints=web"
- "traefik.http.routers.filebrowser-http.middlewares=redirect-to-https@file"
# Internal port (Filebrowser listens on 80 inside the container)
- "traefik.http.services.filebrowser.loadbalancer.server.port=80"
volumes:
filebrowser_db:
filebrowser_srv:
networks:
web_net:
external: true

View File

@@ -5,9 +5,7 @@ services:
restart: unless-stopped
hostname: gitlab.local
ports:
- "8929:80"
- "2224:22"
volumes:
- ./config:/etc/gitlab
- ./logs:/var/log/gitlab
@@ -16,10 +14,14 @@ services:
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['monitoring_whitelist'] = ['127.0.0.1', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
external_url 'http://192.168.100.6:8929'
external_url 'https://gitlab.home.server'
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['proxy_set_headers'] = {
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}
gitlab_rails['gitlab_shell_ssh_port'] = 2224
@@ -38,14 +40,52 @@ services:
postgres_exporter['enable'] = false
gitlab_exporter['enable'] = false
# Registry off for now — flip to true later if you want it
registry['enable'] = false
# Registry
registry['enable'] = true
registry_external_url 'https://registry.home.server'
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.home.server"
gitlab_rails['registry_port'] = "443"
registry_nginx['listen_port'] = 5050
registry_nginx['listen_https'] = false
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# --- Web UI ---
- "traefik.http.routers.gitlab.rule=Host(`gitlab.home.server`)"
- "traefik.http.routers.gitlab.entrypoints=websecure"
- "traefik.http.routers.gitlab.tls=true"
- "traefik.http.routers.gitlab.service=gitlab"
- "traefik.http.routers.gitlab.middlewares=security-headers@file"
- "traefik.http.routers.gitlab-http.rule=Host(`gitlab.home.server`)"
- "traefik.http.routers.gitlab-http.entrypoints=web"
- "traefik.http.routers.gitlab-http.service=gitlab"
- "traefik.http.routers.gitlab-http.middlewares=redirect-to-https@file"
- "traefik.http.services.gitlab.loadbalancer.server.port=80"
# --- Container Registry ---
- "traefik.http.routers.registry.rule=Host(`registry.home.server`)"
- "traefik.http.routers.registry.entrypoints=websecure"
- "traefik.http.routers.registry.tls=true"
- "traefik.http.routers.registry.service=registry"
- "traefik.http.routers.registry.middlewares=security-headers@file"
- "traefik.http.routers.registry-http.rule=Host(`registry.home.server`)"
- "traefik.http.routers.registry-http.entrypoints=web"
- "traefik.http.routers.registry-http.service=registry"
- "traefik.http.routers.registry-http.middlewares=redirect-to-https@file"
- "traefik.http.services.registry.loadbalancer.server.port=5050"
gitlab-runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: unless-stopped
ports:
- "9252:9252"
volumes:
- ./runner-config:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
networks:
web_net:
external: true

View File

@@ -17,7 +17,25 @@ services:
- /mnt/storage/films/downloads:/downloads
networks:
- mediastack
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.qbittorrent.rule=Host(`qbittorrent.home.server`)"
- "traefik.http.routers.qbittorrent.entrypoints=websecure"
- "traefik.http.routers.qbittorrent.tls=true"
- "traefik.http.routers.qbittorrent.service=qbittorrent"
- "traefik.http.routers.qbittorrent.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.qbittorrent-http.rule=Host(`qbittorrent.home.server`)"
- "traefik.http.routers.qbittorrent-http.entrypoints=web"
- "traefik.http.routers.qbittorrent-http.middlewares=redirect-to-https@file"
# Internal port (qbittorrent WebUI listens on 8080 inside the container)
- "traefik.http.services.qbittorrent.loadbalancer.server.port=8080"
networks:
mediastack:
external: true
web_net:
external: true

View File

@@ -2,11 +2,12 @@ services:
plex:
image: lscr.io/linuxserver/plex:latest
container_name: plex
restart: unless-stopped
network_mode: host
environment:
- TZ=Asia/Tehran
- PLEX_CLAIM=claim-uRK14oDz86FsyFgNyaBh
volumes:
- /home/rezayaghobi/docker/plex:/config
- /mnt/storage:/media
restart: unless-stopped

View File

@@ -13,7 +13,28 @@ services:
- ./config:/config
networks:
- mediastack
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.prowlarr.rule=Host(`prowlarr.home.server`)"
- "traefik.http.routers.prowlarr.entrypoints=websecure"
- "traefik.http.routers.prowlarr.tls=true"
- "traefik.http.routers.prowlarr.service=prowlarr"
- "traefik.http.routers.prowlarr.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.prowlarr-http.rule=Host(`prowlarr.home.server`)"
- "traefik.http.routers.prowlarr-http.entrypoints=web"
- "traefik.http.routers.prowlarr-http.middlewares=redirect-to-https@file"
# Internal port (prowlarr listens on 9696 inside the container)
- "traefik.http.services.prowlarr.loadbalancer.server.port=9696"
networks:
mediastack:
external: true
web_net:
external: true

View File

@@ -10,13 +10,30 @@ services:
- ./config:/config
- /mnt/storage/films:/media
- /mnt/storage/films/downloads:/downloads
ports:
- 7878:7878
restart: unless-stopped
networks:
- mediastack
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.radarr.rule=Host(`radarr.home.server`)"
- "traefik.http.routers.radarr.entrypoints=websecure"
- "traefik.http.routers.radarr.tls=true"
- "traefik.http.routers.radarr.service=radarr"
- "traefik.http.routers.radarr.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.radarr-http.rule=Host(`radarr.home.server`)"
- "traefik.http.routers.radarr-http.entrypoints=web"
- "traefik.http.routers.radarr-http.middlewares=redirect-to-https@file"
# Internal port (radarr listens on 7878 inside the container)
- "traefik.http.services.radarr.loadbalancer.server.port=7878"
networks:
mediastack:
external: true
web_net:
external: true

View File

@@ -16,7 +16,29 @@ services:
restart: unless-stopped
networks:
- mediastack
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.sonarr.rule=Host(`sonarr.home.server`)"
- "traefik.http.routers.sonarr.entrypoints=websecure"
- "traefik.http.routers.sonarr.tls=true"
- "traefik.http.routers.sonarr.service=sonarr"
- "traefik.http.routers.sonarr.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.sonarr-http.rule=Host(`sonarr.home.server`)"
- "traefik.http.routers.sonarr-http.entrypoints=web"
- "traefik.http.routers.sonarr-http.middlewares=redirect-to-https@file"
# Internal port (Filebrowser listens on 8989 inside the container)
- "traefik.http.services.sonarr.loadbalancer.server.port=8989"
networks:
mediastack:
external: true
web_net:
external: true

View File

@@ -15,10 +15,27 @@ services:
- /mnt/storage/films/downloads:/downloads
- /mnt/storage/adult:/data/whisparr
- /mnt/storage/films/downloads/whisparr:/downloads/whisparr # ADD THIS
networks:
- mediastack
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.whisparr.rule=Host(`whisparr.home.server`)"
- "traefik.http.routers.whisparr.entrypoints=websecure"
- "traefik.http.routers.whisparr.tls=true"
- "traefik.http.routers.whisparr.service=whisparr"
- "traefik.http.routers.whisparr.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.whisparr-http.rule=Host(`whisparr.home.server`)"
- "traefik.http.routers.whisparr-http.entrypoints=web"
- "traefik.http.routers.whisparr-http.middlewares=redirect-to-https@file"
# Internal port (whisparr listens on 6969 inside the container)
- "traefik.http.services.whisparr.loadbalancer.server.port=6969"
networks:
mediastack:
external: true
web_net:
external: true

View File

@@ -3,13 +3,54 @@ services:
image: minio/minio:RELEASE.2024-01-18T22-51-28Z-cpuv1
container_name: minio
restart: unless-stopped
ports:
- "9500:9000"
- "9501:9001"
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: change this
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
MINIO_BROWSER_REDIRECT_URL: https://minio.home.server
volumes:
- ./data:/data
command: server /data --console-address ":9001"
mem_limit: 256m
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# Console
- "traefik.http.routers.minio-console.rule=Host(`minio.home.server`)"
- "traefik.http.routers.minio-console.entrypoints=websecure"
- "traefik.http.routers.minio-console.tls=true"
- "traefik.http.routers.minio-console.service=minio-console"
- "traefik.http.routers.minio-console.middlewares=security-headers@file"
- "traefik.http.services.minio-console.loadbalancer.server.port=9001"
# HTTP -> HTTPS
- "traefik.http.routers.minio-console-http.rule=Host(`minio.home.server`)"
- "traefik.http.routers.minio-console-http.entrypoints=web"
- "traefik.http.routers.minio-console-http.middlewares=redirect-to-https@file"
- "traefik.http.routers.minio-console-http.service=minio-console"
# S3 API
- "traefik.http.routers.minio-api.rule=Host(`s3.home.server`)"
- "traefik.http.routers.minio-api.entrypoints=websecure"
- "traefik.http.routers.minio-api.tls=true"
- "traefik.http.routers.minio-api.service=minio-api"
- "traefik.http.routers.minio-api.middlewares=security-headers@file"
- "traefik.http.services.minio-api.loadbalancer.server.port=9000"
# HTTP -> HTTPS
- "traefik.http.routers.minio-api-http.rule=Host(`s3.home.server`)"
- "traefik.http.routers.minio-api-http.entrypoints=web"
- "traefik.http.routers.minio-api-http.middlewares=redirect-to-https@file"
- "traefik.http.routers.minio-api-http.service=minio-api"
networks:
web_net:
external: true

View File

@@ -4,7 +4,7 @@ services:
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
- "9090:9090" # keep for now
volumes:
- ./prometheus:/etc/prometheus:ro
- ./data/prometheus:/prometheus
@@ -14,18 +14,44 @@ services:
- "--web.enable-lifecycle"
networks:
- monitoring
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.prometheus.rule=Host(`prometheus.home.server`)"
- "traefik.http.routers.prometheus.entrypoints=websecure"
- "traefik.http.routers.prometheus.tls=true"
- "traefik.http.routers.prometheus.service=prometheus"
- "traefik.http.routers.prometheus.middlewares=security-headers@file"
- "traefik.http.routers.prometheus-http.rule=Host(`prometheus.home.server`)"
- "traefik.http.routers.prometheus-http.entrypoints=web"
- "traefik.http.routers.prometheus-http.middlewares=redirect-to-https@file"
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
- "3000:3000" # keep for now
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources:ro
networks:
- monitoring
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.grafana.rule=Host(`grafana.home.server`)"
- "traefik.http.routers.grafana.entrypoints=websecure"
- "traefik.http.routers.grafana.tls=true"
- "traefik.http.routers.grafana.service=grafana"
- "traefik.http.routers.grafana.middlewares=security-headers@file"
- "traefik.http.routers.grafana-http.rule=Host(`grafana.home.server`)"
- "traefik.http.routers.grafana-http.entrypoints=web"
- "traefik.http.routers.grafana-http.middlewares=redirect-to-https@file"
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
node_exporter:
image: prom/node-exporter:latest
@@ -39,13 +65,14 @@ services:
- /:/rootfs:ro
networks:
- monitoring
# no Traefik labels – no web UI needed
cadvisor:
image: ghcr.io/google/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
ports:
- "8080:8080"
- "8080:8080" # keep for now
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
@@ -53,6 +80,19 @@ services:
- /var/lib/docker/:/var/lib/docker:ro
networks:
- monitoring
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.cadvisor.rule=Host(`cadvisor.home.server`)"
- "traefik.http.routers.cadvisor.entrypoints=websecure"
- "traefik.http.routers.cadvisor.tls=true"
- "traefik.http.routers.cadvisor.service=cadvisor"
- "traefik.http.routers.cadvisor.middlewares=security-headers@file"
- "traefik.http.routers.cadvisor-http.rule=Host(`cadvisor.home.server`)"
- "traefik.http.routers.cadvisor-http.entrypoints=web"
- "traefik.http.routers.cadvisor-http.middlewares=redirect-to-https@file"
- "traefik.http.services.cadvisor.loadbalancer.server.port=8080"
loki:
image: grafana/loki:3.7.3
@@ -62,12 +102,25 @@ services:
ports:
- "3100:3100"
volumes:
- ./loki/local-config.yaml:/etc/loki/local-config.yaml:ro
- ./loki/local-config.yaml:/etc/loki/local-config.yaml:ro
- ./data/loki:/loki
mem_limit: 400m
cpus: 1
networks:
- monitoring
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.loki.rule=Host(`loki.home.server`)"
- "traefik.http.routers.loki.entrypoints=websecure"
- "traefik.http.routers.loki.tls=true"
- "traefik.http.routers.loki.service=loki"
- "traefik.http.routers.loki.middlewares=security-headers@file"
- "traefik.http.routers.loki-http.rule=Host(`loki.home.server`)"
- "traefik.http.routers.loki-http.entrypoints=web"
- "traefik.http.routers.loki-http.middlewares=redirect-to-https@file"
- "traefik.http.services.loki.loadbalancer.server.port=3100"
alloy:
image: grafana/alloy:v1.17.1
@@ -91,7 +144,22 @@ services:
- loki
networks:
- monitoring
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.alloy.rule=Host(`alloy.home.server`)"
- "traefik.http.routers.alloy.entrypoints=websecure"
- "traefik.http.routers.alloy.tls=true"
- "traefik.http.routers.alloy.service=alloy"
- "traefik.http.routers.alloy.middlewares=security-headers@file"
- "traefik.http.routers.alloy-http.rule=Host(`alloy.home.server`)"
- "traefik.http.routers.alloy-http.entrypoints=web"
- "traefik.http.routers.alloy-http.middlewares=redirect-to-https@file"
- "traefik.http.services.alloy.loadbalancer.server.port=12345"
networks:
monitoring:
driver: bridge
web_net:
external: true

View File

@@ -36,23 +36,54 @@ services:
DB_POSTGRESDB_USER: ${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
NPM_ADMIN_EMAIL: ${NPM_ADMIN_EMAIL}
NPM_ADMIN_PASSWORD: ${NPM_ADMIN_PASSWORD}
PIHOLE_PASSWORD: ${PIHOLE_PASSWORD}
N8N_BASIC_AUTH_ACTIVE: true
N8N_BLOCK_ENV_ACCESS_IN_NODE: false
N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER}
N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD}
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_SECURE_COOKIE: false
N8N_HOST: ${N8N_HOST}
N8N_HOST: n8n.home.server
N8N_PROTOCOL: https
N8N_PORT: 5678
N8N_PROTOCOL: http
WEBHOOK_URL: https://n8n.home.server/
TZ: ${TZ}
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS router
- "traefik.http.routers.n8n.rule=Host(`n8n.home.server`)"
- "traefik.http.routers.n8n.entrypoints=websecure"
- "traefik.http.routers.n8n.tls=true"
- "traefik.http.routers.n8n.service=n8n"
- "traefik.http.routers.n8n.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.n8n-http.rule=Host(`n8n.home.server`)"
- "traefik.http.routers.n8n-http.entrypoints=web"
- "traefik.http.routers.n8n-http.middlewares=redirect-to-https@file"
# Internal container port
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
ports:
- "5678:5678"
networks:
- default # keep the existing n8n_default (for postgres)
- web_net # new
volumes:
- ./n8n-data:/home/node/.n8n
- /mnt/storage:/mnt/storage
- /mnt/windows-video:/mnt/windows-video
networks:
web_net:
external: true

View File

@@ -10,14 +10,19 @@ services:
- ./projects:/home/openhands/workspace/project
stdin_open: true
tty: true
ollama:
image: ollama/ollama:latest
container_name: ollama
depends_on:
- github-mcp
github-mcp:
image: ghcr.io/github/github-mcp-server:latest
container_name: github-mcp
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ollama-data:/root/.ollama
- "8083:8083"
stdin_open: true
tty: true
environment:
- GITHUB_PERSONAL_ACCESS_TOKEN=${GITHUB_PERSONAL_ACCESS_TOKEN}
volumes:
openhands-data:
ollama-data:

View File

@@ -1 +1 @@
PIHOLE_WEBPASSWORD=change-me
PIHOLE_WEBPASSWORD=CHANGE_ME

View File

@@ -3,11 +3,10 @@ services:
container_name: pihole
image: ghcr.io/pi-hole/pihole:latest
network_mode: host
env_file:
- .env
environment:
TZ: "Asia/Tehran"
WEBPASSWORD: ${PIHOLE_WEBPASSWORD}
FTLCONF_webserver_port: '8082o,[::]:8082o'
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d

View File

@@ -4,7 +4,31 @@ services:
container_name: portainer
restart: unless-stopped
ports:
- "9000:9000"
- "9001:9000" # keep for now (fallback)
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/rezayaghobi/docker/portainer/data:/data
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.portainer.rule=Host(`portainer.home.server`)"
- "traefik.http.routers.portainer.entrypoints=websecure"
- "traefik.http.routers.portainer.tls=true"
- "traefik.http.routers.portainer.service=portainer"
- "traefik.http.routers.portainer.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.portainer-http.rule=Host(`portainer.home.server`)"
- "traefik.http.routers.portainer-http.entrypoints=web"
- "traefik.http.routers.portainer-http.middlewares=redirect-to-https@file"
# Internal port (Portainer listens on 9000 inside the container)
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
networks:
web_net:
external: true

View File

@@ -0,0 +1,3 @@
SEMAPHORE_ADMIN_PASSWORD=CHANGE_ME
SEMAPHORE_ADMIN_EMAIL=your-email@example.com
SEMAPHORE_SECRET_KEY=CHANGE_ME_generate_with_openssl_rand_hex_32

View File

@@ -8,10 +8,32 @@ services:
SEMAPHORE_DB_DIALECT: sqlite
SEMAPHORE_DB_PATH: /var/lib/semaphore/database.db
SEMAPHORE_ADMIN: admin
SEMAPHORE_ADMIN_PASSWORD: choose a passwor or use .env (better )
SEMAPHORE_ADMIN_EMAIL: rezay5639@gmail.com
SEMAPHORE_ADMIN_PASSWORD: ${SEMAPHORE_ADMIN_PASSWORD}
SEMAPHORE_ADMIN_EMAIL: ${SEMAPHORE_ADMIN_EMAIL}
SEMAPHORE_ADMIN_NAME: Admin
SEMAPHORE_SECRET_KEY: <your-long-secret-key>
SEMAPHORE_SECRET_KEY: ${SEMAPHORE_SECRET_KEY}
volumes:
- ./data:/var/lib/semaphore
- ./playbooks:/playbooks
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.semaphore.rule=Host(`semaphore.home.server`)"
- "traefik.http.routers.semaphore.entrypoints=websecure"
- "traefik.http.routers.semaphore.tls=true"
- "traefik.http.routers.semaphore.service=semaphore"
- "traefik.http.routers.semaphore.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.semaphore-http.rule=Host(`semaphore.home.server`)"
- "traefik.http.routers.semaphore-http.entrypoints=web"
- "traefik.http.routers.semaphore-http.middlewares=redirect-to-https@file"
# Internal port (semaphore listens on 3000 inside the container)
- "traefik.http.services.semaphore.loadbalancer.server.port=3000"
restart: unless-stopped
networks:
web_net:
external: true

View File

@@ -6,7 +6,5 @@ services:
volumes:
- /dev:/dev
- /run/udev:/run/udev:ro
ports:
- "8090:8090"
restart: unless-stopped
- ./report:/etc/hdsentinel
restart: unless-stopped

View File

@@ -0,0 +1,134 @@
# Traefik
Self-hosted reverse proxy replacing Nginx Proxy Manager — gives every service a friendly `<service>.home.server` hostname with locally-trusted HTTPS, configured entirely as code.
## Why the migration from Nginx Proxy Manager
NPM works fine, but the switching cost grew as the homelab did. Two things pushed the move:
### 1. Infrastructure as code
NPM's entire configuration lives behind a web UI — proxy hosts, SSL certificates, custom locations, access rules. None of it is version-controlled, exportable, or reproducible. If the container dies and comes back without its data volume, you're rebuilding every proxy host by hand.
Traefik is the opposite: every route, middleware, TLS cert, and entrypoint is defined in YAML files that live in this repo. The compose file, the `dynamic/` configs, the cert files — all version-controlled, all diffable, all reproducible with `docker compose up -d`. This is the same pattern the rest of the homelab already follows (each service is a Compose file in a folder), and Traefik fits that model naturally where NPM didn't.
### 2. Docker daemon auto-discovery
NPM requires you to manually add each proxy host through its web UI — type the domain, point it at the container's IP and port, attach an SSL cert, save. Every new service means another round-trip through the UI.
Traefik talks directly to the Docker daemon and watches for containers with `traefik.enable=true`. Add a few labels to any compose file and Traefik picks up the new route automatically — no UI interaction, no restart, no manual configuration. This means adding a new service to the reverse proxy is a two-line addition to that service's compose file, not a separate step in a different tool.
## How it works
```
traefik/
├── compose.yaml # Traefik container + static config
├── certs/ # Local TLS certificates (mkcert)
│ ├── home.server.crt
│ └── home.server.key
└── dynamic/ # File-based provider — routes, middlewares, TLS
├── tls.yaml # Default TLS cert store
├── middlewares.yaml # HTTPS redirect + security headers
├── pihole.yaml # Pi-hole route
├── plex.yml # Plex route (external host)
├── sentinel.yml # Sentinel route (external host)
└── dockscope-auth.yml # Basic auth middleware for DockScope
```
### Static config (`compose.yaml`)
Traefik's static configuration is passed as command-line flags:
- **Docker provider** — watches the Docker daemon for labeled containers on the `web_net` network
- **File provider** — watches `/dynamic/` for YAML config changes (hot-reloaded, no restart needed)
- **Entrypoints** — `:80` (HTTP) and `:443` (HTTPS)
- **API dashboard** — enabled but not insecure (accessed via its own HTTPS route)
### Dynamic config (`dynamic/`)
Routes and middlewares are defined as YAML files, not labels. This keeps the compose files clean and makes it easy to see all routing rules in one place:
- **`middlewares.yaml`** — shared `redirect-to-https` and `security-headers` middlewares (HSTS, XSS filter, content-type nosniff, SAMEORIGIN framing)
- **`tls.yaml`** — default TLS cert store pointing at the mkcert-generated certificate
- **`pihole.yaml`**, **`plex.yml`**, **`sentinel.yml`** — per-service route definitions for services that can't use Docker labels (host-network or external hosts)
### Services using Docker labels
Most services define their Traefik routes directly in their compose files via labels:
```yaml
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
- "traefik.http.routers.<service>.rule=Host(`<service>.home.server`)"
- "traefik.http.routers.<service>.entrypoints=websecure"
- "traefik.http.routers.<service>.tls=true"
- "traefik.http.routers.<service>.middlewares=security-headers@file"
- "traefik.http.routers.<service>-http.rule=Host(`<service>.home.server`)"
- "traefik.http.routers.<service>-http.entrypoints=web"
- "traefik.http.routers.<service>-http.middlewares=redirect-to-https@file"
- "traefik.http.services.<service>.loadbalancer.server.port=<internal-port>"
```
Services currently fronted by Traefik:
| Service | Hostname | Internal Port |
|---|---|---|
| Prometheus | `prometheus.home.server` | 9090 |
| Grafana | `grafana.home.server` | 3000 |
| cAdvisor | `cadvisor.home.server` | 8080 |
| Loki | `loki.home.server` | 3100 |
| Alloy | `alloy.home.server` | 12345 |
| Pi-hole | `pihole.home.server` | 8082 (host) |
| Portainer | `portainer.home.server` | 9000 |
| n8n | `n8n.home.server` | 5678 |
| Filebrowser | `filebrowser.home.server` | 80 |
| DockScope | `dockscope.home.server` | 4681 |
| Semaphore | `semaphore.home.server` | 3000 |
| MinIO | `minio.home.server` | 9001 |
| Plex | `plex.home.server` | 32400 (external) |
| Sentinel | `sentinel.home.server` | 8088 (external) |
| Vaultwarden | `vaultwarden.home.server` | 80 |
| Traefik Dashboard | `traefik.home.server` | API@internal |
## TLS certificates
Same approach as before — [mkcert](https://github.com/FiloSottile/mkcert) generates a local CA and signs certificates for `*.home.server`. The cert and key live in `certs/` and are mounted read-only into the Traefik container.
Traefik loads the default cert via `dynamic/tls.yaml`:
```yaml
tls:
stores:
default:
defaultCertificate:
certFile: /certs/home.server.crt
keyFile: /certs/home.server.key
```
Adding a new service with a `.home.server` hostname automatically gets the right cert — no per-host certificate assignment needed.
## Adding a new service
1. **If the service is a Docker container on `web_net`** — add Traefik labels to its compose file (copy the pattern from any existing service above)
2. **If the service is host-network or external** — create a new YAML file in `dynamic/` with the router and service definition
3. **Add the hostname to Pi-hole** — so DNS resolves `<service>.home.server` to the server's LAN IP
No restart required — Traefik watches both the Docker daemon and the `dynamic/` directory and picks up changes automatically.
## Network
All Traefik-fronted services join the `web_net` external Docker network. This network must be created before starting Traefik:
```bash
docker network create web_net
```
## Security notes
- The Traefik dashboard is behind its own HTTPS route with security headers — not exposed on the public internet, LAN-only via Pi-hole DNS
- DockScope additionally uses a basicAuth middleware (`dynamic/dockscope-auth.yml`) since it mounts the Docker socket
- All HTTP requests are redirected to HTTPS permanently (301)
- Security headers include HSTS (1 year, includeSubdomains, preload), XSS filter, content-type nosniff, and SAMEORIGIN framing
[← Back to Home](../../docs/Home.md)

View File

@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEQTCCAqmgAwIBAgIQMHgxq9We6lR+AyMJeJHo7DANBgkqhkiG9w0BAQsFADB3
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExJjAkBgNVBAsMHXJlemF5
YWdob2JpQGhvbWVzZXJ2ZXIgKHJlemEpMS0wKwYDVQQDDCRta2NlcnQgcmV6YXlh
Z2hvYmlAaG9tZXNlcnZlciAocmV6YSkwHhcNMjYwODI0MDgzODU5WhcNMjgxMTI0
MDgzODU5WjBRMScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNh
dGUxJjAkBgNVBAsMHXJlemF5YWdob2JpQGhvbWVzZXJ2ZXIgKHJlemEpMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvgzUWThVUpVqdqkoJ8325vsC5Eoe
mNlihoZ+zXenBBpZgvuiMdz+duBGPdWQcXK7DQr0jBXNqx0wt8w4RSg9pBETPNXT
mcRxudzzvKggVVzUqJ6MrODj2NSNCxUL05oR/iH30+pmliCRE3CyjEvlnpcUVdu1
Qwp0LdxC4fR2ZNbWQbRZ3aoQXYwaQ7WaFno9tlyhvhBdh/rtQOMhi6kVdtB8pTGY
Zzc1fSBJsOCqlwyN6jcp/J8jZ3AfCU1fdqZwMXuQd0TbUOv/K1grQ99IkzJu2zKJ
jKomBdD1SZnn+/buUl2KGAl1e/G6/LIDgoKVDjb7y4XNCcZX4oNx7pxPdwIDAQAB
o28wbTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYDVR0j
BBgwFoAUuWL4Syj7LA309BRwMJjRz3eC+FUwJQYDVR0RBB4wHIINKi5ob21lLnNl
cnZlcoILaG9tZS5zZXJ2ZXIwDQYJKoZIhvcNAQELBQADggGBAKmBR+udJASNvgtN
LtQzHcq790hnnVg/O1dbSd0Ah2PSrz/OtYOVMgOTa9WPIYeMjVKVOsRcPlR8lO7O
udJuDUi3QkSQ+hmsqFKqC9Mt9uPg6ozcGNcX8/jC/eTIJKYlQCdI69brehR/R4rd
xQo+1MYv/JUULUy/1Ix6uGs80jNuVGwwEnfTxU0K47FUI7hx5HjR8wHv0cMY3Fb9
tUEJJfWjyuyq+oXB3x8loEEBL7ESQUb0pCKKmtmclerm0ia1X5Sh2Sn+d/Me3RHC
ABh0zwQcmC0j/r4T5ajTr5ZK5jzo+3NTtqpLF0TiKAPioGr+W9sJlw5IZhlIVpN8
UqNrwvUbyiVuNUrl70QabO0G3PFUX/Kfi1tXh+9eletFpz3CBQrrJljOFoXhzVFt
FZGPiQuKkAryDvdMpS5oRnOcgR/hROIkz6ACkECwvvbWE5wb7BX+9NZm39gpNe8r
5Cj1OyF6+HZ+o5NHOKzcj4Ci0/e0m+I4Fh9kG5ZXC5+cX79z/A==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,56 @@
services:
traefik:
image: traefik:v3.7
container_name: traefik
restart: unless-stopped
command:
- --log.level=INFO
# API / dashboard
- --api.dashboard=true
- --api.insecure=false
# Docker provider
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=web_net
- --providers.file.directory=/dynamic
- --providers.file.watch=true
# Entrypoints
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# Health check
- --ping=true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./dynamic:/dynamic:ro
- ./certs:/certs:ro
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# Dashboard HTTPS
- "traefik.http.routers.traefik.rule=Host(`traefik.home.server`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.middlewares=security-headers@file"
# Dashboard HTTP → HTTPS redirect
- "traefik.http.routers.traefik-http.rule=Host(`traefik.home.server`)"
- "traefik.http.routers.traefik-http.entrypoints=web"
- "traefik.http.routers.traefik-http.middlewares=redirect-to-https@file"
networks:
web_net:
external: true

View File

@@ -0,0 +1,7 @@
http:
middlewares:
dockscope-auth:
basicAuth:
users:
# Generate with: htpasswd -nB <username>
- "${DOCKSCOPE_AUTH_USER}:${DOCKSCOPE_AUTH_HASH}"

View File

@@ -0,0 +1,17 @@
http:
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
permanent: true
# Optional but recommended security headers (we can tune later)
security-headers:
headers:
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
customFrameOptionsValue: "SAMEORIGIN"

View File

@@ -0,0 +1,24 @@
http:
routers:
pihole:
rule: "Host(`pihole.home.server`)"
entryPoints:
- websecure
tls: {}
service: pihole
middlewares:
- security-headers@file
pihole-http:
rule: "Host(`pihole.home.server`)"
entryPoints:
- web
service: pihole # ← added (required)
middlewares:
- redirect-to-https@file
services:
pihole:
loadBalancer:
servers:
- url: "http://172.17.0.1:8082"

View File

@@ -0,0 +1,24 @@
http:
routers:
plex:
rule: "Host(`plex.home.server`)"
entryPoints:
- websecure
tls: {}
service: plex
middlewares:
- security-headers@file
plex-http:
rule: "Host(`plex.home.server`)"
entryPoints:
- web
service: plex
middlewares:
- redirect-to-https@file
services:
plex:
loadBalancer:
servers:
- url: "http://192.168.100.6:32400"

View File

@@ -0,0 +1,24 @@
http:
routers:
sentinel:
rule: "Host(`sentinel.home.server`)"
entryPoints:
- websecure
tls: true
service: sentinel
middlewares:
- security-headers@file
sentinel-http:
rule: "Host(`sentinel.home.server`)"
entryPoints:
- web
service: sentinel
middlewares:
- redirect-to-https@file
services:
sentinel:
loadBalancer:
servers:
- url: "http://192.168.100.6:8088"

View File

@@ -0,0 +1,6 @@
tls:
stores:
default:
defaultCertificate:
certFile: /certs/home.server.crt
keyFile: /certs/home.server.key

View File

@@ -0,0 +1,33 @@
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=false # set false after creating your account
volumes:
- ./vw-data:/data
ports:
- "8084:80"
networks:
- web_net
labels:
- "traefik.enable=true"
- "traefik.docker.network=web_net"
# HTTPS
- "traefik.http.routers.vaultwarden.rule=Host(`vaultwarden.home.server`)"
- "traefik.http.routers.vaultwarden.entrypoints=websecure"
- "traefik.http.routers.vaultwarden.tls=true"
- "traefik.http.routers.vaultwarden.service=vaultwarden"
- "traefik.http.routers.vaultwarden.middlewares=security-headers@file"
# HTTP → HTTPS redirect
- "traefik.http.routers.vaultwarden-http.rule=Host(`vaultwarden.home.server`)"
- "traefik.http.routers.vaultwarden-http.entrypoints=web"
- "traefik.http.routers.vaultwarden-http.middlewares=redirect-to-https@file"
# Internal port (vaultwarden listens on 80 inside the container)
- "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
networks:
web_net:
external: true