1006 lines
31 KiB
YAML
1006 lines
31 KiB
YAML
volumes:
|
|
grafana_lib: {}
|
|
|
|
services:
|
|
traefik:
|
|
image: "traefik:v3.6.11"
|
|
container_name: "traefik"
|
|
env_file: .env
|
|
command:
|
|
- "--log.level=INFO"
|
|
- "--api.dashboard=true"
|
|
- "--api.insecure=true"
|
|
- "--providers.docker=true"
|
|
- "--providers.docker.exposedbydefault=false"
|
|
- "--entrypoints.websecure.address=:443"
|
|
- "--entrypoints.websecure.http.middlewares=crowdsec@file"
|
|
- "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
|
|
- "--certificatesresolvers.mytlschallenge.acme.email=rewelacyjny.rower@gmail.com"
|
|
- "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
|
|
- "--accesslog"
|
|
- "--accesslog.filepath=/logs/access.log"
|
|
- "--accesslog.fields.names.StartUTC=drop"
|
|
- "--metrics.prometheus=true"
|
|
- "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0"
|
|
- "--entrypoints.web.address=:80"
|
|
- "--serversTransport.insecureSkipVerify=true"
|
|
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge=true"
|
|
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web"
|
|
- "--providers.file.filename=/etc/traefik/dynamic_conf.yml"
|
|
ports:
|
|
- target: 443
|
|
published: 443
|
|
mode: host
|
|
- target: 8080
|
|
published: 8082
|
|
protocol: tcp
|
|
mode: ingress
|
|
volumes:
|
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
|
- ${PWD}/traefik/letsencrypt:/letsencrypt/
|
|
- ${PWD}/traefik/logs:/logs
|
|
- ${PWD}/traefik/config/dynamic_conf.yml:/etc/traefik/dynamic_conf.yml:ro
|
|
labels:
|
|
- "traefik.port=8080"
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.api.rule=Host(`traefik.sebson.space`)"
|
|
- "traefik.http.routers.api.service=api@internal"
|
|
- "traefik.http.routers.api.middlewares=auth"
|
|
- "traefik.http.middlewares.auth.basicauth.users=seba:$$2y$$05$$nYWLfxVJthoWM3ow7h7KJuy4gcx9vNog9jTyfsgf0qbO0Cul0X0Fy"
|
|
- "traefik.http.routers.api.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.routers.api.entrypoints=websecure"
|
|
restart: always
|
|
depends_on:
|
|
- grafana
|
|
- whoami
|
|
|
|
whoami:
|
|
image: "traefik/whoami"
|
|
env_file: .env
|
|
container_name: "whoami"
|
|
ports:
|
|
- 81:80
|
|
restart: always
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.whoami.rule=Host(`whoami.sebson.space`)"
|
|
- "traefik.http.routers.whoami.entrypoints=websecure"
|
|
- "traefik.http.routers.whoami.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.middlewares.whoami-auth.basicauth.users=seba:$$2y$$05$$nYWLfxVJthoWM3ow7h7KJuy4gcx9vNog9jTyfsgf0qbO0Cul0X0Fy"
|
|
- "traefik.http.routers.whoami.middlewares=whoami-auth"
|
|
|
|
# ============================================
|
|
# MONITORING
|
|
# ============================================
|
|
|
|
grafana:
|
|
image: grafana/grafana:latest
|
|
env_file: .env
|
|
container_name: grafana
|
|
ports:
|
|
- "3001:3000"
|
|
environment:
|
|
GF_INSTALL_PLUGINS: "grafana-piechart-panel"
|
|
GF_SERVER_PROTOCOL: "http"
|
|
GF_SERVER_DOMAIN: "sebson.space"
|
|
GF_SERVER_METRICS_ENABLED: "true"
|
|
GF_SERVER_METRICS_INTERVAL_SECONDS: "10"
|
|
GF_SERVER_ROOT_URL: https://grafana.sebson.space
|
|
GF_FEATURE_TOGGLES_PUBLICDASHBOARDS: "true"
|
|
GF_SECURITY_ADMIN_USER: seba
|
|
GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD}
|
|
INFLUXDB_URI: "http://influxdb:8086"
|
|
INFLUXDB_DB: GRAFANA
|
|
INFLUXDB_USER: seba
|
|
INFLUXDB_USER_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD}
|
|
PROMETHEUS_USER: ${PROMETHEUS_USER}
|
|
PROMETHEUS_PASSWORD: ${PROMETHEUS_PASSWORD}
|
|
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN}
|
|
TELEGRAM_CHAT_ID: ${TELEGRAM_CHAT_ID}
|
|
volumes:
|
|
- grafana_lib:/var/lib/grafana
|
|
- ${PWD}/grafana/etc/grafana/provisioning:/etc/grafana/provisioning/
|
|
restart: unless-stopped
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.grafana.rule=Host(`grafana.sebson.space`)"
|
|
- "traefik.http.routers.grafana.entrypoints=websecure"
|
|
- "traefik.http.routers.grafana.tls.certresolver=mytlschallenge"
|
|
- "com.centurylinklabs.watchtower.enable=true"
|
|
|
|
prometheus:
|
|
image: quay.io/prometheus/prometheus:latest
|
|
user: "1000:1000"
|
|
container_name: prometheus
|
|
env_file: .env
|
|
volumes:
|
|
- ./prometheus/:/etc/prometheus/
|
|
- ./prometheus/hosts:/etc/hosts
|
|
- ./prometheus/storage/:/prometheus/storage/
|
|
networks:
|
|
- default
|
|
command: "--web.config.file=/etc/prometheus/web.yml --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus/storage --storage.tsdb.retention.time=30d --storage.tsdb.retention.size=20GB --web.enable-admin-api"
|
|
ports:
|
|
- 29090:9090
|
|
restart: always
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.prom.rule=Host(`prom.sebson.space`)"
|
|
- "traefik.http.routers.prom.entrypoints=websecure"
|
|
- "traefik.http.routers.prom.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.routers.prom.middlewares=auth"
|
|
|
|
victoriametrics:
|
|
image: victoriametrics/victoria-metrics:latest
|
|
container_name: victoriametrics
|
|
restart: unless-stopped
|
|
command:
|
|
- "-storageDataPath=/storage"
|
|
- "-retentionPeriod=10y"
|
|
- "-httpListenAddr=:8428"
|
|
volumes:
|
|
- ${PWD}/vm_data:/storage
|
|
networks:
|
|
- default
|
|
|
|
pushgateway:
|
|
container_name: prom_push_gateway
|
|
image: prom/pushgateway
|
|
restart: unless-stopped
|
|
ports:
|
|
- "0.0.0.0:9091:9091"
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:9091/-/ready"]
|
|
interval: 15s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
node_exporter:
|
|
image: prom/node-exporter:latest
|
|
container_name: node_exporter
|
|
environment:
|
|
- PUID=${PUID}
|
|
- PGID=${PGID}
|
|
- TZ=Europe/Prague
|
|
command:
|
|
- '--path.rootfs=/host'
|
|
- '--collector.textfile'
|
|
- '--collector.textfile.directory=/var/lib/prometheus/node-exporter/'
|
|
user: "1000:1000"
|
|
network_mode: host
|
|
pid: host
|
|
restart: unless-stopped
|
|
volumes:
|
|
- '/:/host:ro,rslave'
|
|
- '/var/lib/prometheus/node-exporter/:/var/lib/prometheus/node-exporter'
|
|
|
|
cadvisor:
|
|
image: gcr.io/cadvisor/cadvisor:latest
|
|
container_name: cadvisor
|
|
restart: unless-stopped
|
|
privileged: true
|
|
devices:
|
|
- /dev/kmsg
|
|
ports:
|
|
- 38080:8080
|
|
volumes:
|
|
- /:/rootfs:ro
|
|
- /var/run:/var/run:ro
|
|
- /sys:/sys:ro
|
|
- /var/lib/docker/:/var/lib/docker:ro
|
|
- /dev/disk/:/dev/disk:ro
|
|
|
|
side-agent:
|
|
container_name: side-agent
|
|
build:
|
|
context: ./side-agent
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- ${PWD}:/mydocker
|
|
- ${PWD}/side-agent/manifest:/app/manifest
|
|
- /media/evo2t/frigate/clips:/source:ro
|
|
- ${PWD}/homeassistant/config/www/frigate_notification:/target
|
|
restart: unless-stopped
|
|
environment:
|
|
- TZ=${TZ}
|
|
labels:
|
|
- "com.centurylinklabs.watchtower.enable=true"
|
|
|
|
# ============================================
|
|
# PROXIES
|
|
# ============================================
|
|
|
|
adguard-proxy:
|
|
container_name: adguard-proxy
|
|
env_file: .env
|
|
image: marcnuri/port-forward
|
|
environment:
|
|
- TZ=${TZ}
|
|
- REMOTE_HOST=192.168.1.151
|
|
- REMOTE_PORT=80
|
|
restart: always
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.adguard.rule=Host(`adguard.sebson.space`)"
|
|
- "traefik.http.routers.adguard.entrypoints=websecure"
|
|
- "traefik.http.routers.adguard.tls.certresolver=mytlschallenge"
|
|
|
|
# ============================================
|
|
# DATABASE
|
|
# ============================================
|
|
|
|
postgresql18:
|
|
container_name: postgres18
|
|
image: postgres:18
|
|
command: ["postgres", "-c", "ssl=on", "-c", "ssl_cert_file=/etc/postgresql/ssl/server.crt", "-c", "ssl_key_file=/etc/postgresql/ssl/server.key"]
|
|
restart: always
|
|
ports:
|
|
- "5432:5432"
|
|
environment:
|
|
POSTGRES_USER: homeassistant
|
|
POSTGRES_PASSWORD: ${DB_PASS}
|
|
POSTGRES_DB: homeassistant
|
|
volumes:
|
|
- ${PWD}/postgres18/data:/var/lib/postgresql
|
|
- ${PWD}/postgresql-ssl:/etc/postgresql/ssl:ro
|
|
gitea:
|
|
image: gitea/gitea:1.21
|
|
container_name: gitea
|
|
restart: unless-stopped
|
|
environment:
|
|
- USER_UID=1000
|
|
- USER_GID=1000
|
|
- GITEA__database__DB_TYPE=postgres
|
|
- GITEA__database__HOST=postgresql18:5432
|
|
- GITEA__database__NAME=gitea
|
|
- GITEA__database__USER=homeassistant
|
|
- GITEA__database__PASS=${DB_PASS}
|
|
- GITEA__database__SSL_MODE=disable
|
|
volumes:
|
|
- ./gitea:/data
|
|
- /home/seba/git.repos:/import/git.repos:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
ports:
|
|
- "3003:3000"
|
|
- "2222:22"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.gitea.rule=Host(`git.sebson.space`)"
|
|
- "traefik.http.routers.gitea.entrypoints=websecure"
|
|
- "traefik.http.routers.gitea.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
|
depends_on:
|
|
- postgresql18
|
|
|
|
|
|
postgres-exporter:
|
|
image: prometheuscommunity/postgres-exporter
|
|
container_name: postgres-exporter
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- postgresql18
|
|
environment:
|
|
DATA_SOURCE_NAME: "postgresql://${DB_USER}:${DB_PASS}@postgresql18:5432/homeassistant?sslmode=disable"
|
|
|
|
mktxp:
|
|
image: ghcr.io/akpw/mktxp:latest
|
|
container_name: mktxp
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./mktxp:/home/mktxp/mktxp
|
|
|
|
smartctl-exporter:
|
|
image: prometheuscommunity/smartctl-exporter
|
|
container_name: smartctl-exporter
|
|
privileged: true
|
|
user: root
|
|
ports:
|
|
- "9633:9633"
|
|
volumes:
|
|
- /dev:/dev:ro
|
|
command:
|
|
- "--smartctl.interval=60s"
|
|
- "--log.level=error"
|
|
- "--smartctl.device=/dev/disk/by-id/nvme-Apacer_AS2280P4_1TB_AFJK2451200315"
|
|
- "--smartctl.device=/dev/disk/by-id/nvme-Samsung_SSD_970_EVO_Plus_2TB_S4J4NJ0NC05791A"
|
|
- "--smartctl.device=/dev/disk/by-id/ata-WDC_WD10JUCT-63CYNY0_WD-WX71AB72J9YC"
|
|
- "--smartctl.device=/dev/disk/by-id/ata-WDC_WD181PURP-74B6HY0_2JJGDJ0L"
|
|
restart: unless-stopped
|
|
|
|
pgadmin:
|
|
container_name: pgadmin
|
|
image: dpage/pgadmin4:latest
|
|
restart: always
|
|
ports:
|
|
- 9988:80
|
|
environment:
|
|
PGADMIN_DEFAULT_EMAIL: sebastian.blasiak@gmail.com
|
|
PGADMIN_DEFAULT_PASSWORD: ${DB_PASS}
|
|
|
|
# ============================================
|
|
# HOME AUTOMATION
|
|
# ============================================
|
|
|
|
homeassistant:
|
|
container_name: homeassistant
|
|
env_file: .env
|
|
image: ghcr.io/home-assistant/home-assistant:stable
|
|
privileged: true
|
|
devices:
|
|
- /dev/serial/by-id/usb-Nabu_Casa_ZBT-2_DCB4D90CBE78-if00:/dev/ttyACM0
|
|
- /dev/vhci:/dev/vhci
|
|
volumes:
|
|
- ${PWD}/homeassistant/config:/config
|
|
- ${PWD}/homeassistant/resolv.conf:/etc/resolv.conf
|
|
- ${PWD}/homeassistant/sysctl.d:/etc/sysctl.d
|
|
- ${PWD}/homeassistant/ssh_dir:/root/.ssh
|
|
- ${PWD}/homeassistant/doorbell:/doorbell
|
|
- /media/seagata16t/hikvision16t/:/hikvision16t:slave
|
|
- /home/seba/.ssh/id_ed25519:/config/ssh/asus_private_key/id_ed25519:ro
|
|
- /home/seba/.ssh/id_ed25519:/config/ssh/ansible_private_key/id_ed25519:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
- /run/dbus:/run/dbus:ro
|
|
environment:
|
|
- TZ=Europe/Prague
|
|
- GRPC_VERBOSITY=NONE
|
|
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
|
|
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
|
|
restart: unless-stopped
|
|
network_mode: host
|
|
security_opt:
|
|
- apparmor:unconfined
|
|
cap_add:
|
|
- NET_ADMIN
|
|
- NET_RAW
|
|
depends_on:
|
|
- mosquitto
|
|
- esphome
|
|
- frigate
|
|
|
|
homeassistant-external:
|
|
image: traefik/whoami
|
|
container_name: homeassistant-external
|
|
restart: always
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.ha.rule=Host(`ha.sebson.space`)"
|
|
- "traefik.http.routers.ha.entrypoints=websecure"
|
|
- "traefik.http.routers.ha.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.ha.loadbalancer.server.url=http://192.168.1.132:8123"
|
|
- "traefik.http.middlewares.ha-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
|
|
- "traefik.http.routers.ha.middlewares=ha-headers"
|
|
|
|
frigate:
|
|
container_name: frigate
|
|
privileged: true
|
|
restart: unless-stopped
|
|
image: ghcr.io/blakeblackshear/frigate:stable
|
|
shm_size: "1gb"
|
|
devices:
|
|
- /dev/bus/usb:/dev/bus/usb
|
|
volumes:
|
|
- /etc/localtime:/etc/localtime:ro
|
|
- ./frigate:/config
|
|
- /media/evo2t/frigate:/media/frigate
|
|
- type: tmpfs
|
|
target: /tmp/cache
|
|
tmpfs:
|
|
size: 2000000000
|
|
ports:
|
|
- "5000:5000"
|
|
- "8554:8554"
|
|
- "8555:8555"
|
|
- "8971:8971"
|
|
environment:
|
|
- FRIGATE_MERCUSYS_PW=${FRIGATE_MERCUSYS_PW}
|
|
- FRIGATE_MERCUSYS_USER=${FRIGATE_MERCUSYS_USER}
|
|
- FRIGATE_REO_PW=${FRIGATE_REO_PW}
|
|
- FRIGATE_HIK_PW=${FRIGATE_HIK_PW}
|
|
- FRIGATE_DOMOFON_HIK_PW=${FRIGATE_DOMOFON_HIK_PW}
|
|
- MOSQUITTO_PASSWORD=${MOSQUITTO_PASSWORD}
|
|
- FRIGATE_MQTT_PW=${FRIGATE_MQTT_PW}
|
|
- PLUS_API_KEY=${FRIGATE_PLUS_API_KEY}
|
|
- LIBVA_DRIVER_NAME=radeonsi
|
|
- LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "20m"
|
|
max-file: "3"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 6G
|
|
|
|
esphome:
|
|
container_name: esphome
|
|
image: ghcr.io/esphome/esphome
|
|
privileged: true
|
|
network_mode: host
|
|
volumes:
|
|
- ${PWD}/esphome:/config:rw
|
|
restart: unless-stopped
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "20m"
|
|
max-file: "3"
|
|
|
|
mosquitto:
|
|
container_name: mosquitto
|
|
restart: unless-stopped
|
|
image: eclipse-mosquitto:2
|
|
volumes:
|
|
- ${PWD}/mosquitto/config:/mosquitto/config
|
|
- ${PWD}/mosquitto/log:/mosquitto/log
|
|
- ${PWD}/mosquitto/data:/mosquitto/data
|
|
- /etc/localtime:/etc/localtime:ro
|
|
network_mode: host
|
|
environment:
|
|
- TZ=Europe/Prague
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
# ============================================
|
|
# MEDIA
|
|
# ============================================
|
|
|
|
jellyfin:
|
|
container_name: jellyfin
|
|
restart: always
|
|
image: jellyfin/jellyfin:latest
|
|
env_file: .env
|
|
volumes:
|
|
- ${PWD}/jellyfin/config:/config
|
|
- ${PWD}/jellyfin/Downloads/jellyfin_tmp:/cache
|
|
- ${PWD}/jellyfin/shared:/shared
|
|
- /media/seagata16t:/media/seagata16t:slave
|
|
- /media/wd1t:/media/wd1t
|
|
- /media/evo2t:/media/evo2t
|
|
- /media/asustor/asustor_volume1:/media/asustor/asustor_volume1
|
|
ports:
|
|
- "8096:8096/tcp"
|
|
- "8920:8920/tcp"
|
|
- "7359:7359/udp"
|
|
environment:
|
|
- TZ=${TZ}
|
|
- JELLYFIN_PUID=${PUID}
|
|
- JELLYFIN_PGID=${PGID}
|
|
- JELLYFIN_ADVERTISE_IP="http://192.168.1.132:8096/,https://jfin.sebson.space/"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.services.jfin.loadbalancer.server.port=8096"
|
|
- "traefik.http.routers.jfin.rule=Host(`jfin.sebson.space`)"
|
|
- "traefik.http.routers.jfin.entrypoints=websecure"
|
|
- "traefik.http.routers.jfin.tls.certresolver=mytlschallenge"
|
|
|
|
timelapse-maker:
|
|
container_name: timelapse-maker
|
|
build:
|
|
context: ./timelapse_service
|
|
volumes:
|
|
- /media/seagata16t/hikvision16t/:/media/seagata16t/hikvision16t:slave
|
|
- /media/seagata16t/all_timelapses/:/media/seagata16t/all_timelapses:slave
|
|
- /etc/localtime:/etc/localtime:ro
|
|
environment:
|
|
- PUID=${PUID}
|
|
- PGID=${PGID}
|
|
- TZ=Europe/Prague
|
|
restart: always
|
|
|
|
# ============================================
|
|
# UTILITIES
|
|
# ============================================
|
|
|
|
pingexporter:
|
|
image: czerwonk/ping_exporter
|
|
container_name: pingexporter
|
|
environment:
|
|
- PUID=${PUID}
|
|
- PGID=${PGID}
|
|
- TZ=Europe/Prague
|
|
ports:
|
|
- 9427:9427
|
|
volumes:
|
|
- ${PWD}/pingexporter/config:/config:ro
|
|
restart: unless-stopped
|
|
|
|
glances:
|
|
container_name: glances
|
|
image: docker.io/nicolargo/glances
|
|
restart: always
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
ports:
|
|
- 61208:61208
|
|
environment:
|
|
- GLANCES_OPT=-w
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.glances.rule=Host(`glances.sebson.space`)"
|
|
- "traefik.http.routers.glances.entrypoints=websecure"
|
|
- "traefik.http.routers.glances.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.glances.loadbalancer.server.port=61208"
|
|
- "traefik.http.routers.glances.middlewares=auth_glances"
|
|
- "traefik.http.middlewares.auth_glances.basicauth.users=seba:$$2y$$05$$nYWLfxVJthoWM3ow7h7KJuy4gcx9vNog9jTyfsgf0qbO0Cul0X0Fy"
|
|
|
|
brana-frontend:
|
|
build: ./brana-frontend
|
|
container_name: brana-frontend
|
|
restart: unless-stopped
|
|
ports:
|
|
- "9080:80"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.brana.rule=Host(`brana.sebson.space`)"
|
|
- "traefik.http.routers.brana.entrypoints=websecure"
|
|
- "traefik.http.routers.brana.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.brana.loadbalancer.server.port=80"
|
|
networks:
|
|
- default
|
|
|
|
ha-dashboard:
|
|
build: ./ha-dashboard
|
|
container_name: ha-dashboard
|
|
restart: unless-stopped
|
|
ports:
|
|
- "9081:8080"
|
|
environment:
|
|
- DB_HOST=postgres18
|
|
- DB_PORT=5432
|
|
- DB_USER=homeassistant
|
|
- DB_PASS=${DB_PASS}
|
|
- HA_URL=http://${HOST_IP_HA}:8123
|
|
- HA_TOKEN=${HA_TOKEN}
|
|
- SECRET_KEY=${HA_DASHBOARD_SECRET_KEY}
|
|
- AUTH_DIR=/auth
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- ${PWD}/backup.log:/backup.log:ro
|
|
- ${PWD}/ha-dashboard/auth:/auth
|
|
- ${PWD}/ha-dashboard/app.py:/app/app.py:ro
|
|
- ${PWD}/ha-dashboard/templates:/app/templates:ro
|
|
- ${PWD}/ha-dashboard/static:/app/static:ro
|
|
- ${PWD}/homeassistant/config:/ha_config:ro
|
|
- /home/seba/git.repos/myansible:/myansible:ro
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.ha-dashboard.rule=Host(`hadash.sebson.space`)"
|
|
- "traefik.http.routers.ha-dashboard.entrypoints=websecure"
|
|
- "traefik.http.routers.ha-dashboard.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.ha-dashboard.loadbalancer.server.port=8080"
|
|
networks:
|
|
- default
|
|
depends_on:
|
|
- postgresql18
|
|
|
|
bitwarden:
|
|
image: vaultwarden/server
|
|
container_name: bitwarden
|
|
restart: always
|
|
env_file: .env
|
|
ports:
|
|
- '9989:80'
|
|
environment:
|
|
ADMIN_TOKEN: ${ENCRYPTED_BITWARDEN_ADMIN_TOKEN}
|
|
DATABASE_URL: postgresql://homeassistant:${DB_PASS}@192.168.1.132:5432/bitwarden
|
|
YUBICO_CLIENT_ID: ${YUBICO_CLIENT_ID}
|
|
YUBICO_SECRET_KEY: ${YUBICO_SECRET_KEY}
|
|
YUBICO_SERVER: https://bward.sebson.space/wsapi/2.0/verify
|
|
volumes:
|
|
- ./bitwarden:/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.bward.rule=Host(`bward.sebson.space`)"
|
|
- "traefik.http.routers.bward.entrypoints=websecure"
|
|
- "traefik.http.routers.bward.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.bward.loadbalancer.server.port=80"
|
|
|
|
duplicati:
|
|
image: lscr.io/linuxserver/duplicati:latest
|
|
container_name: duplicati
|
|
env_file: .env
|
|
environment:
|
|
- PUID=${PUID}
|
|
- PGID=${PGID}
|
|
- TZ=Europe/Prague
|
|
volumes:
|
|
- /etc/localtime:/etc/localtime:ro
|
|
- /home/seba/git.repos:/git.repos:ro
|
|
- /home/seba/:/seba_home:ro
|
|
- /home/seba/mydocker:/mydocker:ro
|
|
- /media/evo2t/backups:/evo2t:rw
|
|
- type: bind
|
|
source: /media/seagata16t
|
|
target: /backups
|
|
bind:
|
|
propagation: rshared
|
|
- ${PWD}/duplicati/config:/config
|
|
ports:
|
|
- "8200:8200"
|
|
healthcheck:
|
|
test: ["CMD-SHELL","[ -d /backups ] && ls /backups >/dev/null 2>&1 || exit 1"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
restart: unless-stopped
|
|
|
|
openspeedtest:
|
|
image: openspeedtest/latest
|
|
container_name: openspeedtest
|
|
restart: unless-stopped
|
|
ports:
|
|
- "3005:3000"
|
|
- "3006:3001"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.speedtest.rule=Host(`speed.sebson.space`)"
|
|
- "traefik.http.routers.speedtest.entrypoints=websecure"
|
|
- "traefik.http.routers.speedtest.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.speedtest.loadbalancer.server.port=3000"
|
|
|
|
dozzle:
|
|
container_name: dozzle
|
|
image: amir20/dozzle:latest
|
|
restart: unless-stopped
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
ports:
|
|
- 9888:8080
|
|
environment:
|
|
DOZZLE_LEVEL: info
|
|
networks:
|
|
- default
|
|
|
|
# ============================================
|
|
# NETWORKING
|
|
# ============================================
|
|
|
|
unifi:
|
|
image: jacobalberty/unifi:latest
|
|
container_name: unifi
|
|
restart: unless-stopped
|
|
network_mode: host
|
|
environment:
|
|
- TZ=Europe/Warsaw
|
|
- DB_NAME=unifi
|
|
- DB_URI=mongodb://127.0.0.1:27017/unifi
|
|
- STATDB_URI=mongodb://127.0.0.1:27017/unifi_stat
|
|
- UNIFI_UID=1000
|
|
- UNIFI_GID=1000
|
|
volumes:
|
|
- ./unifi-config:/unifi
|
|
depends_on:
|
|
- unifi-db
|
|
|
|
unifi-db:
|
|
image: mongo:7.0
|
|
container_name: unifi-db
|
|
restart: unless-stopped
|
|
network_mode: host
|
|
volumes:
|
|
- ./unifi-db:/data/db
|
|
|
|
# ============================================
|
|
# PHOTO MANAGEMENT
|
|
# ============================================
|
|
|
|
immich-server:
|
|
container_name: immich_server
|
|
image: ghcr.io/immich-app/immich-server:release
|
|
volumes:
|
|
- /media/seagata16t/immich:/usr/src/app/upload:slave
|
|
- /etc/localtime:/etc/localtime:ro
|
|
env_file:
|
|
- .env
|
|
ports:
|
|
- "2283:2283"
|
|
depends_on:
|
|
- redis
|
|
- database
|
|
networks:
|
|
- default
|
|
restart: always
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 6G
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.services.immch.loadbalancer.server.port=2283"
|
|
- "traefik.http.services.immch.loadbalancer.server.scheme=http"
|
|
- "traefik.http.routers.immch.rule=Host(`immch.sebson.space`)"
|
|
- "traefik.http.routers.immch.entrypoints=websecure"
|
|
- "traefik.http.routers.immch.tls.certresolver=mytlschallenge"
|
|
|
|
immich-machine-learning:
|
|
container_name: immich_machine_learning
|
|
image: ghcr.io/immich-app/immich-machine-learning:release
|
|
volumes:
|
|
- ./immich/model-cache:/cache
|
|
env_file:
|
|
- .env
|
|
restart: always
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '2.0'
|
|
memory: 3G
|
|
|
|
redis:
|
|
container_name: immich_redis
|
|
image: redis:7.2-alpine
|
|
restart: always
|
|
|
|
database:
|
|
container_name: immich_postgres
|
|
image: ghcr.io/immich-app/postgres:14-vectorchord0.5.3
|
|
environment:
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_DB: immich
|
|
volumes:
|
|
- ./immich/postgres:/var/lib/postgresql/data
|
|
restart: always
|
|
|
|
# ============================================
|
|
# LOGGING
|
|
# ============================================
|
|
|
|
loki:
|
|
image: grafana/loki:latest
|
|
container_name: loki
|
|
user: "0:0"
|
|
volumes:
|
|
- ./loki/data:/loki
|
|
- ./loki/wal:/wal
|
|
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
|
|
ports:
|
|
- "3100:3100"
|
|
command: -config.file=/etc/loki/local-config.yaml
|
|
restart: unless-stopped
|
|
networks:
|
|
- default
|
|
|
|
promtail:
|
|
image: grafana/promtail:latest
|
|
container_name: promtail
|
|
volumes:
|
|
- /var/log:/var/log:ro
|
|
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
|
- ./promtail/promtail-config.yaml:/etc/promtail/config.yml
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
command: -config.file=/etc/promtail/config.yml
|
|
restart: unless-stopped
|
|
networks:
|
|
- default
|
|
depends_on:
|
|
- loki
|
|
|
|
# ============================================
|
|
# EXTERNAL PROXIES
|
|
# ============================================
|
|
|
|
nextcloud-external:
|
|
image: traefik/whoami
|
|
container_name: nextcloud-external
|
|
restart: always
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.nc-external.rule=Host(`nc.sebson.space`)"
|
|
- "traefik.http.routers.nc-external.entrypoints=websecure"
|
|
- "traefik.http.routers.nc-external.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.nc-external.loadbalancer.server.url=http://192.168.1.10/nextcloud-php/"
|
|
- "traefik.http.routers.nc-external.middlewares=nc-prefix,nc-headers"
|
|
- "traefik.http.middlewares.nc-prefix.addprefix.prefix=/nextcloud-php"
|
|
- "traefik.http.middlewares.nc-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
|
|
- "traefik.http.middlewares.nc-headers.headers.referrerPolicy=same-origin"
|
|
|
|
gotify:
|
|
image: gotify/server
|
|
container_name: gotify
|
|
ports:
|
|
- 8089:80
|
|
environment:
|
|
- GOTIFY_DEFAULTUSER_PASS=${GOTIFY_PASSWORD}
|
|
volumes:
|
|
- "./gotify_data:/app/data"
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.gotify.rule=Host(`gotify.sebson.space`)"
|
|
- "traefik.http.routers.gotify.entrypoints=websecure"
|
|
- "traefik.http.routers.gotify.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.gotify.loadbalancer.server.port=80"
|
|
|
|
# ============================================
|
|
# DOWNLOADERS
|
|
# ============================================
|
|
|
|
# gluetun, qbittorrent, radarr removed — replaced by torrent-box-with-vpn stack
|
|
|
|
prowlarr:
|
|
image: linuxserver/prowlarr
|
|
container_name: prowlarr
|
|
environment:
|
|
- PUID=1000
|
|
- PGID=1000
|
|
- TZ=Europe/Warsaw
|
|
volumes:
|
|
- ./prowlarr:/config
|
|
ports:
|
|
- 9696:9696
|
|
restart: always
|
|
|
|
# ============================================
|
|
# SECURITY
|
|
# ============================================
|
|
|
|
crowdsec:
|
|
image: crowdsecurity/crowdsec:latest
|
|
container_name: crowdsec
|
|
environment:
|
|
- COLLECTIONS=crowdsecurity/linux crowdsecurity/sshd crowdsecurity/traefik crowdsecurity/whitelist-good-actors
|
|
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
|
|
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
|
|
ports:
|
|
- "127.0.0.1:8878:8080"
|
|
- "127.0.0.1:6060:6060"
|
|
volumes:
|
|
- /var/log/auth.log:/var/log/auth.log:ro
|
|
- ./traefik/logs:/var/log/traefik:ro
|
|
- ./crowdsec/conf:/etc/crowdsec
|
|
- ./crowdsec/data:/var/lib/crowdsec/data
|
|
- ./jellyfin/config/log:/var/log/jellyfin:ro
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
restart: unless-stopped
|
|
|
|
traefik-bouncer:
|
|
image: fbonalair/traefik-crowdsec-bouncer:latest
|
|
container_name: traefik-bouncer
|
|
environment:
|
|
- CROWDSEC_BOUNCER_API_KEY=${CROWDSEC_BOUNCER_API_KEY}
|
|
- CROWDSEC_AGENT_HOST=crowdsec:8080
|
|
- GIN_MODE=release
|
|
depends_on:
|
|
- crowdsec
|
|
restart: unless-stopped
|
|
|
|
# ============================================
|
|
# AI / LLM STACK
|
|
# ============================================
|
|
|
|
ollama:
|
|
image: ollama/ollama:latest
|
|
container_name: ollama
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./ollama_data:/root/.ollama
|
|
ports:
|
|
- "11434:11434"
|
|
environment:
|
|
- TZ=${TZ}
|
|
|
|
open-webui:
|
|
image: ghcr.io/open-webui/open-webui:main
|
|
container_name: open-webui
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- ollama
|
|
volumes:
|
|
- ./open-webui_data:/app/backend/data
|
|
ports:
|
|
- "3002:8080"
|
|
environment:
|
|
- TZ=${TZ}
|
|
- OLLAMA_BASE_URL=http://ollama:11434
|
|
- VECTOR_DB=chroma
|
|
- CHROMA_HTTP_HOST=chromadb
|
|
- CHROMA_HTTP_PORT=8000
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.open-webui.rule=Host(`oi.sebson.space`)"
|
|
- "traefik.http.routers.open-webui.entrypoints=websecure"
|
|
- "traefik.http.routers.open-webui.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.open-webui.loadbalancer.server.port=8080"
|
|
|
|
chromadb:
|
|
image: chromadb/chroma:latest
|
|
container_name: chromadb
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./chromadb/data:/chroma/chroma
|
|
ports:
|
|
- "8000:8000"
|
|
environment:
|
|
- TZ=${TZ}
|
|
- IS_PERSISTENT=TRUE
|
|
|
|
log-ingester:
|
|
build:
|
|
context: ./log-ingester
|
|
container_name: log-ingester
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- chromadb
|
|
- ollama
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- ./frigate:/data/frigate:ro
|
|
- ./homeassistant/config:/data/ha:ro
|
|
- ./log-ingester/state:/data/state
|
|
ports:
|
|
- "8765:8765"
|
|
environment:
|
|
- TZ=${TZ}
|
|
- CHROMA_HOST=chromadb
|
|
- CHROMA_PORT=8000
|
|
- OLLAMA_URL=http://ollama:11434
|
|
- FRIGATE_DB=/data/frigate/frigate.db
|
|
- HA_LOG=/data/ha/home-assistant.log
|
|
- STATE_FILE=/data/state/state.json
|
|
- INGEST_INTERVAL=300
|
|
- PG_HOST=postgres18
|
|
- PG_PORT=5432
|
|
- PG_DB=homeassistant
|
|
- PG_USER=${DB_USER}
|
|
- PG_PASS=${DB_PASS}
|
|
|
|
# ============================================
|
|
# HOME ASSISTANT VOICE PIPELINE
|
|
# (disabled — configure when RPi4 satellite is ready)
|
|
# ============================================
|
|
# piper + wyoming-openwakeword: uncomment when setting up voice satellite
|
|
|
|
# ============================================
|
|
# TRANSMISSION VPN (legacy, kept for compatibility)
|
|
# ============================================
|
|
|
|
transmission-vpn:
|
|
image: haugene/transmission-openvpn:latest
|
|
container_name: transmission-vpn
|
|
restart: unless-stopped
|
|
cap_add:
|
|
- NET_ADMIN
|
|
volumes:
|
|
- ./transmission-vpn/transmission-home:/config
|
|
- ./transmission-vpn/completed:/data/completed
|
|
- ./transmission-vpn/incomplete:/data/incomplete
|
|
- ./transmission-vpn/watch:/data/watch
|
|
environment:
|
|
- TZ=${TZ}
|
|
- OPENVPN_PROVIDER=${OPENVPN_PROVIDER}
|
|
- OPENVPN_USERNAME=${NORD_VPN_USERNAME_ID}
|
|
- OPENVPN_PASSWORD=${NORD_VPN_PASSWORD}
|
|
- TRANSMISSION_RATIO_LIMIT_ENABLED=${TRANSMISSION_RATIO_LIMIT_ENABLED}
|
|
- TRANSMISSION_RATIO_LIMIT=${TRANSMISSION_RATIO_LIMIT}
|
|
- TRANSMISSION_SPEED_LIMIT_DOWN_ENABLED=${TRANSMISSION_SPEED_LIMIT_DOWN_ENABLED}
|
|
- TRANSMISSION_SPEED_LIMIT_DOWN=${TRANSMISSION_SPEED_LIMIT_DOWN}
|
|
- TRANSMISSION_SPEED_LIMIT_UP_ENABLED=${TRANSMISSION_SPEED_LIMIT_UP_ENABLED}
|
|
- TRANSMISSION_SPEED_LIMIT_UP=${TRANSMISSION_SPEED_LIMIT_UP}
|
|
- WEBPROXY_ENABLED=false
|
|
- LOCAL_NETWORK=192.168.1.0/24
|
|
ports:
|
|
- "9092:9091"
|
|
sysctls:
|
|
- net.ipv6.conf.all.disable_ipv6=0
|
|
devices:
|
|
- /dev/net/tun
|
|
|
|
uptime-kuma:
|
|
image: louislam/uptime-kuma
|
|
container_name: uptime-kuma
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ${PWD}/uptime-kuma/data:/app/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.uptime-kuma.rule=Host(`kuma.sebson.space`)"
|
|
- "traefik.http.routers.uptime-kuma.entrypoints=websecure"
|
|
- "traefik.http.routers.uptime-kuma.tls.certresolver=mytlschallenge"
|
|
- "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001"
|
|
|