# The following variables should be set in a file named .env in the same directory as docker-compose.yml (alter as needed):
# - CLOUDFLARE_API_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# - TIMEZONE=America/New_York
# - UID=1000
# - GID=1000

version: "3.8"

services:

  # Auth files should be generated with `htpasswd -c $HOME/traefik/conf/$file.auth [username]`
  traefik:
    image: traefik:2.4
    container_name: traefik
    restart: always
    environment:
      - "CF_DNS_API_TOKEN=${CLOUDFLARE_API_TOKEN}"
    command:
      - "--providers.docker=true"
      - "--providers.file.directory=/conf"
      - "--providers.file.watch=true"
      - "--entrypoints.pihole-tcp.address=:53"
      - "--entrypoints.pihole-udp.address=:53/udp"
      - "--entrypoints.http.address=:80"
      - "--entrypoints.https.address=:443"
      - "--entrypoints.mosquitto.address=:1883"
      - "--entrypoints.rtmp.address=:1935"
      - "--entrypoints.unifi-stun.address=:3478/udp"
      - "--entrypoints.sflow.address=:6343/udp"
      - "--entrypoints.syslog.address=:6514"
      - "--entrypoints.torrent-tcp.address=:6881"
      - "--entrypoints.torrent-udp.address=:6881/udp"
      - "--entrypoints.unifi-comms.address=:8080"
      - "--entrypoints.metrics.address=:8082"
      - "--entrypoints.unifi-https.address=:8843"
      - "--entrypoints.unifi-http.address=:8880"
      - "--entrypoints.gitea.address=:9023"
      - "--entrypoints.unifi-discovery.address=:10001/udp"
      - "--entrypoints.syncthing.address=:22000"
      - "--entrypoints.minecraft.address=:25570"
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare"
      - "--certificatesresolvers.letsencrypt.acme.storage=/certs/acme.json"
      - "--accesslog=true"
      - "--log.level=ERROR"
      - "--log.filePath=/var/log/traefik.log"
      - "--metrics.prometheus=true"
      - "--metrics.prometheus.entrypoint=metrics"
      - "--metrics.prometheus.addentrypointslabels=true"
      - "--metrics.prometheus.addserviceslabels=true"
      - "--serverstransport.insecureskipverify=true"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.compress.compress=true"
      - "traefik.http.middlewares.adminauth.basicauth.usersfile=/conf/admin.auth"
      - "traefik.http.middlewares.familyauth.basicauth.usersfile=/conf/family.auth"
      - "traefik.http.middlewares.friendsauth.basicauth.usersfile=/conf/friends.auth"
      - "traefik.http.middlewares.secure.headers.browserxssfilter=true"
      - "traefik.http.middlewares.secure.headers.contenttypenosniff=true"
      - "traefik.http.middlewares.secure.headers.customresponseheaders.Permissions-Policy=geolocation=(), midi=(), sync-xhr=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), fullscreen=(), payment=()"
      - "traefik.http.middlewares.secure.headers.framedeny=true"
      - "traefik.http.middlewares.secure.headers.customframeoptionsvalue=SAMEORIGIN"
      - "traefik.http.middlewares.secure.headers.sslredirect=true"
      - "traefik.http.middlewares.secure.headers.referrerpolicy=strict-origin"
      - "traefik.http.middlewares.secure.headers.forcestsheader=true"
      - "traefik.http.middlewares.secure.headers.stspreload=true"
      - "traefik.http.middlewares.secure.headers.stsincludesubdomains=true"
      - "traefik.http.middlewares.secure.headers.stsseconds=63072000"
      - "traefik.http.middlewares.secure.headers.customresponseheaders.Server=GNU Netcat 0.7.1"
      - "traefik.http.middlewares.secure.headers.customresponseheaders.X-Clacks-Overhead=GNU Terry Pratchett"
      - "traefik.http.middlewares.secure.headers.customresponseheaders.Expect-CT=enforce,max-age=86400"
      - "traefik.http.middlewares.secure.headers.customrequestheaders.X-Forwarded-Proto=https"
    ports:
      - "53:53"
      - "53:53/udp"
      - "80:80"
      - "443:443"
      - "1883:1883"
      - "1935:1935"
      - "3478:3478/udp"
      - "6343:6343/udp"
      - "6514:6514"
      - "6881:6881"
      - "6881:6881/udp"
      - "8080:8080"
      - "8843:8443"
      - "8880:8880"
      - "9023:9023"
      - "10001:10001/udp"
      - "22000:22000"
      - "25570:25570"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
        read_only: true
      - type: volume
        source: traefik
        target: /certs
      - type: bind
        source: /home/sinc/traefik/conf
        target: /conf
        read_only: true

  smokeping:
    image: ghcr.io/linuxserver/smokeping:latest
    container_name: smokeping
    restart: always
    environment:
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.smokeping.headers.contentSecurityPolicy=default-src 'self'; img-src 'self' data:"
      - "traefik.http.routers.smokeping.rule=Host(`ping.gate.seedno.de`)"
      - "traefik.http.routers.smokeping.entrypoints=https"
      - "traefik.http.routers.smokeping.service=smokeping"
      - "traefik.http.routers.smokeping.tls=true"
      - "traefik.http.routers.smokeping.tls.certresolver=letsencrypt"
      - "traefik.http.routers.smokeping.middlewares=compress,secure,smokeping"
      - "traefik.http.services.smokeping.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /home/sinc/traefik/smokeping
        target: /config
        read_only: true
      - type: volume
        source: smokeping
        target: /data

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: always
    environment:
      - "GF_ALERTING_ENABLED=false"
      - "GF_AUTH_ANONYMOUS_ENABLED=false"
      - "GF_DEFAULT_INSTANCE_NAME=grafana.gate.seedno.de"
      - "GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-clock-panel"
      - "GF_METRICS_ENABLED=true"
      - "GF_SECURITY_COOKIE_SECURE=true"
      - "GF_SECURITY_DISABLE_GRAVATAR=true"
      - "GF_SECURITY_ALLOW_EMBEDDING=false"
      - "GF_SERVER_DOMAIN=grafana.gate.seedno.de"
      - "GF_SERVER_ENFORCE_DOMAIN=true"
      - "GF_SERVER_HTTP_PORT=3000"
      - "GF_SERVER_HTTP_PROTOCOL=https"
      - "GF_SERVER_ROOT_URL=https://grafana.gate.seedno.de/"
      - "GF_SERVER_SERVE_FROM_SUB_PATH=false"
      - "GF_SNAPSHOTS_EXTERNAL_ENABLED=false"
      - "GF_USERS_ALLOW_SIGN_UP=false"
      - "GF_USERS_VIEWERS_CAN_EDIT=false"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.grafana.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:"
      - "traefik.http.routers.grafana.rule=Host(`grafana.gate.seedno.de`)"
      - "traefik.http.routers.grafana.entrypoints=https"
      - "traefik.http.routers.grafana.service=grafana"
      - "traefik.http.routers.grafana.tls=true"
      - "traefik.http.routers.grafana.tls.certresolver=letsencrypt"
      - "traefik.http.routers.grafana.middlewares=grafana,compress,secure"
      - "traefik.http.services.grafana.loadbalancer.server.port=3000"
    networks:
      - traefik
    volumes:
      - type: volume
        source: grafana
        target: /var/lib/grafana

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - UNIFI_POLLER_USER
  # - UNIFI_POLLER_PASS
  unifi-poller:
    image: golift/unifi-poller:latest
    container_name: unifi-poller
    restart: always
    depends_on:
      - unifi
    environment:
      - "UP_UNIFI_DYNAMIC=true"
      - "UP_UNIFI_CONTROLLER_0_URL=https://unifi:8443"
      - "UP_UNIFI_CONTROLLER_0_USER=${UNIFI_POLLER_USER}"
      - "UP_UNIFI_CONTROLLER_0_PASS=${UNIFI_POLLER_PASS}"
      - "UP_UNIFI_CONTROLLER_0_SITE_0=all"
      - "UP_UNIFI_CONTROLLER_0_VERIFY_SSL=false"
      - "UP_PROMETHEUS_DISABLE=false"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik

  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    restart: always
    depends_on:
      - prometheus
    command:
      - "--path.rootfs=/host"
    cap_add:
      - "SYS_TIME"
    pid: "host"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /
        target: /host
        read_only: true
        bind:
          propagation: rslave

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: always
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /home/sinc/traefik/prometheus/prometheus.yml
        target: /etc/prometheus/prometheus.yml
        read_only: true
      - type: volume
        source: prometheus
        target: /prometheus

  sflow-exporter:
    image: sflow/host-sflow:latest
    container_name: sflow-exporter
    restart: always
    environment:
      - "COLLECTOR=sflow.gate.seedno.de"
      - "DROPMON=enable"
      - "NET=host"
      - "POLLING=5"
      - "PORT=6343"
      - "SAMPLING=1000"
    labels:
      - "traefik.enable=false"
    network_mode: host
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
        read_only: true

  sflow-collector:
    image: sflow/prometheus:latest
    container_name: sflow-collector
    restart: always
    environment:
      - "RTMEM=2G"
    command:
      - "-Dsnmp.ifname=yes"
      - "-Dgeo.country=resources/config/GeoLite2-Country.mmdb"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.sflow-web.headers.contentSecurityPolicy=default-src 'self'"
      - "traefik.http.routers.sflow-web.rule=Host(`sflow.gate.seedno.de`)"
      - "traefik.http.routers.sflow-web.entrypoints=https"
      - "traefik.http.routers.sflow-web.service=sflow-web"
      - "traefik.http.routers.sflow-web.tls=true"
      - "traefik.http.routers.sflow-web.tls.certresolver=letsencrypt"
      - "traefik.http.routers.sflow-web.middlewares=adminauth,compress,secure,sflow-web"
      - "traefik.http.services.sflow-web.loadbalancer.server.port=8008"
      - "traefik.udp.routers.sflow-collector.entrypoints=sflow"
      - "traefik.udp.routers.sflow-collector.service=sflow-collector"
      - "traefik.udp.services.sflow-collector.loadbalancer.server.port=6343"
    networks:
      - traefik

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - BOOKSTACK_DB_USER
  # - BOOKSTACK_DB_PASS
  bookstack:
    image: ghcr.io/linuxserver/bookstack:latest
    container_name: bookstack
    restart: always
    depends_on:
      - bookstack-db
    environment:
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "APP_URL=https://bookstack.seedno.de"
      - "DB_HOST=bookstack-db"
      - "DB_USER=${BOOKSTACK_DB_USER}"
      - "DB_PASS=${BOOKSTACK_DB_PASS}"
      - "DB_DATABASE=bookstack"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.bookstack.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.bookstack.rule=Host(`bookstack.seedno.de`)"
      - "traefik.http.routers.bookstack.entrypoints=https"
      - "traefik.http.routers.bookstack.service=bookstack"
      - "traefik.http.routers.bookstack.tls=true"
      - "traefik.http.routers.bookstack.tls.certresolver=letsencrypt"
      - "traefik.http.routers.bookstack.middlewares=compress,secure,bookstack"
      - "traefik.http.services.bookstack.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: volume
        source: bookstack
        target: /config

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - BOOKSTACK_DB_ROOT_PASS
  # - BOOKSTACK_DB_USER
  # - BOOKSTACK_DB_PASS
  bookstack-db:
    image: ghcr.io/linuxserver/mariadb
    container_name: bookstack-db
    restart: always
    environment:
      - "MYSQL_ROOT_PASSWORD=${BOOKSTACK_DB_ROOT_PASS}"
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
      - "MYSQL_DATABASE=bookstack"
      - "MYSQL_USER=${BOOKSTACK_DB_USER}"
      - "MYSQL_PASSWORD=${BOOKSTACK_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: bookstack-db
        target: /config

  youtube-dl:
    image: tzahi12345/youtubedl-material:nightly
    container_name: youtube-dl
    restart: always
    environment:
      - "ALLOW_CONFIG_MUTATIONS=true"
      - "UID=${UID}"
      - "GID=${GID}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.youtube-dl.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline' https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.github.com"
      - "traefik.http.routers.youtube-dl.rule=Host(`ytdl.seedno.de`)"
      - "traefik.http.routers.youtube-dl.entrypoints=https"
      - "traefik.http.routers.youtube-dl.service=youtube-dl"
      - "traefik.http.routers.youtube-dl.tls=true"
      - "traefik.http.routers.youtube-dl.tls.certresolver=letsencrypt"
      - "traefik.http.routers.youtube-dl.middlewares=friendsauth,compress,secure,youtube-dl"
      - "traefik.http.services.youtube-dl.loadbalancer.server.port=17442"
    networks:
      - traefik
    volumes:
      - type: volume
        source: youtube-dl
        target: /app
      - type: bind
        source: /home/sinc/youtube-dl/audio
        target: /app/audio
      - type: bind
        source: /home/sinc/youtube-dl/video
        target: /app/video

  imgproxy:
    image: darthsim/imgproxy:latest
    container_name: imgproxy
    restart: always
    environment:
      - "IMGPROXY_KEY=${IMGPROXY_KEY}"
      - "IMGPROXY_SALT=${IMGPROXY_SALT}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.imgproxy.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.imgproxy.rule=Host(`imgproxy.seedno.de`)"
      - "traefik.http.routers.imgproxy.entrypoints=https"
      - "traefik.http.routers.imgproxy.service=imgproxy"
      - "traefik.http.routers.imgproxy.tls=true"
      - "traefik.http.routers.imgproxy.tls.certresolver=letsencrypt"
      - "traefik.http.routers.imgproxy.middlewares=compress,secure,imgproxy"
      - "traefik.http.services.imgproxy.loadbalancer.server.port=8080"
    networks:
      - traefik

  polaris:
    image: ogarcia/polaris:latest
    container_name: polaris
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.polaris.headers.contentSecurityPolicy=default-src 'self'"
      - "traefik.http.routers.polaris.rule=Host(`music.seedno.de`)"
      - "traefik.http.routers.polaris.entrypoints=https"
      - "traefik.http.routers.polaris.service=polaris"
      - "traefik.http.routers.polaris.tls=true"
      - "traefik.http.routers.polaris.tls.certresolver=letsencrypt"
      - "traefik.http.routers.polaris.middlewares=compress,secure,polaris"
      - "traefik.http.services.polaris.loadbalancer.server.port=5050"
    networks:
      - traefik
    volumes:
      - type: volume
        source: polaris
        target: /var/lib/polaris
      - type: bind
        source: /home/sinc/audio
        target: /music
        read_only: true

  cyberchef:
    image: mpepping/cyberchef:latest
    container_name: cyberchef
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.cyberchef.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'self' data:; frame-src 'self' data:; worker-src 'self' blob: data:"
      - "traefik.http.routers.cyberchef.rule=Host(`tools.seedno.de`)"
      - "traefik.http.routers.cyberchef.entrypoints=https"
      - "traefik.http.routers.cyberchef.service=cyberchef"
      - "traefik.http.routers.cyberchef.tls=true"
      - "traefik.http.routers.cyberchef.tls.certresolver=letsencrypt"
      - "traefik.http.routers.cyberchef.middlewares=compress,secure,cyberchef"
      - "traefik.http.services.cyberchef.loadbalancer.server.port=8000"
    networks:
      - traefik

  coloratura:
    image: docker.seedno.de/seednode/glulxe-coloratura:latest
    container_name: coloratura
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.coloratura.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; media-src 'self' data:"
      - "traefik.http.routers.coloratura.rule=Host(`coloratura.seedno.de`)"
      - "traefik.http.routers.coloratura.entrypoints=https"
      - "traefik.http.routers.coloratura.service=coloratura"
      - "traefik.http.routers.coloratura.tls=true"
      - "traefik.http.routers.coloratura.tls.certresolver=letsencrypt"
      - "traefik.http.routers.coloratura.middlewares=compress,secure,coloratura"
      - "traefik.http.services.coloratura.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: volume
        source: coloratura
        target: /data

  glulxe:
    image: docker.seedno.de/seednode/glulxe:latest
    container_name: glulxe
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.glulxe.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; media-src 'self' data:"
      - "traefik.http.routers.glulxe.rule=Host(`fs.seedno.de`)"
      - "traefik.http.routers.glulxe.entrypoints=https"
      - "traefik.http.routers.glulxe.service=glulxe"
      - "traefik.http.routers.glulxe.tls=true"
      - "traefik.http.routers.glulxe.tls.certresolver=letsencrypt"
      - "traefik.http.routers.glulxe.middlewares=adminauth,compress,secure,glulxe"
      - "traefik.http.services.glulxe.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: volume
        source: glulxe
        target: /data

  mediawiki:
    image: mediawiki
    container_name: mediawiki
    restart: always
    depends_on:
      - mediawiki-db
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.mediawiki.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; img-src 'self' https: data:; media-src 'self' https: data:"
      - "traefik.http.routers.mediawiki.rule=Host(`wiki.seedno.de`)"
      - "traefik.http.routers.mediawiki.entrypoints=https"
      - "traefik.http.routers.mediawiki.service=mediawiki"
      - "traefik.http.routers.mediawiki.tls=true"
      - "traefik.http.routers.mediawiki.tls.certresolver=letsencrypt"
      - "traefik.http.routers.mediawiki.middlewares=compress,secure,mediawiki"
      - "traefik.http.services.mediawiki.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: volume
        source: mediawiki
        target: /var/www/html

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - MEDIAWIKI_DB_ROOT_PASS
  # - MEDIAWIKI_DB_USER
  # - MEDIAWIKI_DB_PASS
  mediawiki-db:
    image: ghcr.io/linuxserver/mariadb
    container_name: mediawiki-db
    restart: always
    environment:
      - "MYSQL_ROOT_PASSWORD=${MEDIAWIKI_DB_ROOT_PASS}"
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
      - "MYSQL_DATABASE=mediawiki"
      - "MYSQL_USER=${MEDIAWIKI_DB_USER}"
      - "MYSQL_PASSWORD=${MEDIAWIKI_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: mediawiki-db
        target: /config

  element:
    image: vectorim/element-web
    container_name: element
    restart: always
    depends_on:
      - synapse
      - synapse-db
    environment:
      - "VIRTUAL_PORT=80"
      - "VIRTUAL_HOST=element.seedno.de"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.element.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self' https:; img-src 'self' data: https:; media-src 'self' https:"
      - "traefik.http.routers.element.rule=Host(`element.seedno.de`)"
      - "traefik.http.routers.element.entrypoints=https"
      - "traefik.http.routers.element.service=element"
      - "traefik.http.routers.element.tls=true"
      - "traefik.http.routers.element.tls.certresolver=letsencrypt"
      - "traefik.http.routers.element.middlewares=compress,secure,element"
      - "traefik.http.services.element.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /home/sinc/traefik/matrix/config.json
        target: /usr/share/nginx/html/config.element.seedno.de.json
        read_only: true

  synapse:
    image: matrixdotorg/synapse:latest
    container_name: synapse
    restart: always
    depends_on:
      - synapse-db
    environment:
      - "SYNAPSE_CONFIG_DIR=/data"
      - "SYNAPSE_CONFIG_PATH=/data/homeserver.yaml"
      - "UID=${UID}"
      - "GID=${GID}"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.synapse.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.synapse.rule=Host(`matrix.seedno.de`)"
      - "traefik.http.routers.synapse.entrypoints=https"
      - "traefik.http.routers.synapse.service=synapse"
      - "traefik.http.routers.synapse.tls=true"
      - "traefik.http.routers.synapse.tls.certresolver=letsencrypt"
      - "traefik.http.routers.synapse.middlewares=compress,secure,synapse"
      - "traefik.http.services.synapse.loadbalancer.server.port=8008"
    networks:
      - traefik
    volumes:
      - type: volume
        source: synapse-data
        target: /data
      - type: volume
        source: synapse-media
        target: /data/media
      - type: volume
        source: synapse-uploads
        target: /data/uploads

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - SYNAPSE_DB_USER
  # - SYNAPSE_DB_PASS
  synapse-db:
    image: postgres:12-alpine
    container_name: synapse-db
    restart: always
    environment:
      - "POSTGRES_DB=synapse"
      - "POSTGRES_USER=${SYNAPSE_DB_USER}"
      - "POSTGRES_PASSWORD=${SYNAPSE_DB_PASS}"
      - "POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: synapse-db
        target: /var/lib/postgresql/data


  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - BINGO_FLASK_SECRET
  bingo:
    image: docker.seedno.de/seednode/bingo:latest
    container_name: bingo
    restart: always
    depends_on:
      - bingo-redis
    environment:
     - "BINGO_API_PORT=80"
     - "BINGO_API_HOST=0.0.0.0"
     - "BINGO_REDIS_PORT=6379"
     - "BINGO_REDIS_HOST=bingo-redis"
     - "BINGO_FLASK_SECRET=${BINGO_SECRET}"
     - "BINGO_VERBOSE=True"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.bingo.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"
      - "traefik.http.routers.bingo.rule=Host(`bingo.seedno.de`)"
      - "traefik.http.routers.bingo.entrypoints=https"
      - "traefik.http.routers.bingo.service=bingo"
      - "traefik.http.routers.bingo.tls=true"
      - "traefik.http.routers.bingo.tls.certresolver=letsencrypt"
      - "traefik.http.routers.bingo.middlewares=compress,secure,bingo"
      - "traefik.http.services.bingo.loadbalancer.server.port=80"
    networks:
      - traefik

  bingo-redis:
    image: redis
    container_name: bingo-redis
    restart: always
    labels:
      - "traefik.enable=false"
    networks:
      - traefik

  pleroma:
    image: docker.seedno.de/seednode/pleroma:latest
    container_name: pleroma
    restart: always
    depends_on:
      - pleroma-db
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.pleroma.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:"
      - "traefik.http.routers.pleroma.rule=Host(`blaming.me`)"
      - "traefik.http.routers.pleroma.entrypoints=https"
      - "traefik.http.routers.pleroma.service=pleroma"
      - "traefik.http.routers.pleroma.tls=true"
      - "traefik.http.routers.pleroma.tls.certresolver=letsencrypt"
      - "traefik.http.routers.pleroma.middlewares=compress,secure,pleroma"
      - "traefik.http.services.pleroma.loadbalancer.server.port=4000"
    networks:
      - traefik
    volumes:
      - type: volume
        source: pleroma
        target: /pleroma/uploads

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - PLEROMA_DB_USER
  # - PLEROMA_DB_PASS
  pleroma-db:
    image: postgres:alpine
    container_name: pleroma-db
    restart: always
    environment:
      - "POSTGRES_DB=pleroma"
      - "POSTGRES_USER=${PLEROMA_DB_USER}"
      - "POSTGRES_PASSWORD=${PLEROMA_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: pleroma-db
        target: /var/lib/postgresql/data

  pastebin:
    image: mkaczanowski/pastebin
    container_name: pastebin
    restart: always
    command:
      - "--address=0.0.0.0"
      - "--port=8000"
      - "--db=/data/pastebin.db"
      - "--uri=https://paste.seedno.de"
      - "--slug-len=12"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.pastebin.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' https://cdnjs.cloudflare.com; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; font-src 'self' https://cdnjs.cloudflare.com; img-src 'self' data:"
      - "traefik.http.routers.pastebin.rule=Host(`paste.seedno.de`)"
      - "traefik.http.routers.pastebin.entrypoints=https"
      - "traefik.http.routers.pastebin.service=pastebin"
      - "traefik.http.routers.pastebin.tls=true"
      - "traefik.http.routers.pastebin.tls.certresolver=letsencrypt"
      - "traefik.http.routers.pastebin.middlewares=compress,secure,pastebin"
      - "traefik.http.services.pastebin.loadbalancer.server.port=8000"
    networks:
      - traefik
    volumes:
      - type: volume
        source: pastebin
        target: /data

  hastebin:
    image: angristan/hastebin:latest
    container_name: hastebin
    restart: always
    environment:
      - "UID=${UID}"
      - "GID=${GID}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.hastebin.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' ajax.googleapis.com"
      - "traefik.http.routers.hastebin.rule=Host(`haste.seedno.de`)"
      - "traefik.http.routers.hastebin.entrypoints=https"
      - "traefik.http.routers.hastebin.service=hastebin"
      - "traefik.http.routers.hastebin.tls=true"
      - "traefik.http.routers.hastebin.tls.certresolver=letsencrypt"
      - "traefik.http.routers.hastebin.middlewares=compress,secure,hastebin"
      - "traefik.http.services.hastebin.loadbalancer.server.port=7777"
    networks:
      - traefik
    volumes:
      - type: volume
        source: hastebin
        target: /app/data

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - PHPBB_USER
  # - PHPBB_PASS
  # - PHPBB_DB_USER
  # - PHPBB_DB_PASS
  # - PHPBB_SMTP_USER
  # - PHPBB_SMTP_PASS
  phpbb:
    image: bitnami/phpbb:latest
    container_name: phpbb
    restart: always
    depends_on:
      - phpbb-db
    environment:
      - "APACHE_HTTP_PORT_NUMBER=8080"
      - "APACHE_HTTPS_PORT_NUMBER=8443"
      - "PHPBB_USERNAME=${PHPBB_USER}"
      - "PHPBB_PASSWORD=${PHPBB_PASS}"
      - "PHPBB_EMAIL=phpbb@seedno.de"
      - "PHPBB_FORUM_NAME=Seedno.de"
      - "PHPBB_FORUM_DESCRIPTION=Just stop worrying about it."
      - "PHPBB_HOST=forum.seedno.de"
      - "PHPBB_SKIP_BOOTSTRAP=no"
      - "PHPBB_COOKIE_SECURE=yes"
      - "PHPBB_FORUM_SERVER_PROTOCOL=https://"
      - "PHPBB_DISABLE_SESSION_VALIDATION=false"
      - "PHPBB_DATABASE_HOST=phpbb-db"
      - "PHPBB_DATABASE_PORT_NUMBER=3306"
      - "PHPBB_DATABASE_NAME=phpbb"
      - "PHPBB_DATABASE_USER=${PHPBB_DB_USER}"
      - "PHPBB_DATABASE_PASSWORD=${PHPBB_DB_PASS}"
      - "ALLOW_EMPTY_PASSWORD=no"
      - "PHPBB_SMTP_HOST=mail.seedno.de"
      - "PHPBB_SMTP_PORT=587"
      - "PHPBB_SMTP_USER=${PHPBB_SMTP_USER}"
      - "PHPBB_SMTP_PASSWORD=${PHPBB_SMTP_PASS}"
      - "PHPBB_SMTP_PROTOCOL=tls"
      - "PHP_MEMORY_LIMIT=1024M"
      - "PHP_POST_MAX_SIZE=50M"
      - "PHP_UPLOAD_MAX_FILESIZE=50M"
      - "PHP_EXPOSE_PHP=no"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.phpbb.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.phpbb.rule=Host(`forum.seedno.de`)"
      - "traefik.http.routers.phpbb.entrypoints=https"
      - "traefik.http.routers.phpbb.service=phpbb"
      - "traefik.http.routers.phpbb.tls=true"
      - "traefik.http.routers.phpbb.tls.certresolver=letsencrypt"
      - "traefik.http.routers.phpbb.middlewares=compress,secure,phpbb"
      - "traefik.http.services.phpbb.loadbalancer.server.port=8080"
    networks:
      - traefik
    volumes:
      - type: volume
        source: phpbb-conf
        target: /bitnami

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - PHPBB_DB_ROOT_PASS
  # - PHPBB_DB_USER
  # - PHPBB_DB_PASS
  phpbb-db:
    image: ghcr.io/linuxserver/mariadb
    container_name: phpbb-db
    restart: always
    environment:
      - "MYSQL_ROOT_PASSWORD=${PHPBB_DB_ROOT_PASS}"
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
      - "MYSQL_DATABASE=phpbb"
      - "MYSQL_USER=${PHPBB_DB_USER}"
      - "MYSQL_PASSWORD=${PHPBB_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: phpbb-db
        target: /config

  # Set password after first boot via `docker exec -it pihole pihole -a -p`
  pihole:
    image: pihole/pihole:latest
    container_name: pihole
    restart: always
    environment:
      - "ADMIN_EMAIL=pihole@seedno.de"
      - "DNS1=1.1.1.1"
      - "DNS2=8.8.8.8"
      - "DNSSEC=true"
      - "DNS_BOGUS_PRIV=false"
      - "DNS_FQDN_REQUIIRED=false"
      - "DNSMASQ_LISTENING=all"
      - "DNSMASQ_USER=pihole"
      - "TEMPERATUREUNIT=c"
      - "VIRTUAL_HOST=pihole.seedno.de"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.pihole.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.pihole-web.rule=Host(`pihole.seedno.de`)"
      - "traefik.http.routers.pihole-web.entrypoints=https"
      - "traefik.http.routers.pihole-web.service=pihole-web"
      - "traefik.http.routers.pihole-web.tls=true"
      - "traefik.http.routers.pihole-web.tls.certresolver=letsencrypt"
      - "traefik.http.routers.pihole-web.middlewares=compress,secure,pihole,whitelist@file"
      - "traefik.http.services.pihole-web.loadbalancer.server.port=80"
      - "traefik.tcp.routers.pihole-tcp.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pihole-tcp.entrypoints=pihole-tcp"
      - "traefik.tcp.routers.pihole-tcp.service=pihole-tcp"
      - "traefik.tcp.services.pihole-tcp.loadbalancer.server.port=53"
      - "traefik.udp.routers.pihole-udp.entrypoints=pihole-udp"
      - "traefik.udp.routers.pihole-udp.service=pihole-udp"
      - "traefik.udp.services.pihole-udp.loadbalancer.server.port=53"
    networks:
      - traefik
    volumes:
      - type: volume
        source: pihole-conf
        target: /etc/pihole
      - type: volume
        source: pihole-dnsmasq
        target: /etc/dnsmasq.d

  editormd:
    image: docker.seedno.de/seednode/editormd:1.19.6
    container_name: editormd
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.editormd.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; font-src 'self' data:; img-src 'self' data:"
      - "traefik.http.routers.editormd.rule=Host(`md.seedno.de`)"
      - "traefik.http.routers.editormd.entrypoints=https"
      - "traefik.http.routers.editormd.service=editormd"
      - "traefik.http.routers.editormd.tls=true"
      - "traefik.http.routers.editormd.tls.certresolver=letsencrypt"
      - "traefik.http.routers.editormd.middlewares=compress,secure,editormd"
      - "traefik.http.services.editormd.loadbalancer.server.port=80"
    networks:
      - traefik

  # Note: "proxy_set_header X-Forwarded-for $remote_addr;" must be commented out in /config/nginx/site-confs/default, due to how traefik handles the header value
  snapdrop:
    image: ghcr.io/linuxserver/snapdrop
    container_name: snapdrop
    restart: always
    environment:
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.snapdrop.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'sha256-biLFinpqYMtWHmXfkA1BPeCY0/fNt46SAZ+BBk5YUog='; style-src-attr 'self' 'unsafe-inline'"
      - "traefik.http.routers.snapdrop.rule=Host(`drop.seedno.de`)"
      - "traefik.http.routers.snapdrop.entrypoints=https"
      - "traefik.http.routers.snapdrop.service=snapdrop"
      - "traefik.http.routers.snapdrop.tls=true"
      - "traefik.http.routers.snapdrop.tls.certresolver=letsencrypt"
      - "traefik.http.routers.snapdrop.middlewares=compress,secure,snapdrop"
      - "traefik.http.services.snapdrop.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: volume
        source: snapdrop
        target: /config

  rtmp:
    image: docker.seedno.de/seednode/nginx-rtmp:1.19.6
    container_name: rtmp
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.rtmp.headers.contentSecurityPolicy=default-src 'self'; style-src 'unsafe-inline'; script-src 'unsafe-inline' 'self' blob:; media-src 'self' blob:"
      - "traefik.http.routers.rtmp-web.rule=Host(`stream.seedno.de`)"
      - "traefik.http.routers.rtmp-web.entrypoints=https"
      - "traefik.http.routers.rtmp-web.service=rtmp-web"
      - "traefik.http.routers.rtmp-web.tls=true"
      - "traefik.http.routers.rtmp-web.tls.certresolver=letsencrypt"
      - "traefik.http.routers.rtmp-web.middlewares=compress,secure,rtmp"
      - "traefik.http.services.rtmp-web.loadbalancer.server.port=80"
      - "traefik.tcp.routers.rtmp-stream.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.rtmp-stream.entrypoints=rtmp"
      - "traefik.tcp.routers.rtmp-stream.service=rtmp-stream"
      - "traefik.tcp.services.rtmp-stream.loadbalancer.server.port=1935"
    networks:
      - traefik
    volumes:
      - type: volume
        source: rtmp-streams
        target: /var/www/html
      - type: volume
        source: rtmp-log
        target: /var/log/nginx

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - GUACAMOLE_DB_USER
  # - GUACAMOLE_DB_PASS
  guacamole:
    image: guacamole/guacamole
    container_name: guacamole
    restart: always
    depends_on:
      - guac-db
      - guacd
    environment:
      - "GUACD_HOSTNAME=guacd"
      - "POSTGRES_HOSTNAME=guac-db"
      - "POSTGRES_DATABASE=guacamole"
      - "POSTGRES_USER=${GUACAMOLE_DB_USER}"
      - "POSTGRES_PASSWORD=${GUACAMOLE_DB_PASS}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.guacamole.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; img-src 'self' data:"
      - "traefik.http.routers.guacamole.rule=Host(`guacamole.seedno.de`)"
      - "traefik.http.routers.guacamole.entrypoints=https"
      - "traefik.http.routers.guacamole.service=guacamole"
      - "traefik.http.routers.guacamole.tls=true"
      - "traefik.http.routers.guacamole.tls.certresolver=letsencrypt"
      - "traefik.http.routers.guacamole.middlewares=compress,secure,guacamole"
      - "traefik.http.services.guacamole.loadbalancer.server.port=8080"
    networks:
      - traefik

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - GUACAMOLE_DB_USER
  # - GUACAMOLE_DB_PASS
  guac-db:
    image: postgres:alpine
    container_name: guac-db
    restart: always
    environment:
      - "POSTGRES_DB=guacamole"
      - "POSTGRES_USER=${GUACAMOLE_DB_USER}"
      - "POSTGRES_PASSWORD=${GUACAMOLE_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: guac-db
        target: /var/lib/postgresql/data

  guacd:
    image: ghcr.io/linuxserver/guacd:latest
    container_name: guacd
    restart: always
    labels:
      - "traefik.enable=false"
    networks:
      - traefik

  qbittorrent:
    image: ghcr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    restart: always
    environment:
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
      - "UMASK_SET=022"
      - "WEBUI_PORT=8080"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.qbittorrent.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.qbittorrent-web.rule=Host(`torrent.seedno.de`)"
      - "traefik.http.routers.qbittorrent-web.entrypoints=https"
      - "traefik.http.routers.qbittorrent-web.service=qbittorrent-web"
      - "traefik.http.routers.qbittorrent-web.tls=true"
      - "traefik.http.routers.qbittorrent-web.tls.certresolver=letsencrypt"
      - "traefik.http.routers.qbittorrent-web.middlewares=compress,secure,qbittorrent,adminauth"
      - "traefik.http.services.qbittorrent-web.loadbalancer.server.port=8080"
      - "traefik.tcp.routers.qbittorrent-tcp.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.qbittorrent-tcp.entrypoints=torrent-tcp"
      - "traefik.tcp.routers.qbittorrent-tcp.service=qbittorent-tcp"
      - "traefik.tcp.services.qbittorrent-tcp.loadbalancer.server.port=6881"
      - "traefik.udp.routers.qbittorrent-udp.entrypoints=torrent-udp"
      - "traefik.udp.routers.qbittorrent-udp.service=qbittorrent-udp"
      - "traefik.udp.services.qbittorrent-udp.loadbalancer.server.port=6881"
    networks:
      - traefik
    volumes:
      - type: volume
        source: qbittorrent
        target: /config
      - type: bind
        source: /storage/torrents
        target: /downloads

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - NETBOX_USER
  # - NETBOX_PASS
  # - NETBOX_DB_USER
  # - NETBOX_DB_PASS
  netbox:
    image: ghcr.io/linuxserver/netbox
    container_name: netbox
    restart: always
    depends_on:
      - netbox-redis
      - netbox-db
    environment:
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "SUPERUSER_EMAIL=${NETBOX_USER}"
      - "SUPERUSER_PASSWORD=${NETBOX_PASS}"
      - "ALLOWED_HOST=ipam.seedno.de"
      - "DB_NAME=netbox"
      - "DB_USER=${NETBOX_DB_USER}"
      - "DB_PASSWORD=${NETBOX_DB_PASS}"
      - "DB_HOST=netbox-db"
      - "DB_PORT=5432"
      - "REDIS_HOST=netbox-redis"
      - "REDIS_PORT=6379"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.netbox.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.netbox.rule=Host(`ipam.seedno.de`)"
      - "traefik.http.routers.netbox.entrypoints=https"
      - "traefik.http.routers.netbox.service=netbox"
      - "traefik.http.routers.netbox.tls=true"
      - "traefik.http.routers.netbox.tls.certresolver=letsencrypt"
      - "traefik.http.routers.netbox.middlewares=compress,secure,netbox"
      - "traefik.http.services.netbox.loadbalancer.server.port=8000"
    networks:
      - traefik
    volumes:
      - type: volume
        source: netbox-config
        target: /config
 
  netbox-redis:
    image: redis
    container_name: netbox-redis
    restart: always
    command:
      - "--appendonly yes"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: netbox-redis
        target: /data

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - NETBOX_DB_USER
  # - NETBOX_DB_PASS
  netbox-db:
    image: postgres:alpine
    container_name: netbox-db
    restart: always
    environment:
      - "POSTGRES_DB=netbox"
      - "POSTGRES_USER=${NETBOX_DB_USER}"
      - "POSTGRES_PASSWORD=${NETBOX_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: netbox-db
        target: /var/lib/postgresql/data

  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.mosquitto.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.mosquitto.entrypoints=mosquitto"
      - "traefik.tcp.routers.mosquitto.service=mosquitto"
      - "traefik.tcp.services.mosquitto.loadbalancer.server.port=1883"
    networks:
      - traefik
    volumes:
      - type: volume
        source: mosquitto-conf
        target: /mosquitto/config
      - type: volume
        source: mosquitto-data
        target: /mosquitto/data
      - type: volume
        source: mosquitto-log
        target: /mosquitto/log

  minecraft:
    image: itzg/minecraft-server:latest
    container_name: minecraft
    restart: always
    environment:
      - "VERSION=1.16.4"
      - "ONLINE_MODE=FALSE"
      - "OVERRIDE_SERVER_PROPERTIES=true"
      - "SERVER_NAME=Seednode's Safe Space"
      - "SERVER_PORT=25570"
      - "MEMORY=4G"
      - "MAX_PLAYERS=32"
      - "ENABLE_COMMAND_BLOCK=false"
      - "FORCE_GAMEMODE=true"
      - "MODE=survival"
      - "MOTD=Welcome to Hell."
      - "EULA=TRUE"
      - "TYPE=PAPER"
      - "UID=${UID}"
      - "GID=${GID}"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.minecraft.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.minecraft.entrypoints=minecraft"
      - "traefik.tcp.routers.minecraft.service=minecraft"
      - "traefik.tcp.services.minecraft.loadbalancer.server.port=25570"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /home/sinc/minecraft
        target: /data

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - GHOST_DB_USER
  # - GHOST_DB_PASS
  ghost:
    image: ghost:alpine
    container_name: ghost
    restart: always
    depends_on:
      - ghost-db
    environment:
      - "database__client=mysql"
      - "database__connection__host=ghost-db"
      - "database__connection__port=3306"
      - "database__connection__user=${GHOST_DB_USER}"
      - "database__connection__password=${GHOST_DB_PASS}"
      - "database__connection__database=ghost"
      - "url=https://blog.seedno.de"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ghost.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'unsafe-inline' https://code.jquery.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://static.ghost.org; connect-src 'self' https://ghost.org;"
      - "traefik.http.routers.ghost.rule=Host(`blog.seedno.de`)"
      - "traefik.http.routers.ghost.entrypoints=https"
      - "traefik.http.routers.ghost.service=ghost"
      - "traefik.http.routers.ghost.tls=true"
      - "traefik.http.routers.ghost.tls.certresolver=letsencrypt"
      - "traefik.http.routers.ghost.middlewares=compress,secure,ghost"
      - "traefik.http.services.ghost.loadbalancer.server.port=2368"
    networks:
      - traefik
    volumes:
      - type: volume
        source: ghost
        target: /var/lib/ghost/content

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - GHOST_DB_ROOT_PASS
  # - GHOST_DB_USER
  # - GHOST_DB_PASS
  ghost-db:
    image: ghcr.io/linuxserver/mariadb
    container_name: ghost-db
    restart: always
    environment:
      - "MYSQL_ROOT_PASSWORD=${GHOST_DB_ROOT_PASS}"
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
      - "MYSQL_DATABASE=ghost"
      - "MYSQL_USER=${GHOST_DB_USER}"
      - "MYSQL_PASSWORD=${GHOST_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: ghost-db
        target: /config

  code-server:
    image: ghcr.io/linuxserver/code-server:latest
    container_name: code-server
    restart: always
    environment:
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.code-server.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:"
      - "traefik.http.routers.code-server.rule=Host(`code.seedno.de`)"
      - "traefik.http.routers.code-server.entrypoints=https"
      - "traefik.http.routers.code-server.service=code-server"
      - "traefik.http.routers.code-server.tls=true"
      - "traefik.http.routers.code-server.tls.certresolver=letsencrypt"
      - "traefik.http.routers.code-server.middlewares=adminauth,compress,secure,code-server"
      - "traefik.http.services.code-server.loadbalancer.server.port=8443"
    networks:
      - traefik
    volumes:
      - type: volume
        source: code-server
        target: /config

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - BITWARDEN_DB_USER
  # - BITWARDEN_DB_PASS
  bitwarden:
    image: bitwardenrs/server:multidb
    container_name: bitwarden
    restart: always
    depends_on:
      - bitwarden-db
    environment:
      - "DATABASE_URL=postgresql://${BITWARDEN_DB_USER}:${BITWARDEN_DB_PASS}@bitwarden-db:5432/bitwarden"
      - "DOMAIN=https://vault.seedno.de"
      - "WEBSOCKET_ENABLED=false"
      - "SIGNUPS_ALLOWED=false"
      - "INVITATIONS_ALLOWED=false"
      - "SHOW_PASSWORD_HINT=false"
      - "LOG_FILE=/data/bitwarden.log"
      - "ROCKET_PORT=80"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.bitwarden.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; img-src 'self' data:"
      - "traefik.http.routers.bitwarden.rule=Host(`vault.seedno.de`)"
      - "traefik.http.routers.bitwarden.entrypoints=https"
      - "traefik.http.routers.bitwarden.service=bitwarden"
      - "traefik.http.routers.bitwarden.tls=true"
      - "traefik.http.routers.bitwarden.tls.certresolver=letsencrypt"
      - "traefik.http.routers.bitwarden.middlewares=compress,secure,bitwarden"
      - "traefik.http.services.bitwarden.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: volume
        source: bitwarden
        target: /data

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - BITWARDEN_DB_USER
  # - BITWARDEN_DB_PASS
  bitwarden-db:
    image: postgres:alpine
    container_name: bitwarden-db
    restart: always
    environment:
      - "POSTGRES_DB=bitwarden"
      - "POSTGRES_USER=${BITWARDEN_DB_USER}"
      - "POSTGRES_PASSWORD=${BITWARDEN_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: bitwarden-db
        target: /var/lib/postgresql/data

  nginx:
    image: docker.seedno.de/seednode/nginx-php:1.19.6
    container_name: nginx
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.accessseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; font-src 'self' data:; img-src 'self' data:"
      - "traefik.http.routers.accessseednode.rule=Host(`access.seedno.de`)"
      - "traefik.http.routers.accessseednode.entrypoints=https"
      - "traefik.http.routers.accessseednode.service=nginx"
      - "traefik.http.routers.accessseednode.tls=true"
      - "traefik.http.routers.accessseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.accessseednode.middlewares=adminauth,compress,secure,accessseednode"
      - "traefik.http.middlewares.casconseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.casconseednode.rule=Host(`cascon.seedno.de`)"
      - "traefik.http.routers.casconseednode.entrypoints=https"
      - "traefik.http.routers.casconseednode.service=nginx"
      - "traefik.http.routers.casconseednode.tls=true"
      - "traefik.http.routers.casconseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.casconseednode.middlewares=compress,secure,casconseednode"
      - "traefik.http.middlewares.cdnseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline' https://seedno.de; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net blob:; img-src 'self' https://seedno.de; media-src 'self' blob:"
      - "traefik.http.routers.cdnseednode.rule=Host(`cdn.seedno.de`)"
      - "traefik.http.routers.cdnseednode.entrypoints=https"
      - "traefik.http.routers.cdnseednode.service=nginx"
      - "traefik.http.routers.cdnseednode.tls=true"
      - "traefik.http.routers.cdnseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.cdnseednode.middlewares=compress,secure,cdnseednode"
      - "traefik.http.middlewares.decoseednode.headers.contentSecurityPolicy=default-src 'self'"
      - "traefik.http.routers.decoseednode.rule=Host(`deco.seedno.de`)"
      - "traefik.http.routers.decoseednode.entrypoints=https"
      - "traefik.http.routers.decoseednode.service=nginx"
      - "traefik.http.routers.decoseednode.tls=true"
      - "traefik.http.routers.decoseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.decoseednode.middlewares=compress,secure,decoseednode"
      - "traefik.http.routers.flashseednode.rule=Host(`flash.seedno.de`)"
      - "traefik.http.routers.flashseednode.entrypoints=https"
      - "traefik.http.routers.flashseednode.service=nginx"
      - "traefik.http.routers.flashseednode.tls=true"
      - "traefik.http.routers.flashseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.flashseednode.middlewares=compress,secure"
      - "traefik.http.middlewares.frozenbutthangcom.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' https://seedno.de; img-src 'self' https://seedno.de"
      - "traefik.http.routers.frozenbutthangcom.rule=Host(`frozenbutthang.com`) || Host(`www.frozenbutthang.com`)"
      - "traefik.http.routers.frozenbutthangcom.entrypoints=https"
      - "traefik.http.routers.frozenbutthangcom.service=nginx"
      - "traefik.http.routers.frozenbutthangcom.tls=true"
      - "traefik.http.routers.frozenbutthangcom.tls.certresolver=letsencrypt"
      - "traefik.http.routers.frozenbutthangcom.middlewares=compress,secure,frozenbutthangcom"
      - "traefik.http.middlewares.gibseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.gibseednode.rule=Host(`gib.seedno.de`)"
      - "traefik.http.routers.gibseednode.entrypoints=https"
      - "traefik.http.routers.gibseednode.service=nginx"
      - "traefik.http.routers.gibseednode.tls=true"
      - "traefik.http.routers.gibseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.gibseednode.middlewares=friendsauth,compress,secure,gibseednode"
      - "traefik.http.middlewares.hugoseednode.headers.contentSecurityPolicy=default-src 'self'; script-src 'self' 'unsafe-inline'"
      - "traefik.http.routers.hugoseednode.rule=Host(`hugo.seedno.de`)"
      - "traefik.http.routers.hugoseednode.entrypoints=https"
      - "traefik.http.routers.hugoseednode.service=nginx"
      - "traefik.http.routers.hugoseednode.tls=true"
      - "traefik.http.routers.hugoseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.hugoseednode.middlewares=compress,secure,hugoseednode"
      - "traefik.http.middlewares.imgseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline' https://seedno.de; script-src 'self' 'unsafe-inline'; font-src 'self' data:; img-src 'self' https://seedno.de"
      - "traefik.http.routers.imgseednode.rule=Host(`img.seedno.de`)"
      - "traefik.http.routers.imgseednode.entrypoints=https"
      - "traefik.http.routers.imgseednode.service=nginx"
      - "traefik.http.routers.imgseednode.tls=true"
      - "traefik.http.routers.imgseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.imgseednode.middlewares=adminauth,compress,secure,imgseednode"
      - "traefik.http.middlewares.justinsinkulacom.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' https://seedno.de; img-src 'self' https://seedno.de"
      - "traefik.http.routers.justinsinkulacom.rule=Host(`justinsinkula.com`) || Host(`www.justinsinkula.com`)"
      - "traefik.http.routers.justinsinkulacom.priority=1"
      - "traefik.http.routers.justinsinkulacom.entrypoints=https"
      - "traefik.http.routers.justinsinkulacom.service=nginx"
      - "traefik.http.routers.justinsinkulacom.tls=true"
      - "traefik.http.routers.justinsinkulacom.tls.certresolver=letsencrypt"
      - "traefik.http.routers.justinsinkulacom.middlewares=compress,secure,justinsinkulacom"
      - "traefik.http.middlewares.logsseednode.headers.contentSecurityPolicy=default-src 'self'"
      - "traefik.http.routers.logsseednode.rule=Host(`logs.seedno.de`)"
      - "traefik.http.routers.logsseednode.entrypoints=https"
      - "traefik.http.routers.logsseednode.service=nginx"
      - "traefik.http.routers.logsseednode.tls=true"
      - "traefik.http.routers.logsseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.logsseednode.middlewares=compress,secure,logsseednode"
      - "traefik.http.middlewares.matrixseednode.headers.contentSecurityPolicy=default-src 'self'"
      - "traefik.http.routers.matrixseednode.rule=Host(`matrix.seedno.de`) && PathPrefix(`/.well-known/matrix/`)"
      - "traefik.http.routers.matrixseednode.entrypoints=https"
      - "traefik.http.routers.matrixseednode.service=nginx"
      - "traefik.http.routers.matrixseednode.tls=true"
      - "traefik.http.routers.matrixseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.matrixseednode.middlewares=compress,secure,matrixseednode"
      - "traefik.http.middlewares.mirrorseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline' https:; script-src 'self' 'unsafe-inline'; font-src 'self' https:; connect-src 'self' https:"
      - "traefik.http.routers.mirrorseednode.rule=Host(`mirror.seedno.de`)"
      - "traefik.http.routers.mirrorseednode.entrypoints=https"
      - "traefik.http.routers.mirrorseednode.service=nginx"
      - "traefik.http.routers.mirrorseednode.tls=true"
      - "traefik.http.routers.mirrorseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.mirrorseednode.middlewares=compress,secure,mirrorseednode"
      - "traefik.http.middlewares.picsseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://seedno.de; font-src 'self' data:; img-src 'self' https://seedno.de"
      - "traefik.http.routers.picsseednode.rule=Host(`pics.seedno.de`)"
      - "traefik.http.routers.picsseednode.entrypoints=https"
      - "traefik.http.routers.picsseednode.service=nginx"
      - "traefik.http.routers.picsseednode.tls=true"
      - "traefik.http.routers.picsseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.picsseednode.middlewares=compress,secure,picsseednode"
      - "traefik.http.middlewares.seednode.headers.contentSecurityPolicy=default-src 'self'; script-src 'self' 'sha256-CrLg5HEtxiJtWQPNGCzTFSY0zEk6/BoA7pa7TdC2KzQ='"
      - "traefik.http.routers.seednode.rule=Host(`seedno.de`) || Host(`www.seedno.de`)"
      - "traefik.http.routers.seednode.priority=1"
      - "traefik.http.routers.seednode.entrypoints=https"
      - "traefik.http.routers.seednode.service=nginx"
      - "traefik.http.routers.seednode.tls=true"
      - "traefik.http.routers.seednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.seednode.middlewares=compress,secure,seednode"
      - "traefik.http.middlewares.statsseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline' https://*.seedno.de; script-src 'self' https://*.seedno.de; font-src 'self' https://*.seedno.de; connect-src 'self' https://*.seedno.de"
      - "traefik.http.routers.statsseednode.rule=Host(`stats.seedno.de`)"
      - "traefik.http.routers.statsseednode.priority=1"
      - "traefik.http.routers.statsseednode.entrypoints=https"
      - "traefik.http.routers.statsseednode.service=nginx"
      - "traefik.http.routers.statsseednode.tls=true"
      - "traefik.http.routers.statsseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.statsseednode.middlewares=compress,secure,statsseednode"
      - "traefik.http.middlewares.syncseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline' https://seedno.de; img-src 'self' https://seedno.de"
      - "traefik.http.routers.syncseednode.rule=Host(`sync.seedno.de`)"
      - "traefik.http.routers.syncseednode.entrypoints=https"
      - "traefik.http.routers.syncseednode.service=nginx"
      - "traefik.http.routers.syncseednode.tls=true"
      - "traefik.http.routers.syncseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.syncseednode.middlewares=compress,secure,syncseednode"
      - "traefik.http.middlewares.ttyseednode.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'sha256-k8Gt4ydPyZBh2YfRzVWrh7031fvz/VI3cHeGzcyXNR0=' 'sha256-VwEY7val4b+j8yqYQs9EMxGA1WRNoWDizHNeHzHCjAU=' 'sha256-ZjbbycUVTww9AXSPtpbF6WEV6bbCMIwMXlb/vq8bQRI=' https://seedno.de; img-src 'self' https://seedno.de; media-src 'self' data:"
      - "traefik.http.routers.ttyseednode.rule=Host(`tty.seedno.de`)"
      - "traefik.http.routers.ttyseednode.entrypoints=https"
      - "traefik.http.routers.ttyseednode.service=nginx"
      - "traefik.http.routers.ttyseednode.tls=true"
      - "traefik.http.routers.ttyseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.ttyseednode.middlewares=compress,secure,ttyseednode"
      - "traefik.http.services.nginx.loadbalancer.server.port=80"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /home/sinc/traefik/nginx-logs
        target: /var/log/nginx
      - type: bind
        source: /home/sinc/traefik/nginx
        target: /etc/nginx
        read_only: true
      - type: bind
        source: /var/www/html
        target: /var/www/html
        read_only: true
      - type: volume
        source: linx-files
        target: /files
        read_only: true
      - type: bind
        source: /storage
        target: /storage
        read_only: true
      - type: bind
        source: /home/sinc/photos/miscellaneous
        target: /miscellaneous
        read_only: true
      - type: bind
        source: /home/sinc/gmn
        target: /gmn
        read_only: true
      - type: bind
        source: /home/sinc/audio
        target: /music
        read_only: true
      - type: bind
        source: /home/sinc/DavidRovicsYoutubeArchive
        target: /davidrovics
        read_only: true
      - type: bind
        source: /home/sinc/share
        target: /gib
        read_only: true

  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: always
    depends_on:
      - gitea-db
    environment:
      - "TMPDIR=/data/backups"
      - "USER_UID=1004"
      - "USER_GID=1004"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.gitea.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; font-src 'self' data:; img-src 'self' https: data:"
      - "traefik.http.routers.gitea-web.rule=Host(`git.seedno.de`)"
      - "traefik.http.routers.gitea-web.entrypoints=https"
      - "traefik.http.routers.gitea-web.service=gitea-web"
      - "traefik.http.routers.gitea-web.tls=true"
      - "traefik.http.routers.gitea-web.tls.certresolver=letsencrypt"
      - "traefik.http.routers.gitea-web.middlewares=compress,secure,gitea"
      - "traefik.http.services.gitea-web.loadbalancer.server.port=3000"
      - "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.gitea-ssh.entrypoints=gitea"
      - "traefik.tcp.routers.gitea-ssh.service=gitea-ssh"
      - "traefik.tcp.services.gitea-ssh.loadbalancer.server.port=22"
    networks:
      - traefik
    volumes:
      - type: volume
        source: gitea
        target: /data
      - type: bind
        source: /etc/timezone
        target: /etc/timezone
        read_only: true
      - type: bind
        source: /etc/localtime
        target: /etc/localtime
        read_only: true

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - GITEA_DB_USER
  # - GITEA_DB_PASS
  gitea-db:
    image: postgres:alpine
    container_name: gitea-db
    restart: always
    environment:
      - "POSTGRES_DB=gitea"
      - "POSTGRES_USER=${GITEA_DB_USER}"
      - "POSTGRES_PASSWORD=${GITEA_DB_PASS}"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: gitea-db
        target: /var/lib/postgresql/data

  netdata:
    image: netdata/netdata:latest
    container_name: netdata
    hostname: netdata.seedno.de
    restart: always
    cap_add:
      - "SYS_PTRACE"
    security_opt:
      - "apparmor:unconfined"
    labels:
      - "logspout.exclude=true"
      - "traefik.enable=true"
      - "traefik.http.middlewares.netdata.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; img-src 'self' data:; connect-src 'self' https://registry.my-netdata.io https://www.googleapis.com; frame-src 'self' https://app.netdata.cloud"
      - "traefik.http.routers.netdata.rule=Host(`netdata.seedno.de`)"
      - "traefik.http.routers.netdata.entrypoints=https"
      - "traefik.http.routers.netdata.service=netdata"
      - "traefik.http.routers.netdata.tls=true"
      - "traefik.http.routers.netdata.tls.certresolver=letsencrypt"
      - "traefik.http.routers.netdata.middlewares=compress,secure,netdata"
      - "traefik.http.services.netdata.loadbalancer.server.port=19999"
    networks:
      - traefik
    volumes:
      - type: bind
        source: /proc
        target: /host/proc
        read_only: true
      - type: bind
        source: /sys
        target: /host/sys
        read_only: true

  unifi:
    image: jacobalberty/unifi:latest
    container_name: unifi
    restart: always
    environment:
    - "BIND_PRIV=false"
    - "RUNAS_UID0=false"
    - "UNIFI_UID=${UID}"
    - "UNIFI_GID=${GID}"
    - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.unifi-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.unifi-redirect.redirectscheme.permanent=true"
      - "traefik.http.middlewares.unifi.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; img-src 'self' data: static.ubnt.com"
      - "traefik.http.routers.unifi.rule=Host(`unifi.seedno.de`)"
      - "traefik.http.routers.unifi.entrypoints=https"
      - "traefik.http.routers.unifi.tls=true"
      - "traefik.http.routers.unifi.tls.certresolver=letsencrypt"
      - "traefik.http.routers.unifi.middlewares=compress,secure,unifi-redirect,unifi"
      - "traefik.http.services.unifi.loadbalancer.server.port=8443"
      - "traefik.http.services.unifi.loadbalancer.server.scheme=https"
      - "traefik.tcp.routers.unifi-comms.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.unifi-comms.entrypoints=unifi-comms"
      - "traefik.tcp.routers.unifi-comms.service=unifi-comms"
      - "traefik.tcp.routers.unifi-https.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.unifi-https.entrypoints=unifi-https"
      - "traefik.tcp.routers.unifi-https.service=unifi-https"
      - "traefik.tcp.routers.unifi-http.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.unifi-http.entrypoints=unifi-http"
      - "traefik.tcp.routers.unifi-http.service=unifi-http"
      - "traefik.tcp.services.unifi-comms.loadbalancer.server.port=8080"
      - "traefik.tcp.services.unifi-https.loadbalancer.server.port=8843"
      - "traefik.tcp.services.unifi-http.loadbalancer.server.port=8880"
      - "traefik.udp.routers.unifi-stun.entrypoints=unifi-stun"
      - "traefik.udp.routers.unifi-stun.service=unifi-stun"
      - "traefik.udp.routers.unifi-discovery.entrypoints=unifi-discovery"
      - "traefik.udp.routers.unifi-discovery.service=unifi-discovery"
      - "traefik.udp.services.unifi-stun.loadbalancer.server.port=3478"
      - "traefik.udp.services.unifi-discovery.loadbalancer.server.port=10001"
    networks:
      - traefik
    volumes:
      - type: volume
        source: unifi
        target: /unifi

  thelounge:
    image: ghcr.io/linuxserver/thelounge:latest
    container_name: thelounge
    restart: always
    environment:
      - "PUID=${UID}"
      - "PGID=${GID}"
      - "TZ=${TIMEZONE}"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.thelounge.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='"
      - "traefik.http.routers.thelounge.rule=Host(`chat.seedno.de`)"
      - "traefik.http.routers.thelounge.entrypoints=https"
      - "traefik.http.routers.thelounge.service=thelounge"
      - "traefik.http.routers.thelounge.tls=true"
      - "traefik.http.routers.thelounge.tls.certresolver=letsencrypt"
      - "traefik.http.routers.thelounge.middlewares=compress,secure,thelounge"
      - "traefik.http.services.thelounge.loadbalancer.server.port=9000"
    networks:
      - traefik
    volumes:
      - type: volume
        source: thelounge
        target: /config

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - SIST2_PRIVATE_USER
  # - SIST2_PRIVATE_PASS
  sist2-private:
    image: simon987/sist2:latest
    container_name: sist2-private
    restart: always
    depends_on:
      - sist2-elasticsearch
    command:
      - "web"
      - "--bind=0.0.0.0:4321"
      - "--es-url=http://sist2-elasticsearch:9200"
      - "--es-index=private"
      - "--tag-auth=${SIST2_PRIVATE_USER}:${SIST2_PRIVATE_PASS}"
      - "/index/davidrovics_audio"
      - "/index/davidrovics_video"
      - "/index/gmn"
      - "/index/misc"
      - "/index/music"
      - "/index/skyrim"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.privateseednode.headers.contentSecurityPolicy=default-src 'self' cdn.seedno.de; style-src 'self' 'unsafe-inline'; img-src 'self' data: cdn.seedno.de"
      - "traefik.http.routers.privateseednode.rule=Host(`private.seedno.de`)"
      - "traefik.http.routers.privateseednode.entrypoints=https"
      - "traefik.http.routers.privateseednode.service=privateseednode"
      - "traefik.http.routers.privateseednode.tls=true"
      - "traefik.http.routers.privateseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.privateseednode.middlewares=adminauth,compress,secure,privateseednode"
      - "traefik.http.services.privateseednode.loadbalancer.server.port=4321"
    networks:
      - traefik
    volumes:
      - type: volume
        source: sist2-private
        target: /index

  # The following variables should be set in a file named .env in the same directory as docker-compose.yml:
  # - SIST2_PUBLIC_USER
  # - SIST2_PUBLIC_PASS
  sist2-public:
    image: simon987/sist2:latest
    container_name: sist2-public
    restart: always
    depends_on:
      - sist2-elasticsearch
    command:
      - "web"
      - "--bind=0.0.0.0:4321"
      - "--es-url=http://sist2-elasticsearch:9200"
      - "--es-index=public"
      - "--tag-auth=${SIST2_PUBLIC_USER}:${SIST2_PUBLIC_PASS}"
      - "/index/cdn"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.publicseednode.headers.contentSecurityPolicy=default-src 'self' cdn.seedno.de; style-src 'self' 'unsafe-inline'; img-src 'self' data: cdn.seedno.de"
      - "traefik.http.routers.publicseednode.rule=Host(`public.seedno.de`)" 
      - "traefik.http.routers.publicseednode.entrypoints=https"
      - "traefik.http.routers.publicseednode.service=publicseednode"
      - "traefik.http.routers.publicseednode.tls=true"
      - "traefik.http.routers.publicseednode.tls.certresolver=letsencrypt"
      - "traefik.http.routers.publicseednode.middlewares=compress,secure,publicseednode"
      - "traefik.http.services.publicseednode.loadbalancer.server.port=4321"
    networks:
      - traefik
    volumes:
      - type: volume
        source: sist2-public
        target: /index

  sist2-elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.9.3
    container_name: sist2-elasticsearch
    restart: always
    environment:
      - "discovery.type=single-node"
      - "ES_JAVA_OPTS=-Xms1G -Xmx8G"
    labels:
      - "traefik.enable=false"
    networks:
      - traefik
    volumes:
      - type: volume
        source: sist2-elasticsearch
        target: /usr/share/elasticsearch/data

  # The authfile should be generated with `htpasswd -c /data/auth/authfile [username]` inside the container
  linx:
    image: docker.seedno.de/seednode/linx
    container_name: linx
    restart: always
    entrypoint:
      - "/usr/local/bin/linx-server"
      - "-bind=0.0.0.0:8080"
      - "-filespath=/data/files/"
      - "-metapath=/data/meta/"
      - "-sitename=Seednode Sharing Server (S3)"
      - "-siteurl=https://share.seedno.de/"
      - "-selifpath=files"
      - "-authfile=/data/auth/authfile"
      - "-basicauth"
      - "-maxsize=50000000"
      - "-maxexpiry=86400"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.linx.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
      - "traefik.http.routers.linx.rule=Host(`share.seedno.de`)"
      - "traefik.http.routers.linx.entrypoints=https"
      - "traefik.http.routers.linx.service=linx"
      - "traefik.http.routers.linx.tls=true"
      - "traefik.http.routers.linx.tls.certresolver=letsencrypt"
      - "traefik.http.routers.linx.middlewares=compress,secure,linx"
      - "traefik.http.services.linx.loadbalancer.server.port=8080"
    networks:
      - traefik
    volumes:
      - type: volume
        source: linx-files
        target: /data/files
      - type: volume
        source: linx-metadata
        target: /data/meta
      - type: volume
        source: linx-auth
        target: /data/auth

  syncthing:
    image: ghcr.io/linuxserver/syncthing:latest
    container_name: syncthing
    restart: always
    environment:
      - "PUID=33"
      - "PGID=33"
      - "TZ=${TIMEZONE}"
      - "UMASK_SET=022"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.syncthing.headers.contentSecurityPolicy=default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'"
      - "traefik.http.routers.syncthing-gui.rule=Host(`sync.gate.seedno.de`)"
      - "traefik.http.routers.syncthing-gui.entrypoints=https"
      - "traefik.http.routers.syncthing-gui.service=syncthing-gui"
      - "traefik.http.routers.syncthing-gui.tls=true"
      - "traefik.http.routers.syncthing-gui.tls.certresolver=letsencrypt"
      - "traefik.http.routers.syncthing-gui.middlewares=adminauth,compress,secure,syncthing,whitelist@file"
      - "traefik.http.services.syncthing-gui.loadbalancer.server.port=8384"
      - "traefik.tcp.routers.syncthing-sync.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.syncthing-sync.entrypoints=syncthing"
      - "traefik.tcp.routers.syncthing-sync.service=syncthing-sync"
      - "traefik.tcp.services.syncthing-sync.loadbalancer.server.port=22000"
    networks:
      - traefik
    volumes:
      - type: volume
        source: syncthing
        target: /config
      - type: bind
        source: /storage
        target: /storage

networks:
  traefik:
    name: traefik
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br_traefik
    ipam:
      driver: default
      config:
        - subnet: 10.160.0.0/22

volumes:
  gitea:
  gitea-db:
  traefik:
  bitwarden:
  bitwarden-db:
  unifi:
  thelounge:
  sist2-public:
  sist2-private:
  sist2-elasticsearch:
  linx-files:
  linx-metadata:
  linx-auth:
  syncthing:
  code-server:
  ghost:
  ghost-db:
  mosquitto-conf:
  mosquitto-data:
  mosquitto-log:
  netbox-config:
  netbox-redis:
  netbox-db:
  qbittorrent:
  guac-db:
  rtmp-streams:
  rtmp-log:
  snapdrop:
  pihole-conf:
  pihole-dnsmasq:
  phpbb-conf:
  phpbb-db:
  hastebin:
  pastebin:
  pleroma:
  pleroma-db:
  synapse-data:
  synapse-media:
  synapse-uploads:
  synapse-db:
  mediawiki:
  mediawiki-db:
  glulxe:
  coloratura:
  polaris:
  youtube-dl:
  bookstack:
  bookstack-db:
  prometheus:
  grafana:
  smokeping: