########################### version: "3.9" #################### networks: default: driver: bridge t2_proxy: name: t2_proxy driver: bridge ipam: config: - subnet: 192.168.2.0/24 socket_proxy: name: socket_proxy driver: bridge ipam: config: - subnet: 192.168.3.0/24 #################### secrets: my_email: file: $DOCKERDIR/secrets/my_email cloudflare_email: file: $DOCKERDIR/secrets/cloudflare_email cloudflare_api_key: file: $DOCKERDIR/secrets/cloudflare_api_key cloudflare_api_token: file: $DOCKERDIR/secrets/cloudflare_api_token mysql_root_password: file: $DOCKERDIR/secrets/mysql_root_password redis_password: file: $DOCKERDIR/secrets/redis_password authelia_jwt_secret: file: $DOCKERDIR/secrets/authelia_jwt_secret authelia_session_secret: file: $DOCKERDIR/secrets/authelia_session_secret authelia_storage_mysql_password: file: $DOCKERDIR/secrets/authelia_storage_mysql_password authelia_session_redis_password: file: $DOCKERDIR/secrets/authelia_session_redis_password authelia_notifier_smtp_password: file: $DOCKERDIR/secrets/authelia_notifier_smtp_password authelia_duo_api_secret_key: file: $DOCKERDIR/secrets/authelia_duo_api_secret_key authelia_storage_encryption_key: file: $DOCKERDIR/secrets/authelia_storage_encryption_key #################### ########################### EXTENSION FIELDS # Common environment values x-environment: &default-tz-puid-pgid TZ: $TZ PUID: $PUID PGID: $PGID # Proxy Network and Security x-network-and-security: &network-and-security networks: - t2_proxy security_opt: - no-new-privileges:true # Keys common to some of the services in basic-services.txt x-common-keys-basic: &common-keys-basic <<: *network-and-security restart: always # profiles: # - basic # Keys common to some of the dependent services/apps x-common-keys-apps: &common-keys-apps <<: *network-and-security restart: unless-stopped # profiles: # - apps # Keys common to some of the services in media-services.txt x-common-keys-media: &common-keys-media <<: *network-and-security restart: "no" # profiles: # - media #################### ########################### SERVICES services: traefik: <<: *common-keys-basic # See EXTENSION FIELDS at the top container_name: traefik image: traefik:2.9.6 command: # CLI arguments - --global.checkNewVersion=true - --global.sendAnonymousUsage=false - --entryPoints.http.address=:80 - --entryPoints.https.address=:443 # Allow these IPs to set the X-Forwarded-* headers - Cloudflare IPs: https://www.cloudflare.com/ips/ - --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22 - --entryPoints.traefik.address=:8080 # - --entryPoints.ping.address=:8081 - --api=true # - --api.insecure=true - --api.dashboard=true #- --ping=true #- --pilot.token=$TRAEFIK_PILOT_TOKEN # - --serversTransport.insecureSkipVerify=true - --log=true - --log.level=DEBUG # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC - --accessLog=true - --accessLog.filePath=/traefik.log - --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines - --accessLog.filters.statusCodes=400-499 - --providers.docker=true # - --providers.docker.endpoint=unix:///var/run/docker.sock # Use Docker Socket Proxy instead for improved security - --providers.docker.endpoint=tcp://socket-proxy:2375 # Automatically set Host rule for services # - --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME0`) - --providers.docker.exposedByDefault=false # - --entrypoints.https.http.middlewares=chain-oauth@file # - --entrypoints.https.http.tls.options=tls-opts@file # Add dns-cloudflare as default certresolver for all services. Also enables TLS and no need to specify on individual services - --entrypoints.https.http.tls.certresolver=dns-cloudflare - --entrypoints.https.http.tls.domains[0].main=$DOMAINNAME - --entrypoints.https.http.tls.domains[0].sans=*.$DOMAINNAME # - --entrypoints.https.http.tls.domains[1].main=$DOMAINNAME1 # Pulls main cert for second domain # - --entrypoints.https.http.tls.domains[1].sans=*.$DOMAINNAME1 # Pulls wildcard cert for second domain - --providers.docker.network=t2_proxy - --providers.docker.swarmMode=false - --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory # - --providers.file.filename=/path/to/file # Load dynamic configuration from a file - --providers.file.watch=true # Only works on top level files in the rules folder # - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing - --certificatesResolvers.dns-cloudflare.acme.email=$CLOUDFLARE_EMAIL - --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53 - --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.delayBeforeCheck=90 # To delay DNS check and reduce LE hitrate networks: t2_proxy: ipv4_address: $TRAEFIK_IP # You can specify a static IP socket_proxy: #healthcheck: # test: ["CMD", "traefik", "healthcheck", "--ping"] # interval: 5s # retries: 3 ports: - target: 80 published: 80 protocol: tcp mode: host - target: 443 published: 443 protocol: tcp mode: host # - target: 8080 # published: 8080 # protocol: tcp # mode: host volumes: - $DOCKERDIR/traefik2/rules:/rules # file provider directory # - /var/run/docker.sock:/var/run/docker.sock:ro # Use Docker Socket Proxy instead for improved security - $DOCKERDIR/traefik2/acme/acme.json:/acme.json # cert location - you must touch this file and change permissions to 600 - $DOCKERDIR/traefik2/traefik.log:/traefik.log # for fail2ban - make sure to touch file before starting container #- $DOCKERDIR/shared:/shared environment: - CF_API_EMAIL_FILE=/run/secrets/cloudflare_email - CF_API_KEY_FILE=/run/secrets/cloudflare_api_key secrets: - cloudflare_email - cloudflare_api_key labels: #- "autoheal=true" - "traefik.enable=true" # HTTP-to-HTTPS Redirect - "traefik.http.routers.http-catchall.entrypoints=http" - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)" - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" # HTTP Routers - "traefik.http.routers.traefik-rtr.entrypoints=https" - "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME`)" ## Services - API - "traefik.http.routers.traefik-rtr.service=api@internal" ## Middlewares - "traefik.http.routers.traefik-rtr.middlewares=chain-authelia@file" ################################### # Docker Socket Proxy - Security Enchanced Proxy for Docker Socket socket-proxy: <<: *common-keys-basic # See EXTENSION FIELDS at the top container_name: socket-proxy image: tecnativa/docker-socket-proxy networks: socket_proxy: ipv4_address: $SOCKETPROXY_IP # You can specify a static IP privileged: true ports: - "127.0.0.1:2375:2375" # Port 2375 should only ever get exposed to the internal network. When possible use this line. # I use the next line instead, as I want portainer to manage multiple docker endpoints within my home network. # - "2375:2375" volumes: - "/var/run/docker.sock:/var/run/docker.sock" environment: - LOG_LEVEL=info # debug,info,notice,warning,err,crit,alert,emerg ## Variables match the URL prefix (i.e. AUTH blocks access to /auth/* parts of the API, etc.). # 0 to revoke access. # 1 to grant access. ## Granted by Default - EVENTS=1 - PING=1 - VERSION=1 ## Revoked by Default # Security critical - AUTH=0 - SECRETS=0 - POST=1 # Watchtower # Not always needed - BUILD=0 - COMMIT=0 - CONFIGS=0 - CONTAINERS=1 # Traefik, portainer, etc. - DISTRIBUTION=0 - EXEC=0 - IMAGES=1 # Portainer - INFO=1 # Portainer - NETWORKS=1 # Portainer - NODES=0 - PLUGINS=0 - SERVICES=1 # Portainer - SESSION=0 - SWARM=0 - SYSTEM=0 - TASKS=1 # Portainer - VOLUMES=1 # Portainer ################################### # Authelia authelia: container_name: authelia # Check this before upgrading: https://github.com/authelia/authelia/blob/master/BREAKING.md image: authelia/authelia:4.37.3 restart: always # profiles: # - core # networks: # - t2_proxy networks: t2_proxy: ipv4_address: $AUTHELIA_IP # You can specify a static IP depends_on: - mariadb - redis # ports: # - "9091:9091" volumes: - $DOCKERDIR/authelia:/config # - $DOCKERDIR/authelia/notifications.txt:/config/notifications.txt environment: - TZ=$TZ - AUTHELIA_JWT_SECRET_FILE=/run/secrets/authelia_jwt_secret - AUTHELIA_SESSION_SECRET_FILE=/run/secrets/authelia_session_secret - AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE=/run/secrets/authelia_storage_mysql_password - AUTHELIA_SESSION_REDIS_PASSWORD_FILE=/run/secrets/authelia_session_redis_password - AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE=/run/secrets/authelia_notifier_smtp_password - AUTHELIA_DUO_API_SECRET_KEY_FILE=/run/secrets/authelia_duo_api_secret_key - AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE=/run/secrets/authelia_storage_encryption_key secrets: - authelia_jwt_secret - authelia_session_secret - authelia_storage_mysql_password - authelia_notifier_smtp_password - authelia_duo_api_secret_key - authelia_storage_encryption_key - authelia_session_redis_password labels: - "traefik.enable=true" ## HTTP Routers - "traefik.http.routers.authelia-rtr.entrypoints=https" - "traefik.http.routers.authelia-rtr.rule=Host(`authelia.$DOMAINNAME`)" - "traefik.http.routers.authelia-rtr.tls=true" ## Middlewares - "traefik.http.routers.authelia-rtr.middlewares=chain-authelia@file" ## HTTP Services - "traefik.http.routers.authelia-rtr.service=authelia-svc" - "traefik.http.services.authelia-svc.loadbalancer.server.port=9091" ################################### # MariaDB - MySQL Database # After starting container for first time dexec and mysqladmin -u root password mariadb: <<: *common-keys-basic # See EXTENSION FIELDS at the top container_name: mariadb image: lscr.io/linuxserver/mariadb networks: t2_proxy: ipv4_address: $MARIADB_IP # You can specify a static IP volumes: - $DOCKERDIR/mariadb/data:/config environment: - PUID=$PUID - PGID=$PGID - TZ=$TZ - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password secrets: - mysql_root_password ################################### # Redis - Key-value Store redis: <<: *common-keys-basic # See EXTENSION FIELDS at the top container_name: redis image: redis:latest environment: - REDIS_PASSWORD_FILE=/run/secrets/redis_password secrets: - redis_password entrypoint: redis-server --appendonly yes --requirepass $REDIS_PASSWORD --maxmemory 512mb --maxmemory-policy allkeys-lru networks: t2_proxy: ipv4_address: $REDIS_IP # You can specify a static IP # ports: # - "$REDIS_PORT:6379" volumes: - $DOCKERDIR/redis/data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ################################### nextcloud: image: nextcloud:25.0.2 restart: unless-stopped container_name: nextcloud networks: t2_proxy: ipv4_address: $NEXTCLOUD_IP # You can specify a static IP volumes: - /home/leo/docker/nextcloud/data:/var/www/html depends_on: - mariadb - redis environment: - MYSQL_HOST=mariadb - MYSQL_DATABASE=$NEXTCLOUD_MYSQL_DATABASE - MYSQL_USER=$NEXTCLOUD_MYSQL_USER - MYSQL_PASSWORD=$NEXTCLOUD_MYSQL_PASSWORD - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password - NEXTCLOUD_TRUSTED_DOMAINS=domainname.com - REDIS_HOST=redis # - REDIS_PORT=6379 - REDIS_PASSWORD_FILE=/run/secrets/redis_password - TRUSTED_PROXIES=192.168.2.10 - OVERWRITEHOST=domainname.com - OVERWRITEPROTOCOL=https # - OVERWRITEPROTOCOL=https # - APACHE_DISABLE_REWRITE_IP=1 # - APACHE_IP_BINDING=127.0.0.1 # - APACHE_PORT=11000 secrets: - redis_password - mysql_root_password labels: - "traefik.enable=true" - "traefik.docker.network=t2_proxy" - "traefik.http.routers.nextcloud.entrypoints=http" - "traefik.http.routers.nextcloud.rule=Host(`$DOMAINNAME`,`www.$DOMAINNAME`)" - "traefik.http.routers.nextcloud.tls=true" - "traefik.http.routers.nextcloud.middlewares=nextcloud,nextcloud-redirect" - "traefik.http.routers.https-nextcloud.entrypoints=https" - "traefik.http.routers.https-nextcloud.rule=Host(`$DOMAINNAME`,`www.$DOMAINNAME`)" - "traefik.http.routers.https-nextcloud.tls=true" - "traefik.http.routers.https-nextcloud.middlewares=nextcloud,nextcloud-redirect" - "traefik.http.middlewares.nextcloud.headers.stsSeconds=155520011" - "traefik.http.middlewares.nextcloud.headers.stsIncludeSubdomains=true" - "traefik.http.middlewares.nextcloud.headers.stsPreload=true" - "traefik.http.middlewares.nextcloud-redirect.redirectregex.regex=/.well-known/(card|cal)dav" - "traefik.http.middlewares.nextcloud-redirect.redirectregex.replacement=/remote.php/dav/" - "traefik.http.middlewares.nextcloud-redirect.redirectregex.permanent=true" - "traefik.http.services.nextcloud.loadbalancer.server.port=80" - "traefik.http.routers.nextcloud.service=nextcloud"