Перейти к содержанию

▍Все контейнеры в docker-compose.yml

Подготовительный этап

Создадим структуру директорий:

sudo mkdir -p /srv/{docker/{conf,build},data,www,logs}

Зададим переменные с нашими директориями:

/srv/docker/.env
DIR_CONF=/srv/docker/conf
DIR_BUILD=/srv/docker/build
DIR_DATA=/srv/data
DIR_WWW=/srv/www
DIR_LOGS=/srv/logs

Docker-compose.yml

Устанавливаем вторую версию Docker compose

$ sudo curl -SL https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

$ sudo chmod +x /usr/local/bin/docker-compose

$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

$ docker-compose -v
Docker Compose version v2.15.1

/srv/docker/docker-compose.yml
# Пропишем версию
version: "3.9"

# Перечислим сервисы
services:
  authelia:
    image: authelia/authelia
    container_name: authelia
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_CONF/authelia:/config
    environment:
      - TZ=Europe/Moscow
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.authelia.rule=Host(`authelia.example.ru`)'
      - 'traefik.http.routers.authelia.entrypoints=https'
      - 'traefik.http.routers.authelia.tls=true'
      - 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://authelia.example.ru/'
      - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
      - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email'
      - 'traefik.http.middlewares.authelia-basic.forwardauth.address=http://authelia:9091/api/verify?auth=basic'
      - 'traefik.http.middlewares.authelia-basic.forwardauth.trustForwardHeader=true'
      - 'traefik.http.middlewares.authelia-basic.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email'

  traefik:
    image: traefik:latest
    container_name: traefik
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    security_opt:
      - no-new-privileges:true
    ports:
      - 192.168.0.111:80:80
      - 192.168.0.111:443:443/tcp
      - 192.168.0.111:443:443/udp
    depends_on:
      - authelia    
    environment:
      - SELECTEL_API_TOKEN=EfRBHW6kKKDJfAd3ynSf7GEPZSesuXUJd
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - $DIR_CONF/traefik/traefik.yml:/traefik.yml:ro
      - $DIR_CONF/traefik/acme.json:/acme.json
      - $DIR_CONF/traefik/custom/:/custom/:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.ru`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=traefik:$$apr1$$2Zn1nUu4$$pkolhgkp1KRDht2do7N/1." # echo $(htpasswd -nb traefik passw0rd) | sed -e s/\\$/\\$\\$/g
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.ru`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=selectel"
      - "traefik.http.routers.traefik-secure.tls.domains[0].main=example.ru"
      - "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.example.ru"
      - "traefik.http.middlewares.WhitelistHome.ipwhitelist.sourcerange=172.18.0.0/24, 192.168.0.0/16, 172.20.0.0/24"
      - "traefik.http.routers.traefik-secure.service=api@internal"

### SITES
  mysql:
    image: mariadb:10.8
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-S", "/var/lib/mysql/mysqld.sock", "--silent"]
      interval: 5s
      timeout: 5s
      retries: 10
    ports:
      - "3306:3306"
    volumes:
      - $DIR_CONF/50-server.cnf:/etc/mysql/mariadb.conf.d/50-server.cnf
      - $DIR_DATA/mysql:/var/lib/mysql
      - /etc/localtime:/etc/localtime:ro

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin
    environment:
      - PMA_ARBITRARY=0
      - PMA_HOSTS=mysql
      - UPLOAD_LIMIT=100M
      - HIDE_PHP_VERSION=true
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_CONF/phpmyadmin/session:/sessions
      - /etc/localtime:/etc/localtime:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pma.tls=true"
      - "traefik.http.routers.pma.rule=Host(`pma.example.ru`)"
      - "traefik.http.routers.pma.middlewares=WhitelistHome"
      - "traefik.http.services.pma.loadbalancer.server.port=80"
      - "com.centurylinklabs.watchtower.enable=true"

  nginx:
    image: nginx:latest
    container_name: nginx
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    ports:
      - "192.168.0.200:80:80"
    volumes:
      - $DIR_WWW:/www
      - $DIR_CONF/nginx/misc:/etc/nginx/misc
      - $DIR_CONF/nginx/nginx.conf:/etc/nginx/nginx.conf
      - $DIR_CONF/nginx/conf.d:/etc/nginx/conf.d
      - $DIR_CONF/nginx/sites-available:/etc/nginx/sites-available
      - $DIR_CONF/nginx/sites-enabled:/etc/nginx/sites-enabled
      - $DIR_LOGS/nginx:/var/log/nginx
      - /etc/localtime:/etc/localtime:ro
    depends_on:
      - php56        
      - php7
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.rule=Host(`example.ru`, `site.example.ru`)"
      - "traefik.http.routers.nginx.entrypoints=https"
      - "traefik.http.routers.nginx.middlewares=default-headers@file"
      - "traefik.http.routers.nginx.tls=true"
      - "traefik.http.services.nginx.loadbalancer.server.port=80"
      - "com.centurylinklabs.watchtower.enable=true"

   php56:
        image: daffin/php5.6-fpm
        build: $DIR_BUILD/php56
        container_name: php56
        restart: always
        volumes:
          - $DIR_WWW/site.example.ru:/www/site.example.ru
          - $DIR_CONF/php-fpm/www.conf:/usr/local/etc/php-fpm.d/www.conf
          - $DIR_LOGS/php-fpm/php56:/var/log/php
          - /etc/localtime:/etc/localtime:ro

   php7:
        image: daffin/php7.3-fpm
        build: $DIR_BUILD/php73
        container_name: php7
        restart: always
        volumes:
          - $DIR_WWW/example.ru:/www/example.ru
          - $DIR_LOGS/php-fpm/php7:/var/log/php
          - /etc/localtime:/etc/localtime:ro

  api:
    image: daffin/api.example.ru # node16-alpine
    container_name: api
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.ru`)"
      - "traefik.http.routers.api.entrypoints=https"
      - "traefik.http.routers.api.tls=true"
      - "traefik.http.routers.api.middlewares=api,WhitelistHome"
      - "traefik.http.middlewares.api.headers.accesscontrolalloworiginlist=https://test.example.ru,https://api.example.ru"
      - "traefik.http.middlewares.api.headers.accesscontrolallowmethods=POST"
      - "traefik.http.middlewares.api.headers.accesscontrolmaxage=100"
      - "traefik.http.middlewares.api.headers.addvaryheader=true"
      - "traefik.http.services.api.loadbalancer.server.port=3001"
      - "com.centurylinklabs.watchtower.enable=true"

  redis:
    image: redis:5.0-alpine
    container_name: redis
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    command: redis-server --appendonly yes
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
    volumes:
      - $DIR_DATA/redis:/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "6379:6379"

  trilium:
    image: zadam/trilium:0.45-latest
    container_name: trilium
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      - TRILIUM_DATA_DIR=/data
    volumes:
      - $DIR_DATA/trilium:/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.trilium.rule=Host(`notes.example.ru`)"
      - "traefik.http.routers.trilium.entrypoints=https"
      - "traefik.http.routers.trilium.tls=true"
      - "traefik.http.routers.trilium.middlewares=authelia@docker"
      - "traefik.http.services.trilium.loadbalancer.server.port=8080"
      - "com.centurylinklabs.watchtower.enable=true"

### DEVELOPMENT
  codeserver:
    image: codercom/code-server
    container_name: codeserver
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    command: --auth none --disable-telemetry
    volumes:
      - $DIR_CONF/codeserver/coder:/home/coder
      - /etc/localtime:/etc/localtime:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.codeserver.tls=true"
      - "traefik.http.routers.codeserver.rule=Host(`codeserver.example.ru`)"
      - "traefik.http.routers.codeserver.middlewares=WhitelistHome,authelia@docker"
      - "traefik.http.services.codeserver.loadbalancer.server.port=8080"
      - "com.centurylinklabs.watchtower.enable=true"

  gitlab:
    image: gitlab/gitlab-ce:latest
    container_name: gitlab
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.example.ru'
        nginx['listen_port'] = 80
        nginx['listen_https'] = false
        nginx['proxy_set_headers'] = {
        "X-Forwarded-Proto" => "https",
        "X-Forwarded-Ssl" => "on"
         }
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "smtp.mail.ru"
        gitlab_rails['smtp_port'] = 465
        gitlab_rails['smtp_user_name'] = "[email protected]"
        gitlab_rails['smtp_password'] = "PASSWORD"
        gitlab_rails['smtp_domain'] = "mail.ru"
        gitlab_rails['smtp_authentication'] = "login"
        gitlab_rails['smtp_enable_starttls_auto'] = false
        gitlab_rails['smtp_tls'] = true
        gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
        gitlab_rails['gitlab_email_from'] = '[email protected]'
        gitlab_rails['gitlab_email_reply_to'] = '[email protected]'
    ports:
      - "2222:22"
    shm_size: '256m'
    volumes:
      - $DIR_CONF/gitlab:/etc/gitlab
      - $DIR_DATA/gitlab:/var/opt/gitlab
      - /etc/localtime:/etc/localtime:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.gitlab.tls=true"
      - "traefik.http.routers.gitlab.rule=Host(`gitlab.example.ru`)"
      - "traefik.http.routers.gitlab.middlewares=WhitelistHome"
      - "traefik.http.services.gitlab.loadbalancer.server.port=80"
      - "com.centurylinklabs.watchtower.enable=true"

  gitlab-runner:
    image: 'gitlab/gitlab-runner:latest'
    container_name: gitlab-runner
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    links:
      - gitlab
    volumes:
      - $DIR_CONF/gitlab-runner:/etc/gitlab-runner
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/localtime:/etc/localtime:ro
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

### LOCAL ARCHIVE
  archivebox:
    image: archivebox/archivebox
    container_name: archivebox
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_DATA/archivebox:/data
    environment:
      - ALLOWED_HOSTS=*
      - MEDIA_MAX_SIZE=750m
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.archivebox.tls=true"
      - "traefik.http.routers.archivebox.rule=Host(`archive.example.ru`)"
      - "traefik.http.routers.archivebox.middlewares=WhitelistHome,authelia@docker"
      - "traefik.http.services.archivebox.loadbalancer.server.port=8000"
      - "com.centurylinklabs.watchtower.enable=true"

  archivebox-cron:
    image: archivebox/archivebox
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    command: schedule --foreground --every=hour --depth=1 https://getpocket.com/users/LOGIN/feed/all
    volumes:
      - $DIR_DATA/archivebox:/data
    environment:
      - USE_COLOR=True
      - SHOW_PROGRESS=False

  ytdl_material:
    image: tzahi12345/youtubedl-material:latest
    container_name: ytdl_material
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      - ALLOW_CONFIG_MUTATIONS=true
      - ytdl_use_local_db=true
      - write_ytdl_config=true
    volumes:
      - $DIR_CONF/ytdl/appdata:/app/appdata
      - $DIR_MEDIA/YOUTUBE:/app/video
      - $DIR_CONF/ytdl/subscriptions:/app/subscriptions
      - $DIR_CONF/ytdl/users:/app/users
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ytdl.rule=Host(`ytdl.example.ru`)"
      - "traefik.http.routers.ytdl.entrypoints=https"
      - "traefik.http.routers.ytdl.tls=true"
      - "traefik.http.routers.ytdl.middlewares=WhitelistHome,authelia@docker"
      - "traefik.http.services.ytdl.loadbalancer.server.port=17442"
      - "com.centurylinklabs.watchtower.enable=true"

  kiwix:
    image: kiwix/kiwix-serve
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: kiwix
    volumes:
      - $DIR_BIGDATA/wikipedia:/data
    command:
      wikipedia_ru_all_maxi_2022-12.zim
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.kiwix.tls=true"
      - "traefik.http.routers.kiwix.rule=Host(`wikipedia.example.ru`)"
      - "traefik.http.routers.kiwix.middlewares=WhitelistHome"
      - "traefik.http.services.kiwix.loadbalancer.server.port=8080"

  calibre:
    image: linuxserver/calibre:latest
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: calibre
    volumes:
      - $DIR_CONF/calibre:/config
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Moscow
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.calibre.tls=true"
      - "traefik.http.routers.calibre.rule=Host(`calibre.example.ru`)"
      - "traefik.http.routers.calibre.middlewares=WhitelistHome"
      - "traefik.http.services.calibre.loadbalancer.server.port=8081" # port=8080 web-gui xrdp

  aptmirror:
    image: daffin/apt-mirror
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: aptmirror
    volumes:
      - $DIR_DATA/apt-mirror:/apt-mirror
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.aptmirror.tls=true"
      - "traefik.http.routers.aptmirror.rule=Host(`mirror.example.ru`)"
      - "traefik.http.routers.aptmirror.middlewares=WhitelistHome"
      - "traefik.http.services.aptmirror.loadbalancer.server.port=80"

### MEDIA & GAMES
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - $DIR_WWW/nextcloud.example.ru:/var/www/html
      - $DIR_DATA/nextcloud:/data
    depends_on:
      - mysql
      - redis
    environment:
      REDIS_HOST: redis
      MYSQL_HOST: mysql:3306
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: PASSWORD
      TRUSTED_PROXIES: traefik
      NEXTCLOUD_TRUSTED_DOMAINS: nextcloud.example.ru
      NEXTCLOUD_DATA_DIR: /data
      SMTP_HOST: smtp.mail.ru
      SMTP_SECURE: tls
      SMTP_PORT: 587
      SMTP_NAME: [email protected]
      SMTP_PASSWORD: PASSWORD
      MAIL_FROM_ADDRESS: [email protected]
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.middlewares=nextcloud,nextcloud_redirect"
      - "traefik.http.routers.nextcloud.tls=true"
      - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.example.ru`)"
      - "traefik.http.routers.nextcloud.middlewares=default-headers@file,nextcloud_redirect"
      - "traefik.http.middlewares.nextcloud.headers.customFrameOptionsValue=ALLOW-FROM https://nextcloud.example.ru"
      - "traefik.http.middlewares.nextcloud.headers.contentSecurityPolicy=frame-ancestors 'self' nextcloud.example.ru *.example.ru"
      - "traefik.http.middlewares.nextcloud_redirect.redirectregex.permanent=true"
      - "traefik.http.middlewares.nextcloud_redirect.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav"
      - "traefik.http.middlewares.nextcloud_redirect.redirectregex.replacement=https://$${1}/remote.php/dav/"

  photoprism:
    image: photoprism/photoprism:latest
    container_name: photoprism
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    depends_on:
      - mysql
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    environment:
      PHOTOPRISM_ADMIN_PASSWORD: ""                  # INITIAL PASSWORD FOR "admin" USER, MINIMUM 8 CHARACTERS
      PHOTOPRISM_AUTH_MODE: "public"                 # authentication mode (public, password)
      PHOTOPRISM_SITE_URL: "https://photoprism.example.ru/"  # public server URL incl http:// or https:// and /path, :port is optional
      PHOTOPRISM_ORIGINALS_LIMIT: 5000               # file size limit for originals in MB (increase for high-res video)
      PHOTOPRISM_HTTP_COMPRESSION: "gzip"            # improves transfer speed and bandwidth utilization (none or gzip)
      PHOTOPRISM_LOG_LEVEL: "info"                   # log level: trace, debug, info, warning, error, fatal, or panic
      PHOTOPRISM_READONLY: "false"                   # do not modify originals directory (reduced functionality)
      PHOTOPRISM_EXPERIMENTAL: "false"               # enables experimental features
      PHOTOPRISM_DISABLE_CHOWN: "false"              # disables updating storage permissions via chmod and chown on startup
      PHOTOPRISM_DISABLE_WEBDAV: "false"             # disables built-in WebDAV server
      PHOTOPRISM_DISABLE_SETTINGS: "false"           # disables settings UI and API
      PHOTOPRISM_DISABLE_TENSORFLOW: "true"          # disables all features depending on TensorFlow
      PHOTOPRISM_DISABLE_FACES: "true"               # disables face detection and recognition (requires TensorFlow)
      PHOTOPRISM_DISABLE_CLASSIFICATION: "true"      # disables image classification (requires TensorFlow)
      PHOTOPRISM_DISABLE_RAW: "false"                # disables indexing and conversion of RAW files
      PHOTOPRISM_RAW_PRESETS: "false"                # enables applying user presets when converting RAW files (reduces performance)
      PHOTOPRISM_JPEG_QUALITY: 85                    # a higher value increases the quality and file size of JPEG images and thumbnails (25-100)
      PHOTOPRISM_DETECT_NSFW: "false"                # automatically flags photos as private that MAY be offensive (requires TensorFlow)
      PHOTOPRISM_UPLOAD_NSFW: "true"                 # allows uploads that MAY be offensive (no effect without TensorFlow)
      PHOTOPRISM_DATABASE_DRIVER: "mysql"            # use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
      PHOTOPRISM_DATABASE_SERVER: "mysql:3306"       # MariaDB or MySQL database server (hostname:port)
      PHOTOPRISM_DATABASE_NAME: "photoprism"         # MariaDB or MySQL database schema name
      PHOTOPRISM_DATABASE_USER: "photoprism"         # MariaDB or MySQL database user name
      PHOTOPRISM_DATABASE_PASSWORD: "PASSWORD"       # MariaDB or MySQL database user password
      PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
      PHOTOPRISM_SITE_DESCRIPTION: ""                # meta site description
      PHOTOPRISM_SITE_AUTHOR: ""                     # meta site author
      PHOTOPRISM_DEFAULT_LOCALE: "ru"
    working_dir: "/photoprism" # do not change or remove
    volumes:
      - "$DIR_DATA/FOTO:/photoprism/originals"               # Original media files (DO NOT REMOVE)
      - "$DIR_DATA/PHONE:/photoprism/originals/phone:ro"
      - "$DIR_CONF/photoprism/storage:/photoprism/storage"                              # *Writable* storage folder for cache, database, and sidecar files (DO NOT REMOVE)
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.photoprism.rule=Host(`photoprism.example.ru`)"
      - "traefik.http.routers.photoprism.entrypoints=https"
      - "traefik.http.routers.photoprism.tls=true"
      - "traefik.http.routers.photoprism.middlewares=WhitelistHome,authelia@docker"
      - "traefik.http.services.photoprism.loadbalancer.server.port=2342"
      - "com.centurylinklabs.watchtower.enable=true"

  jellyfin:
    image: jellyfin/jellyfin
    container_name: jellyfin
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_CONF/jellyfin/config:/config
      - $DIR_MEDIA/ФИЛЬМЫ:/data/movies:ro
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Moscow
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.jellyfin.rule=Host(`jellyfin.example.ru`)"
      - "traefik.http.routers.jellyfin.entrypoints=https"
      - "traefik.http.routers.jellyfin.tls=true"
      - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
      - "traefik.http.routers.jellyfin.middlewares=WhitelistHome,default-headers@file"
      - "com.centurylinklabs.watchtower.enable=true"

  rutorrent:
    image: linuxserver/rutorrent
    container_name: rutorrent
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      - PUID=1000
      - PGID=1000
    ports:
      - 51413:51413
      - 6881:6881/udp
    volumes:
      - $DIR_CONF/rutorrent:/config
      - $DIR_MEDIA/TORRENTS:/downloads
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.rutorrent.rule=Host(`torrents.example.ru`)"
      - "traefik.http.routers.rutorrent.entrypoints=https"
      - "traefik.http.routers.rutorrent.tls=true"
      - "traefik.http.routers.rutorrent.middlewares=WhitelistHome"
      - "com.centurylinklabs.watchtower.enable=true"

  ps3netsrv:
    image: daffin/ps3netsrv
    build: $DIR_BUILD/ps3netsrv
    container_name: ps3netsrv
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    ports:
      - 38008:38008
    volumes:
      - $DIR_DATA/PS3ISO:/games
    environment:
      - TZ=Europe/Moscow
      - USER_ID=1000
      - GROUP_ID=888

  minecraft:
    image: daffin/minecraft
    build: $DIR_BUILD/maincraft
    container_name: minecraft
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    ports:
      - 25565:25565
      - 25565:25565/udp
    volumes:
      - $DIR_DATA/minecraft:/data
      - /etc/localtime:/etc/localtime:ro

### UTILS
  heimdall:
    image: linuxserver/heimdall:latest
    container_name: heimdall
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Moscow
    volumes:
      - $DIR_CONF/heimdall:/config
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.heimdall.rule=Host(`heimdall.example.ru`)"
      - "traefik.http.routers.heimdall.entrypoints=https"
      - "traefik.http.routers.heimdall.tls=true"
      - "traefik.http.routers.heimdall.middlewares=WhitelistHome,authelia@docker"
      - "com.centurylinklabs.watchtower.enable=true"

  vault:
    image: vault
    container_name: vault
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    command: vault server -config=/vault/config/vault.json
    environment:
      - VAULT_ADDR=http://0.0.0.0:8200
      - VAULT_API_ADDR=http://0.0.0.0:8200
      - VAULT_ADDRESS=http://0.0.0.0:8200
    volumes:
      - $DIR_CONF/vault:/vault
      - $DIR_CONF/vault/file:/vault/file
    cap_add:
      - IPC_LOCK
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vault.rule=Host(`vault.example.ru`)"
      - "traefik.http.routers.vault.entrypoints=https"
      - "traefik.http.routers.vault.tls=true"
      - "traefik.http.routers.vault.middlewares=WhitelistHome"
      - "traefik.http.services.vault.loadbalancer.server.port=8200"
      - "com.centurylinklabs.watchtower.enable=true"

  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      - WEBSOCKET_ENABLED=true  # Enable WebSocket notifications.
      - SIGNUPS_ALLOWED=false
    volumes:
      - $DIR_CONF/vaultwarden:/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vaultwarden.tls=true"
      - "traefik.http.routers.vaultwarden.middlewares=default-headers@file"
      - "traefik.http.routers.vaultwarden.rule=Host(`vaultwarden.example.ru`)"

  portainer:
    image: portainer/portainer-ce
    container_name: portainer
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    security_opt:
      - no-new-privileges:true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - $DIR_CONF/portainer/data:/data
      - $DIR_CONF/portainer/shared:/shared
      - /etc/localtime:/etc/localtime:ro
    environment:
      - TZ=Europe/Moscow
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.portainer.tls=true"
      - "traefik.http.routers.portainer.rule=Host(`portainer.example.ru`)"
      - "traefik.http.routers.portainer.middlewares=WhitelistHome,authelia@docker"
      - "traefik.http.services.portainer.loadbalancer.server.port=9000"
      - "com.centurylinklabs.watchtower.enable=true"

  pihole:
    image: pihole/pihole:latest
    container_name: pihole
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    ports:
      - "192.168.0.111:53:53/udp"
      - "192.168.0.111:53:53/tcp"
    environment:
      - TZ=Europe/Moscow
      - WEBPASSWORD=PASSWORD
      - VIRTUAL_HOST=pihole.example.ru
    volumes:
      - $DIR_CONF/pihole/conf:/etc/pihole
      - $DIR_CONF/pihole/dnsmasq.d:/etc/dnsmasq.d
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pihole.entrypoints=http"
      - "traefik.http.routers.pihole.rule=Host(`pihole.example.ru`)"
      - "traefik.http.middlewares.pihole-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.pihole-secure.middlewares=WhitelistHome"
      - "traefik.http.routers.pihole.middlewares=pihole-https-redirect"
      - "traefik.http.routers.pihole-secure.entrypoints=https"
      - "traefik.http.routers.pihole-secure.rule=Host(`pihole.example.ru`)"
      - "traefik.http.routers.pihole-secure.tls=true"
      - "traefik.http.routers.pihole-secure.service=pihole"
      - "traefik.http.services.pihole.loadbalancer.server.port=80"
      - "com.centurylinklabs.watchtower.enable=true"

  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/timezone:/etc/timezone:ro
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_LABEL_ENABLE=true
      - WATCHTOWER_INCLUDE_RESTARTING=true
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  ocs:
    image: ocsinventory/ocsinventory-docker-image:latest
    container_name: ocs
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - /etc/localtime:/etc/localtime:ro
    environment:
      OCS_DB_SERVER: mysql
      OCS_DB_USER: ocs
      OCS_DB_PASS: PASSWORD
      OCS_DB_NAME: ocsweb
    depends_on:
      - mysql
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ocs.tls=true"
      - "traefik.http.routers.ocs.rule=Host(`ocs.example.ru`)"
      - "traefik.http.routers.ocs.middlewares=WhitelistHome"
      - "traefik.http.services.ocs.loadbalancer.server.port=80"
      - "com.centurylinklabs.watchtower.enable=true"

  registry:
    image: registry:latest
    container_name: registry
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_DATA/registry:/var/lib/registry
      - $DIR_CONF/registry/auth:/auth
      - /etc/localtime:/etc/localtime:ro
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.registry.rule=Host(`registry.example.ru`)"
      - "traefik.http.routers.registry.entrypoints=https"
      - "traefik.http.routers.registry.tls=true"
      - "traefik.http.services.registry.loadbalancer.server.port=5000"
      - "com.centurylinklabs.watchtower.enable=true"

### HA
  mosquitto:
    image: eclipse-mosquitto
    container_name: mosquitto
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_CONF/mosquitto:/mosquitto

  zigbee2mqtt:
    image: koenkk/zigbee2mqtt
    container_name: zigbee2mqtt
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    depends_on:
      - mosquitto
    environment:
      - TZ=Europe/Moscow
    volumes:
      - $DIR_CONF/zigbee2mqtt:/app/data
      - /run/udev:/run/udev:ro
    devices:
      - /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_b8e81ef55b29ec119d78757840c9ce8d-if00-port0:/dev/ttyACM0
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.zigbee2mqtt.rule=Host(`zigbee.example.ru`)"
      - "traefik.http.routers.zigbee2mqtt.entrypoints=https"
      - "traefik.http.routers.zigbee2mqtt.tls=true"
      - "traefik.http.routers.zigbee2mqtt.middlewares=WhitelistHome"
      - "traefik.http.services.zigbee2mqtt.loadbalancer.server.port=80"
      - "com.centurylinklabs.watchtower.enable=true"

  homeassistant:
    image: homeassistant/home-assistant:latest
    container_name: homeassistant
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_CONF/homeassistant:/config
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.homeassistant.tls=true"
      - "traefik.http.routers.homeassistant.rule=Host(`homeassistant.example.ru`)"
      - "traefik.http.routers.homeassistant.middlewares=default-headers@file"
      - "traefik.http.services.homeassistant.loadbalancer.server.port=8123"

### LOGS & MONITORING
  uptimekuma:
    image: louislam/uptime-kuma:latest
    container_name: uptimekuma
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_CONF/uptimekuma:/app/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.uptime.tls=true"
      - "traefik.http.routers.uptime.rule=Host(`uptime.example.ru`)"
      - "traefik.http.routers.uptime.middlewares=WhitelistHome"
      - "traefik.http.services.uptime.loadbalancer.server.port=3001"
      - "com.centurylinklabs.watchtower.enable=true"

  mysql-logs:
    image: mariadb:10.8
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: mysql-logs
    volumes:
      - $DIR_DATA/mysql-logs:/var/lib/mysql
      - /etc/localtime:/etc/localtime:ro
    environment:
      - MYSQL_ROOT_PASSWORD=PASSWORD
      - MYSQL_PASSWORD=PASSWORD
      - MYSQL_USER=zabbix
      - MYSQL_DATABASE=zabbix

  zabbix-web-nginx-mysql:
    image: zabbix/zabbix-web-nginx-mysql:latest
    container_name: zabbix-web
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s
    environment:
      DB_SERVER_HOST: mysql-logs
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_PASSWORD: PASSWORD
    depends_on:
      - mysql-logs
    volumes:
      - /etc/localtime:/etc/localtime:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.zabbix.tls=true"
      - "traefik.http.routers.zabbix.rule=Host(`zabbix.example.ru`)"
      - "traefik.http.routers.zabbix.middlewares=WhitelistHome"
      - "traefik.http.services.zabbix.loadbalancer.server.port=8080"

  zabbix-java-gateway:
    image: zabbix/zabbix-java-gateway:latest
    container_name: zabbix-gateway
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - /etc/localtime:/etc/localtime:ro

  zabbix-server-mysql:
    image: zabbix/zabbix-server-mysql:latest
    container_name: zabbix-server
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    depends_on:
      - zabbix-java-gateway
      - mysql-logs
    environment:
      DB_SERVER_HOST: mysql-logs
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_PASSWORD: PASSWORD
      ZBX_JAVAGATEWAY: zabbix-java-gateway
    volumes:
      - /etc/localtime:/etc/localtime:ro

  grafana:
    image: grafana/grafana-oss:latest
    container_name: grafana
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_DATA/grafana:/var/lib/grafana
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.grafana.rule=Host(`grafana.example.ru`)"
      - "traefik.http.routers.grafana.entrypoints=https"
      - "traefik.http.routers.grafana.tls=true"
      - "traefik.http.services.grafana.loadbalancer.server.port=3000"
      - "traefik.http.routers.grafana.middlewares=WhitelistHome"
      - "com.centurylinklabs.watchtower.enable=true"

  influxdb:
    image: influxdb:1.8
    container_name: influxdb
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - $DIR_DATA/influxdb:/var/lib/influxdb
    environment:
      - INFLUXDB_DB=telegraf
      - INFLUXDB_ADMIN_ENABLED=true
      - INFLUXDB_ADMIN_USER=admin
      - INFLUXDB_ADMIN_PASSWORD=a4Q9PuLppX88qxzi
      - INFLUXDB_USER=telegraf
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  node:
    image: prom/node-exporter
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: node
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
      - /:/host:ro,rslave
    command:
      - '--path.rootfs=/host'
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - --collector.filesystem.ignored-mount-points
      - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"

  cadvisor:
    image: gcr.io/cadvisor/cadvisor
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: cadvisor
    devices:
      - "/dev/kmsg:/dev/kmsg"
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro

  filebeat:
    image: elastic/filebeat:8.4.3
    container_name: filebeat
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    entrypoint: "filebeat -e -strict.perms=false"
    volumes:
      - $DIR_CONF/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml

  prometheus:
    image: prom/prometheus
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    depends_on:
      - cadvisor
    volumes:
      - $DIR_CONF/prometheus:/etc/prometheus
      - $DIR_DATA/prometheus:/prometheus
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

  alertmanager:
    image: prom/alertmanager
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: alertmanager
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    ports:
      - "9093:9093"
    volumes:
      - $DIR_CONF/alertmanager:/etc/alertmanager

  fluentd:
    image: fluent/fluentd
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: fluentd
    volumes:
      - $DIR_CONF/fluentd:/fluentd/etc
    links:
      - "elasticsearch"

  elasticsearch:
    image: elasticsearch:8.4.3
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: elasticsearch
    hostname: 'elasticsearch'
    environment:
      - discovery.type=single-node
      - ELASTIC_PASSWORD=PASSWORD
      - xpack.license.self_generated.type=basic
      - path.data=/usr/share/elasticsearch/data
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - $DIR_DATA/elasticsearch:/usr/share/elasticsearch/data

  kibana:
    image: kibana:8.4.3
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: kibana
    depends_on:
      - elasticsearch
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - SERVER_NAME=kibana
      - PATH_DATA=/usr/share/kibana/data
    volumes:
      - $DIR_CONF/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
      - $DIR_DATA/kibana:/usr/share/kibana/data
    links:
      - "elasticsearch"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.kibana.tls=true"
      - "traefik.http.routers.kibana.rule=Host(`kibana.example.ru`)"
      - "traefik.http.routers.kibana.middlewares=WhitelistHome"
      - "traefik.http.services.kibana.loadbalancer.server.port=5601"

  logstash:
    image: logstash:8.4.3
    container_name: logstash
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      - NODE_NAME=logstash
      - xpack.monitoring.enabled=false
    volumes:
      - $DIR_CONF/logstash/pipeline:/usr/share/logstash/pipeline
    links:
      - elasticsearch
    depends_on:
      - elasticsearch

  elastalert:
    image: jertel/elastalert2
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    container_name: elastalert
    depends_on:
      - elasticsearch
    volumes:
      - $DIR_CONF/elastalert/elastalert.yaml:/opt/elastalert/config.yaml
      - $DIR_CONF/elastalert/rules:/opt/elastalert/rules
      - $DIR_CONF/elastalert/smtp.yaml:/opt/elastalert/smtp_auth_file.yml

### BACKUPS
  minio:
    image: quay.io/minio/minio
    container_name: minio
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    command: server /data --address ":9000" --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: DMxXvdYz4o8QDq
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3
    volumes:
      - $DIR_BACKUP/minio:/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.minio.rule=Host(`minio.example.ru`)"
      - "traefik.http.routers.minio.entrypoints=https"
      - "traefik.http.routers.minio.tls=true"
      - "traefik.http.routers.minio.middlewares=WhitelistHome"
      - "traefik.http.services.minio.loadbalancer.server.port=9001"
      - "com.centurylinklabs.watchtower.enable=true"

  duplicati:
    image: linuxserver/duplicati:latest
    container_name: duplicati
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    environment:
      - PUID=0
      - PGID=0
      - TZ=Europe/Moscow
    volumes:
      - $DIR_CONF/duplicati:/config
      - $DIR_BACKUP/DUPLICATI:/backups
      - /srv:/source
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.duplicati.rule=Host(`duplicati.example.ru`)"
      - "traefik.http.routers.duplicati.entrypoints=https"
      - "traefik.http.routers.duplicati.tls=true"
      - "traefik.http.services.duplicati.loadbalancer.server.port=8200"
      - "traefik.http.routers.duplicati.middlewares=WhitelistHome,authelia@docker"
      - "com.centurylinklabs.watchtower.enable=true"

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "false"
К началу