diff --git a/config/docker/2023/New-Docker-Deployment/home/user/docker-compose-t2-synology.yml b/config/docker/2023/New-Docker-Deployment/home/user/docker-compose-t2-synology.yml new file mode 100644 index 0000000..a38ece1 --- /dev/null +++ b/config/docker/2023/New-Docker-Deployment/home/user/docker-compose-t2-synology.yml @@ -0,0 +1,860 @@ +version: "3.9" + +######### IMPORTANT ############# +# docker-compose-t2.yml is my main docker compose that runs on a dedicated cloud server with Proxmox. +# You will find only a few apps (only those that I run on Synology NAS for my homelab use) in this docker-compose file. +# You can copy-paste services from one docker-compose file in this repo to another to add other apps. + +########################### SYSTEM DESCRIPTION +# DOCKER-COMPOSE FOR SYNOLOGY DS918+ +# 8 GB RAM, DSM 7.X +# 1x4TB + 3x8TB +# 2x256GB NVMe SSD Read-Write Cache +# Google Drive mounted using Rclone Docker Container for media + +########################### NETWORKS +# There is no need to create any networks outside this docker-compose file. +# You may customize the network subnets (192.168.90.0/24 and 91.0/24) below as you please. +# Docker Compose version 3.5 or higher required to define networks this way. + +networks: + t2_proxy: + name: t2_proxy + driver: bridge + ipam: + config: + - subnet: 192.168.90.0/24 + default: + driver: bridge + socket_proxy: + name: socket_proxy + driver: bridge + ipam: + config: + - subnet: 192.168.91.0/24 + +########################### SECRETS +secrets: + htpasswd: + file: $DOCKERDIR/secrets/htpasswd + 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 + oauth_secret: + file: $DOCKERDIR/secrets/oauth_secret + google_client_secret: + file: $DOCKERDIR/secrets/google_client_secret + google_client_id: + file: $DOCKERDIR/secrets/google_client_id + my_email: + file: $DOCKERDIR/secrets/my_email + plex_claim: + file: $DOCKERDIR/secrets/plex_claim + mysql_root_password: + file: $DOCKERDIR/secrets/mysql_root_password + +########################### EXTENSION FIELDS +# Helps eliminate repetition of sections +# More Info on how to use this: https://github.com/htpcBeginner/docker-traefik/pull/228 + +# 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: + ############################# FRONTENDS + + # Traefik 2 - Reverse Proxy + # touch (create empty files) traefik.log and acme/acme.json. Set acme.json permissions to 600. + # touch $DOCKERDIR/traefik2/acme/acme.json + # chmod 600 $DOCKERDIR/traefik2/acme/acme.json + # touch $DOCKERDIR/traefik2/traefik.log + traefik: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: traefik + image: traefik:2.5 + command: # CLI arguments + - --global.checkNewVersion=true + - --global.sendAnonymousUsage=true + - --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=WARN # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC + - --accessLog=false + - --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-external@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=$DOMAINNAME0 + - --entrypoints.https.http.tls.domains[0].sans=*.$DOMAINNAME0 + # - --entrypoints.https.http.tls.domains[1].main=$DOMAINNAME01 # Pulls main cert for second domain + # - --entrypoints.https.http.tls.domains[1].sans=*.$DOMAINNAME01 # 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 + - 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/appdata/traefik2/rules:/rules # file provider directory + # - /var/run/docker.sock:/var/run/docker.sock:ro # Use Docker Socket Proxy instead for improved security + - $DOCKERDIR/appdata/traefik2/acme/acme.json:/acme.json # cert location - you must touch this file and change permissions to 600 + - $DOCKERDIR/appdata/traefik2/traefik.log:/traefik.log # for fail2ban - make sure to touch file before starting container + environment: + - CF_API_EMAIL_FILE=/run/secrets/cloudflare_email + - CF_API_KEY_FILE=/run/secrets/cloudflare_api_key + - HTPASSWD_FILE=/run/secrets/htpasswd # HTPASSWD_FILE can be whatever as it is not used/called anywhere. + secrets: + - cloudflare_email + - cloudflare_api_key + - htpasswd + 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(`traefikh.$DOMAINNAME0`)" + ## Services - API + - "traefik.http.routers.traefik-rtr.service=api@internal" + ## Healthcheck/ping + #- "traefik.http.routers.ping.rule=Host(`traefik.$DOMAINNAME0`) && Path(`/ping`)" + #- "traefik.http.routers.ping.tls=true" + #- "traefik.http.routers.ping.service=ping@internal" + ## Middlewares + - "traefik.http.routers.traefik-rtr.middlewares=chain-oauth-external@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: fluencelabs/docker-socket-proxy + networks: + - socket_proxy + privileged: true + 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 + - DELETE=1 # Watchtower + # GET Optons + - BUILD=0 + - COMMIT=0 + - CONFIGS=0 + - CONTAINERS=1 # Traefik, portainer, etc. + - DISTRIBUTION=0 + - EXEC=0 + - IMAGES=1 # Portainer, Watchtower + - INFO=1 # Portainer + - NETWORKS=1 # Portainer, Watchtower + - NODES=0 + - PLUGINS=0 + - SERVICES=1 # Portainer + - SESSION=0 + - SWARM=0 + - SYSTEM=0 + - TASKS=1 # Portaienr + - VOLUMES=1 # Portainer + # POST Options + - CONTAINERS_CREATE=1 # WatchTower + - CONTAINERS_START=1 # WatchTower + - CONTAINERS_UPDATE=1 # WatchTower + # DELETE Options + - CONTAINERS_DELETE=1 # WatchTower + - IMAGES_DELETE=1 # WatchTower + + # Google OAuth - Single Sign On using OAuth 2.0 + # Removed redundant Google OAuth forwarder. Forwarding all authentication requests to oauth:4181 on docker-compose-t2.yml (cloud server). See middlewares-oauth-external in middlewares.yml.example and chain-oauth-external in middlewares-chains.yml.example. + + # Portainer - WebUI for Containers + portainer: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: portainer + image: portainer/portainer-ce:latest + # command: -H unix:///var/run/docker.sock # # Use Docker Socket Proxy instead for improved security + command: -H tcp://socket-proxy:2375 + networks: + - t2_proxy + - socket_proxy + #ports: + # - "$PORTAINER_PORT:9000" + volumes: + # - /var/run/docker.sock:/var/run/docker.sock:ro # # Use Docker Socket Proxy instead for improved security + - $DOCKERDIR/appdata/portainer/data:/data # Change to local directory if you want to save/transfer config locally + environment: + - TZ=$TZ + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.portainer-rtr.entrypoints=https" + - "traefik.http.routers.portainer-rtr.rule=Host(`portainerh.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.portainer-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.portainer-rtr.service=portainer-svc" + - "traefik.http.services.portainer-svc.loadbalancer.server.port=9000" + + # Autoindex - Simple Directory Index + autoindex: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + container_name: autoindex + image: dceoy/nginx-autoindex:latest + # ports: + # - "$AUTOINDEX_PORT:80" + volumes: + - /volume1:/var/lib/nginx/html:ro # Location you want to index + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.autoindex-rtr.entrypoints=https" + - "traefik.http.routers.autoindex-rtr.rule=Host(`indexh.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.autoindex-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.autoindex-rtr.service=autoindex-svc" + - "traefik.http.services.autoindex-svc.loadbalancer.server.port=80" + + ############################# SMART HOME + + # Mosquitto - MQTT Broker + # Create mosquitto.conf, passwd, mosquitto.log files and set permissions to 775 user:docker + # dexec mosquitto /bin/sh -> mosquitto_passwd -b /mosquitto/config/passwd username passwd + mosquitto: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: eclipse-mosquitto:latest + container_name: mosquitto + ports: + - "$MOSQUITTO_HTTP_PORT:1883" #http + - "9001:9001" #websockets + # - "$MOSQUITTO_HTTPS_PORT:8883" #https + volumes: + - $DOCKERDIR/appdata/mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf + - $DOCKERDIR/appdata/mosquitto/config/passwd:/mosquitto/config/passwd + - $DOCKERDIR/shared:/shared + environment: + PUID: $PUID + PGID: $PGID + TZ: $TZ + + ############################# DATABASE + + # 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: linuxserver/mariadb:latest + ports: + - "$MARIADB_PORT:3306" + volumes: + - $DOCKERDIR/appdata/mariadb/data:/config + - /etc/TZ:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + environment: + - PUID=$PUID + - PGID=$PGID + - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password # Not taking this pw during initialization + secrets: + - mysql_root_password + + # InfluxDB - Database for sensor data + # Create influxdb.conf + influxdb: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + image: influxdb:latest + container_name: influxdb + ports: + - "$INFLUXDB_PORT:8086" + volumes: + # - $DOCKERDIR/appdata/influxdb/influxdb.conf:/etc/influxdb/influxdb.conf:ro + - $DOCKERDIR/appdata/influxdb/db:/var/lib/influxdb + # command: -config /etc/influxdb/influxdb.conf + + # phpMyAdmin - Database management + # Create a new user with admin privileges. Cannot login as MySQL root for some reason. + phpmyadmin: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: phpmyadmin/phpmyadmin:latest + container_name: phpmyadmin + # ports: + # - "$PHPMYADMIN_PORT:80" + # volumes: + # - $DOCKERDIR/appdata/phpmyadmin:/etc/phpmyadmin + environment: + - PMA_HOST=mariadb + #- PMA_PORT=$DB_PORT + #- PMA_ARBITRARY=1 + - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password + secrets: + - mysql_root_password + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.phpmyadmin-rtr.entrypoints=https" + - "traefik.http.routers.phpmyadmin-rtr.rule=Host(`pmah.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.phpmyadmin-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.phpmyadmin-rtr.service=phpmyadmin-svc" + - "traefik.http.services.phpmyadmin-svc.loadbalancer.server.port=80" + + ############################# DOWNLOADERS + + # qBittorrent - Torrent downloader + # Needs trailing / if using PathPrefixStrip + qbittorrent: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: lscr.io/linuxserver/qbittorrent + container_name: qbittorrent + # ports: + #- "$QBITTORRENT_PORT:8168" + #- 6881:6881 + #- 6881:6881/udp + volumes: + - $DOCKERDIR/appdata/qbittorrent:/config + - $DOWNLOADSDIR:/downloads + environment: + PUID: $PUID + PGID: $PGID + TZ: $TZ + UMASK: 002 + WEBUI_PORT: 8168 + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.qbittorrent-rtr.entrypoints=https" + - "traefik.http.routers.qbittorrent-rtr.rule=Host(`qbith.$DOMAINNAME0`)" + - "traefik.http.routers.qbittorrent-rtr.tls=true" + ## Middlewares + - "traefik.http.routers.qbittorrent-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.qbittorrent-rtr.service=qbittorrent-svc" + - "traefik.http.services.qbittorrent-svc.loadbalancer.server.port=8168" + + ############################# MEDIA + + # Plex - Media Server + plexms: + <<: *common-keys-media # See EXTENSION FIELDS at the top + image: plexinc/pms-docker:public + container_name: plexms + ports: + - "$PLEX_PORT:32400/tcp" + - "3005:3005/tcp" + - "8324:8324/tcp" + - "32469:32469/tcp" + # - "1900:1900/udp" # conflicts with xTeVe and Synology default ports + - "32410:32410/udp" + - "32412:32412/udp" + - "32413:32413/udp" + - "32414:32414/udp" + - "$PLEX_WEB_TOOLS_PORT:33400" + devices: + - /dev/dri:/dev/dri # for hardware transcoding + volumes: + - $DOCKERDIR/appdata/plexms:/config + - $DOWNLOADSDIR:/downloads + - $DS918/media:/media + - /dev/shm:/transcode + environment: + TZ: $TZ + HOSTNAME: "sPlex" + PLEX_CLAIM_FILE: /run/secrets/plex_claim + PLEX_UID: $PUID + PLEX_GID: $PGID + ADVERTISE_IP: http://$SERVER_IP1:32400/ + secrets: + - plex_claim + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.plexms-rtr.entrypoints=https" + - "traefik.http.routers.plexms-rtr.rule=Host(`synplex.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.plexms-rtr.middlewares=chain-no-auth@file" + ## HTTP Services + - "traefik.http.routers.plexms-rtr.service=plexms-svc" + - "traefik.http.services.plexms-svc.loadbalancer.server.port=32400" + + ############################# MEDIA FILE MANAGEMENT + + # Tdarr Server - Library Optimizer + tdarr: + <<: *common-keys-media # See EXTENSION FIELDS at the top + image: haveagitgat/tdarr:latest + container_name: tdarr + #ports: + # - "$TDARR_SERVER_PORT:8266" + # - "$TDARR_WEB_PORT:8265" + # - 8267:8267 # node port. It should be mapped on this container because the node container use the network from the main container + volumes: + - $DOCKERDIR/appdata/tdarr/server:/app/server + - $DOCKERDIR/appdata/tdarr/configs:/app/configs + - $DOCKERDIR/appdata/tdarr/logs:/app/logs + - $DOWNLOADSDIR/transcode/tdarr:/data/temp + - $DATADIR/Photos/zVideos:/data/media:ro + - $DS918/media/zvideos:/data/output + environment: + PUID: $PUID + PGID: $PGID + TZ: $TZ + serverIP: tdarr # or hostname + serverPort: 8266 + webUIPort: 8265 + UMASK_SET: 002 + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.tdarr-rtr.entrypoints=https" + - "traefik.http.routers.tdarr-rtr.rule=Host(`tdarr.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.tdarr-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.tdarr-rtr.service=tdarr-svc" + - "traefik.http.services.tdarr-svc.loadbalancer.server.port=8265" + + # Tdarr Node - Transcoder Node + tdarr-node1: + <<: *common-keys-media # See EXTENSION FIELDS at the top + image: haveagitgat/tdarr_node:latest + container_name: tdarr-node1 + devices: + - /dev/dri:/dev/dri # for hardware transcoding + environment: + PUID: $PUID + PGID: $PGID + TZ: $TZ + UMASK_SET: 002 + nodeID: Node1 + nodeIP: tdarr-node1 # or hostname + nodePort: 8267 + serverIP: tdarr # or hostname + serverPort: 8266 + volumes: + - $DOCKERDIR/appdata/tdarr/configs:/app/configs + - $DOCKERDIR/appdata/tdarr/logs:/app/logs + - $DOWNLOADSDIR/transcode/tdarr:/data/temp + - $DATADIR/Photos/zVideos:/data/media:ro + - $DS918/media/zvideos:/data/output + + ############################# FILES + + # Rclone - Google Drive Mount + # https://github.com/openbridge/ob_bulkstash/issues/19 + # https://github.com/romancin/rclonebrowser-docker + # https://hub.docker.com/r/d2dyno/rclone-gui + rclone-drive: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: rclone-drive + image: rclone/rclone:latest + cap_add: + - SYS_ADMIN + security_opt: + - apparmor:unconfined + command: + "mount drive: /data/drive \ + --use-mmap \ + --allow-other \ + --no-modtime \ + --allow-non-empty \ + --dir-cache-time=1000h \ + --poll-interval=15s \ + --buffer-size=256M \ + --umask=002 \ + --uid=1026 \ + --gid=100 \ + --drive-chunk-size=256M \ + --user-agent=DS918 \ + --cache-dir=/data/cache/drive \ + --vfs-cache-mode=full \ + --vfs-cache-max-age=336h \ + --vfs-cache-max-size=512G \ + --vfs-read-chunk-size=32M \ + --vfs-read-chunk-size-limit=2G \ + --log-file /config/rclone/logs/drive.log \ + --rc \ + --rc-web-gui \ + --rc-addr :5572 \ + --rc-user=$RCLONE_WEBUI_USER \ + --rc-pass=$RCLONE_WEBUI_PASS \ + --log-level=INFO" + #--bwlimit 150M \ + #--bwlimit-file 40M \ + devices: + - /dev/fuse + volumes: + - $DOCKERDIR/appdata/rclone:/config/rclone + - $DS918/rclone/drive:/data/drive:shared + - $DS918/rclone/cache/drive:/data/cache/drive + - /etc/passwd:/etc/passwd:ro + - /etc/group:/etc/group:ro + - /etc/fuse.conf:/etc/fuse.conf:ro + environment: + - TZ=$TZ + - PUID=$PUID + - PGID=$PGID + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.rclone-drive-rtr.entrypoints=https" + - "traefik.http.routers.rclone-drive-rtr.rule=Host(`rcloneh.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.rclone-drive-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.rclone-drive-rtr.service=rclone-drive-svc" + - "traefik.http.services.rclone-drive-svc.loadbalancer.server.port=5572" + + # Rclone - Google Drive Mount + rclone-crypt: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: rclone-crypt + image: rclone/rclone:latest + cap_add: + - SYS_ADMIN + security_opt: + - apparmor:unconfined + command: + "mount crypt: /data/crypt \ + --use-mmap \ + --allow-other \ + --no-modtime \ + --allow-non-empty \ + --dir-cache-time=1000h \ + --poll-interval=15s \ + --buffer-size=256M \ + --uid=1026 \ + --gid=100 \ + --umask=002 \ + --drive-chunk-size=256M \ + --user-agent=DS918 \ + --cache-dir=/data/cache/crypt \ + --vfs-cache-mode=full \ + --vfs-cache-max-age=336h \ + --vfs-cache-max-size=512G \ + --vfs-read-chunk-size=32M \ + --vfs-read-chunk-size-limit=2G \ + --log-file /config/rclone/logs/crypt.log \ + --log-level=NOTICE" + #--bwlimit 3M \ + # 3M approxmimately equals 253 GB limit per day + # previously buffer 256 buffer 256 chunk size 128 read and limit off + devices: + - /dev/fuse + volumes: + - $DOCKERDIR/appdata/rclone:/config/rclone + - $DS918/rclone/crypt:/data/crypt:shared + - $DS918/rclone/cache/crypt:/data/cache/crypt + - /etc/passwd:/etc/passwd:ro + - /etc/group:/etc/group:ro + - /etc/fuse.conf:/etc/fuse.conf:ro + environment: + - TZ=$TZ + - PUID=$PUID + - PGID=$PGID + + ############################# UTILITIES + + # Firefox - Web Broswer + # VNC password not working - check + firefox: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: jlesage/firefox:latest + container_name: firefox + security_opt: + - no-new-privileges:true + - seccomp:unconfined # October 15, 2020 https://github.com/jlesage/docker-firefox/blob/master/README.md#allowing-the-membarrier-system-call + # ports: + # - "$FIREFOX_PORT:5800" + volumes: + - $DOCKERDIR/appdata/firefox:/config + - $DOWNLOADSDIR:/config/Downloads + - /dev/shm:/dev/shm + environment: + USER_ID: $PUID + GROUP_ID: $PGID + TZ: $TZ + UMASK: 002 + KEEP_APP_RUNNING: 1 + CLEAN_TMP_DIR: 1 + DISPLAY_WIDTH: 1600 + DISPLAY_HEIGHT: 960 + # VNC_PASSWD: $FIREFOX_VNC_PASSWD # Since OAuth is enabled + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.firefox-rtr.entrypoints=https" + - "traefik.http.routers.firefox-rtr.rule=Host(`firefoxh.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.firefox-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.firefox-rtr.service=firefox-svc" + - "traefik.http.services.firefox-svc.loadbalancer.server.port=5800" + + # Glances - System Information + glances: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: nicolargo/glances:latest + container_name: glances + privileged: true + # network_mode: host + networks: + - t2_proxy + - socket_proxy + ports: + - "$GLANCES_PORT:61208" + pid: host + volumes: + - $DOCKERDIR/appdata/glances/glances.conf:/glances/conf/glances.conf # Use this if you want to add a glances.conf file + # - /var/run/docker.sock:/var/run/docker.sock:ro # Use Docker Socket Proxy instead for improved security + environment: + # GLANCES_OPT: "-C /glances/conf/glances.conf --quiet --export influxdb" + GLANCES_OPT: "-w" + DOCKER_HOST: tcp://socket-proxy:2375 + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.glances-rtr.entrypoints=https" + - "traefik.http.routers.glances-rtr.rule=Host(`glancesh.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.glances-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.glances-rtr.service=glances-svc" + - "traefik.http.services.glances-svc.loadbalancer.server.port=61208" + + # qDirStat - Directory Statistics + qdirstat: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: jlesage/qdirstat:latest + container_name: qdirstat + # ports: + # - "$QDIRSTAT_PORT:5800" + volumes: + - /volume1:/storage:ro + - $DOCKERDIR/appdata/qdirstat/config:/config:rw + environment: + USER_ID: $PUID + GROUP_ID: $PGID + UMASK: 002 + TZ: $TZ + KEEP_APP_RUNNING: 1 + CLEAN_TMP_DIR: 1 + DISPLAY_WIDTH: 1600 + DISPLAY_HEIGHT: 960 + VNC_PASSWORD: $QDIRSTAT_VNC_PASSWD + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.qdirstat-rtr.entrypoints=https" + - "traefik.http.routers.qdirstat-rtr.rule=Host(`qdirh.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.qdirstat-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.qdirstat-rtr.service=qdirstat-svc" + - "traefik.http.services.qdirstat-svc.loadbalancer.server.port=5800" + + # SyncThing - Keep folders in Sync + syncthing: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + image: lscr.io/linuxserver/syncthing + container_name: syncthing + ports: + - "8384:8384" + - "22000:22000/tcp" + - "22000:22000/udp" + - "21027:21027/udp" + volumes: + - /volume1:/data + - $DOCKERDIR/appdata/syncthing:/config + environment: + PUID: $PUID + PGID: $PGID + TZ: $TZ + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.syncthing-rtr.entrypoints=https" + - "traefik.http.routers.syncthing-rtr.rule=Host(`stnas.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.syncthing-rtr.middlewares=chain-oauth-external@file" + ## HTTP Services + - "traefik.http.routers.syncthing-rtr.service=syncthing-svc" + - "traefik.http.services.syncthing-svc.loadbalancer.server.port=8384" + + ############################# MAINTENANCE + + # WatchTower - Automatic Docker Container Updates + watchtower: + image: containrrr/watchtower + container_name: watchtower + restart: unless-stopped + networks: + - default + - socket_proxy + environment: + TZ: $TZ + WATCHTOWER_CLEANUP: "true" + WATCHTOWER_REMOVE_VOLUMES: "true" + WATCHTOWER_INCLUDE_STOPPED: "true" + WATCHTOWER_NO_STARTUP_MESSAGE: "false" + WATCHTOWER_SCHEDULE: "0 30 12 * * *" # Everyday at 12:30 + WATCHTOWER_NOTIFICATIONS: shoutrrr + WATCHTOWER_NOTIFICATION_URL: "telegram://$TGRAM_BOT_TOKEN@telegram?channels=$TGRAM_CHAT_ID" + WATCHTOWER_NOTIFICATIONS_LEVEL: info + DOCKER_HOST: tcp://socket-proxy:2375 + DOCKER_API_VERSION: "1.40" + + # Docker-GC - Automatic Docker Garbage Collection + # Create docker-gc-exclude file + dockergc: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: clockworksoul/docker-gc-cron:latest + container_name: docker-gc + restart: unless-stopped + networks: + - socket_proxy + volumes: + # - /var/run/docker.sock:/var/run/docker.sock # Use Docker Socket Proxy instead for improved security + - $DOCKERDIR/appdata/docker-gc/docker-gc-exclude:/etc/docker-gc-exclude + environment: + CRON: 0 0 0 * * ? # Everyday at midnight. Previously 0 0 * * * + FORCE_IMAGE_REMOVAL: 1 + FORCE_CONTAINER_REMOVAL: 0 + GRACE_PERIOD_SECONDS: 604800 + DRY_RUN: 0 + CLEAN_UP_VOLUMES: 1 + TZ: $TZ + DOCKER_HOST: tcp://socket-proxy:2375 + + # Cloudflare DDNS - Dynamic DNS Updater + cf-ddns: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: cf-ddns + image: oznu/cloudflare-ddns:latest + environment: + API_KEY: $CLOUDFLARE_API_TOKEN + ZONE: $DOMAINNAME0 + SUBDOMAIN: home + PROXIED: "true" + RRTYPE: A + DELETE_ON_STOP: "false" + DNS_SERVER: 1.1.1.1 + #secrets: # not working + # - cloudflare_api_token + + # Cloudflare-Companion - Automatic CNAME DNS Creation + cf-companion: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + container_name: cf-companion + image: tiredofit/traefik-cloudflare-companion:latest + networks: + - socket_proxy + environment: + - TIMEZONE=$TZ + - TRAEFIK_VERSION=2 + #- CF_EMAIL=$CLOUDFLARE_EMAIL + - CF_TOKEN=$CLOUDFLARE_API_TOKEN + - TARGET_DOMAIN=home.$DOMAINNAME0 + - DOMAIN1=$DOMAINNAME0 + - DOMAIN1_ZONE_ID=$CLOUDFLARE_ZONEID # Copy from Cloudflare Overview page + - DOMAIN1_PROXIED=TRUE + - DOCKER_HOST=tcp://socket-proxy:2375 + secrets: # not working + - cloudflare_api_token + labels: + # Add hosts specified in rules here to force cf-companion to create the CNAMEs + # Since cf-companion creates CNAMEs based on host rules, this a workaround for non-docker/external apps + - "traefik.http.routers.cf-companion-rtr.rule=Host(`webminh.$DOMAINNAME0`) || Host(`shellh.$DOMAINNAME0`) || Host(`syno.$DOMAINNAME0`) || Host(`ibox.$DOMAINNAME0`) || Host(`synplex.$DOMAINNAME0`) || Host(`pirpi.$DOMAINNAME0`) || Host(`pidoc.$DOMAINNAME0` || Host(`stpc.$DOMAINNAME0`)" diff --git a/config/docker/2023/New-Docker-Deployment/home/user/docker-compose-t2-web.yml b/config/docker/2023/New-Docker-Deployment/home/user/docker-compose-t2-web.yml new file mode 100644 index 0000000..ff94f3a --- /dev/null +++ b/config/docker/2023/New-Docker-Deployment/home/user/docker-compose-t2-web.yml @@ -0,0 +1,574 @@ +version: "3.9" + +######### IMPORTANT ############# +# docker-compose-t2.yml is my main docker compose that runs on the same Proxmox host. +# You will find only a few apps in this web stack that hosts a few wordpress and non-wordpress sites. +# You can copy-paste services from one docker-compose file in this repo to another to add other apps. + +########################### SYSTEM DESCRIPTION +# DOCKER-COMPOSE FOR WORDPRESS / WEB SERVER +# PROXMOX HOST: Dual Intel Xeon 5420, 16 GB RAM, 240 GB SSD, and 2 TB HDD +# LXC CONTAINER: 4 CORES, 4 GB RAM, Ubuntu 20.04, and Docker +# 32 GB SSD for / + +########################### NETWORKS +# There is no need to create any networks outside this docker-compose file. +# You may customize the network subnets (192.168.90.0/24 and 91.0/24) below as you please. +# Docker Compose version 3.5 or higher required to define networks this way. + +networks: + t2_proxy: + name: t2_proxy + driver: bridge + ipam: + config: + - subnet: 192.168.90.0/24 + default: + driver: bridge + socket_proxy: + name: socket_proxy + driver: bridge + ipam: + config: + - subnet: 192.168.91.0/24 + +########################### SECRETS +secrets: + htpasswd: + file: $DOCKERDIR/secrets/htpasswd + cloudflare_email: + file: $SECRETSDIR/cloudflare_email + cloudflare_api_key: + file: $SECRETSDIR/cloudflare_api_key + mysql_root_password: + file: $SECRETSDIR/mysql_root_password + authelia_jwt_secret: + file: $SECRETSDIR/authelia_jwt_secret + authelia_session_secret: + file: $SECRETSDIR/authelia_session_secret + authelia_storage_mysql_password: + file: $SECRETSDIR/authelia_storage_mysql_password + authelia_notifier_smtp_password: + file: $SECRETSDIR/authelia_notifier_smtp_password + authelia_duo_api_secret_key: + file: $SECRETSDIR/authelia_duo_api_secret_key + oauth_secret: + file: $SECRETSDIR/oauth_secret + google_client_secret: + file: $SECRETSDIR/google_client_secret + google_client_id: + file: $SECRETSDIR/google_client_id + my_email: + file: $SECRETSDIR/my_email + +########################### EXTENSION FIELDS +# Helps eliminate repetition of sections +# More Info on how to use this: https://github.com/htpcBeginner/docker-traefik/pull/228 + +# 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: + ############################# FRONTENDS + + # Traefik 2 - Reverse Proxy + # Touch (create empty files) traefik.log and acme/acme.json. Set acme.json permissions to 600. + # touch $DOCKERDIR/traefik2/acme/acme.json + # chmod 600 $DOCKERDIR/traefik2/acme/acme.json + # touch $DOCKERDIR/traefik2/traefik.log + traefik: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: traefik + image: traefik:2.5 + command: # CLI arguments + - --global.checkNewVersion=true + - --global.sendAnonymousUsage=true + - --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=WARN # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC + - --accessLog=false + - --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=$DOMAINNAME0 + - --entrypoints.https.http.tls.domains[0].sans=*.$DOMAINNAME0 + # - --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: 192.168.90.254 # 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/appdata/traefik2/rules:/rules # file provider directory + # - /var/run/docker.sock:/var/run/docker.sock:ro # Use Docker Socket Proxy instead for improved security + - $DOCKERDIR/appdata/traefik2/acme/acme.json:/acme.json # cert location - you must touch this file and change permissions to 600 + - $DOCKERDIR/appdata/traefik2/traefik.log:/traefik.log # for fail2ban - make sure to touch file before starting container + environment: + - CF_API_EMAIL_FILE=/run/secrets/cloudflare_email + - CF_API_KEY_FILE=/run/secrets/cloudflare_api_key + - HTPASSWD_FILE=/run/secrets/htpasswd # HTPASSWD_FILE can be whatever as it is not used/called anywhere. + secrets: + - cloudflare_email + - cloudflare_api_key + - htpasswd + 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.$DOMAINNAME0`)" + ## Services - API + - "traefik.http.routers.traefik-rtr.service=api@internal" + ## Healthcheck/ping + #- "traefik.http.routers.ping.rule=Host(`traefik.$DOMAINNAME0`) && Path(`/ping`)" + #- "traefik.http.routers.ping.tls=true" + #- "traefik.http.routers.ping.service=ping@internal" + ## Middlewares + - "traefik.http.routers.traefik-rtr.middlewares=chain-oauth@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: 192.168.91.254 # 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 # Portaienr + - VOLUMES=1 # Portainer + + # Google OAuth - Single Sign On using OAuth 2.0 + # https://www.smarthomebeginner.com/google-oauth-with-traefik-docker/ + oauth: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: oauth + image: thomseddon/traefik-forward-auth:latest + # image: thomseddon/traefik-forward-auth:2.1-arm # Use this image with Raspberry Pi + # Allow apps to bypass OAuth. Radarr example below will bypass OAuth if API key is present in the request (eg. from NZB360 mobile app). + # While this is one way, the recommended way is to bypass authentication using Traefik labels shown in some of the apps later. + # command: --rule.radarr.action=allow --rule.radarr.rule="Headers(`X-Api-Key`, `$RADARR_API_KEY`)" + # command: --rule.sabnzbd.action=allow --rule.sabnzbd.rule="HeadersRegexp(`X-Forwarded-Uri`, `$SABNZBD_API_KEY`)" + environment: + - PROVIDERS_GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID + - PROVIDERS_GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET + - SECRET=$OAUTH_SECRET + - COOKIE_DOMAIN=$DOMAINNAME0 + - INSECURE_COOKIE=false + - AUTH_HOST=oauth.$DOMAINNAME0 + - URL_PATH=/_oauth + - WHITELIST=$MY_EMAIL + - LOG_LEVEL=warn + - LOG_FORMAT=text + - LIFETIME=86400 # 1 day + - DEFAULT_ACTION=auth + - DEFAULT_PROVIDER=google + secrets: # had trouble getting secrets to work: https://github.com/thomseddon/traefik-forward-auth/issues/155#issuecomment-664630985 + - google_client_id + - google_client_secret + - oauth_secret + - my_email + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.oauth-rtr.tls=true" + - "traefik.http.routers.oauth-rtr.entrypoints=https" + - "traefik.http.routers.oauth-rtr.rule=Host(`oauth.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.oauth-rtr.middlewares=chain-oauth@file" + ## HTTP Services + - "traefik.http.routers.oauth-rtr.service=oauth-svc" + - "traefik.http.services.oauth-svc.loadbalancer.server.port=4181" + + # Portainer - WebUI for Containers + portainer: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: portainer + image: portainer/portainer-ce:latest + # command: -H unix:///var/run/docker.sock # # Use Docker Socket Proxy instead for improved security + command: -H tcp://socket-proxy:2375 + networks: + - t2_proxy + - socket_proxy + volumes: + # - /var/run/docker.sock:/var/run/docker.sock:ro # # Use Docker Socket Proxy instead for improved security + - $DOCKERDIR/appdata/portainer/data:/data # Change to local directory if you want to save/transfer config locally + environment: + - TZ=$TZ + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.portainer-rtr.entrypoints=https" + - "traefik.http.routers.portainer-rtr.rule=Host(`portainer.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.portainer-rtr.middlewares=chain-oauth@file" + ## HTTP Services + - "traefik.http.routers.portainer-rtr.service=portainer-svc" + - "traefik.http.services.portainer-svc.loadbalancer.server.port=9000" + + # Autoindex - Simple Directory Index + autoindex: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + container_name: autoindex + image: dceoy/nginx-autoindex:latest + # ports: + # - "$AUTOINDEX_PORT:80" + volumes: + #- $USERDIR:/var/lib/nginx/html:ro # Location you want to index + - $USERDIR:/var/lib/nginx/html:ro # Location you want to index + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.autoindex-rtr.entrypoints=https" + - "traefik.http.routers.autoindex-rtr.rule=Host(`index.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.autoindex-rtr.middlewares=chain-oauth@file" + ## HTTP Services + - "traefik.http.routers.autoindex-rtr.service=autoindex-svc" + - "traefik.http.services.autoindex-svc.loadbalancer.server.port=80" + + ############################# DATABASE + + # 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 + ports: + - "$MARIADB_PORT:3306" + volumes: + - $DOCKERDIR/appdata/mariadb/data:/config + environment: + - PUID=$PUID + - PGID=$PGID + - TZ=$TZ + - FILE__MYSQL_ROOT_PASSWORD=/run/secrets/mysql_root_password # Note FILE__ (double underscore) - Issue #127 + secrets: + - mysql_root_password + + # InfluxDB - Database for sensor data + # Create influxdb.conf + influxdb: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + image: influxdb:latest + container_name: influxdb + ports: + - "$INFLUXDB_PORT:8086" + - "$INFLUXDB_PORT_PROXMOX:8087/udp" + volumes: + - $DOCKERDIR/appdata/influxdb/etc/influxdb.conf:/etc/influxdb/influxdb.conf:ro + - $DOCKERDIR/appdata/influxdb/db:/var/lib/influxdb + # command: -config /etc/influxdb/influxdb.conf + + # Redis - Key-value Store + redis: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: redis + image: redis:latest + entrypoint: redis-server --appendonly yes --requirepass $REDIS_PASSWORD --maxmemory 512mb --maxmemory-policy allkeys-lru + ports: + - "$REDIS_PORT:6379" + volumes: + - $DOCKERDIR/appdata/redis/data:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + + # Redis Commander - Redis Management Tool + rediscommander: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + container_name: rediscommander + image: rediscommander/redis-commander:latest + # ports: + # - "$REDISCOMMANDER_PORT:8081" + environment: + - REDIS_HOST=$REDIS_HOST + - REDIS_PASSWORD=$REDIS_PASSWORD + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.rediscommander-rtr.entrypoints=https" + - "traefik.http.routers.rediscommander-rtr.rule=Host(`rediscom.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.rediscommander-rtr.middlewares=chain-oauth@file" + ## HTTP Services + - "traefik.http.routers.rediscommander-rtr.service=rediscommander-svc" + - "traefik.http.services.rediscommander-svc.loadbalancer.server.port=8081" + + # phpMyAdmin - Database management + # Create a new user with admin privileges. Cannot login as MySQL root for some reason. + phpmyadmin: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: phpmyadmin/phpmyadmin:latest + container_name: phpmyadmin + # ports: + # - "$PHPMYADMIN_PORT:80" + # volumes: + # - $DOCKERDIR/appdata/phpmyadmin:/etc/phpmyadmin + environment: + - PMA_HOST=$MARIADB_HOST + - PMA_PORT=$MARIADB_PORT + #- PMA_ARBITRARY=1 + - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password + secrets: + - mysql_root_password + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.phpmyadmin-rtr.entrypoints=https" + - "traefik.http.routers.phpmyadmin-rtr.rule=Host(`pma.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.phpmyadmin-rtr.middlewares=chain-oauth@file" + ## HTTP Services + - "traefik.http.routers.phpmyadmin-rtr.service=phpmyadmin-svc" + - "traefik.http.services.phpmyadmin-svc.loadbalancer.server.port=80" + + ########################### WEB + + # Nginx - Web Server + nginx: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: nginx + image: nginx:1.20 # 1.18 # Updated 8/9/2021 + depends_on: + - php7 + volumes: + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + - /var/log/nginx:/var/log/nginx + - $DOCKERDIR/appdata/nginx:/etc/nginx + - $DOCKERDIR/shared/.htpassd:/shared/.htpasswd + - $DOCKERDIR/sites/shb/html:/var/www/html/shb + - $DOCKERDIR/sites/shb/beta:/var/www/html/beta + - $DOCKERDIR/sites/khub/html:/var/www/html/khub + - $DOCKERDIR/sites/dash/html:/var/www/html/dash + labels: + - "traefik.enable=true" + ## HTTP Routers SHB (WordPress) Auth + - "traefik.http.routers.nginx-shb-auth-rtr.entrypoints=https" + - "traefik.http.routers.nginx-shb-auth-rtr.rule=Host(`www.$DOMAINNAME0`) && Path(`/wp-login.php`)" + - "traefik.http.routers.nginx-shb-auth-rtr.priority=100" + ## HTTP Routers SHB (WordPress) Bypass + - "traefik.http.routers.nginx-shb-rtr.entrypoints=https" + - "traefik.http.routers.nginx-shb-rtr.rule=Host(`$DOMAINNAME0`) || Host(`www.$DOMAINNAME0`)" + - "traefik.http.routers.nginx-shb-rtr.priority=99" + ## HTTP Routers SHB Beta (WordPress) + - "traefik.http.routers.nginx-shb-beta-rtr.entrypoints=https" + - "traefik.http.routers.nginx-shb-beta-rtr.rule=Host(`beta.$DOMAINNAME0`)" + ## HTTP Routers DASH (non-WordPress) + - "traefik.http.routers.nginx-dash-rtr.entrypoints=https" + - "traefik.http.routers.nginx-dash-rtr.rule=Host(`dash.$DOMAINNAME0`)" + ## HTTP Routers KHUB (non-WordPress) + - "traefik.http.routers.nginx-khub-rtr.entrypoints=https" + - "traefik.http.routers.nginx-khub-rtr.rule=Host(`$DOMAINNAME1`) || Host(`www.$DOMAINNAME1`)" + # Redirect shb non-www to www middleware + - "traefik.http.middlewares.shb-redirect.redirectregex.regex=^https?://$DOMAINNAME0/(.*)" + - "traefik.http.middlewares.shb-redirect.redirectregex.replacement=https://www.$DOMAINNAME0/$${1}" + - "traefik.http.middlewares.shb-redirect.redirectregex.permanent=true" + # Redirect khub non-www to www middleware + - "traefik.http.middlewares.khub-redirect.redirectregex.regex=^https?://$DOMAINNAME1/(.*)" + - "traefik.http.middlewares.khub-redirect.redirectregex.replacement=https://www.$DOMAINNAME1/$${1}" + - "traefik.http.middlewares.khub-redirect.redirectregex.permanent=true" + ## Middlewares + - "traefik.http.routers.nginx-khub-rtr.middlewares=khub-redirect,chain-no-auth@file" + - "traefik.http.routers.nginx-shb-rtr.middlewares=shb-redirect,chain-no-auth-wp@file" + #- "traefik.http.routers.nginx-shb-auth-rtr.middlewares=shb-redirect,chain-oauth-wp@file" + - "traefik.http.routers.nginx-shb-auth-rtr.middlewares=shb-redirect,chain-no-auth-wp@file" + - "traefik.http.routers.nginx-dash-rtr.middlewares=chain-oauth@file" + - "traefik.http.routers.nginx-shb-beta-rtr.middlewares=chain-oauth@file" + ## HTTP Services + - "traefik.http.routers.nginx-shb-rtr.service=nginx-svc" + - "traefik.http.routers.nginx-shb-auth-rtr.service=nginx-svc" + - "traefik.http.routers.nginx-khub-rtr.service=nginx-svc" + - "traefik.http.routers.nginx-dash-rtr.service=nginx-svc" + - "traefik.http.routers.nginx-shb-beta-rtr.service=nginx-svc" + - "traefik.http.services.nginx-svc.loadbalancer.server.port=80" + + # PHP - Hypertext Preprocessor + php7: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + container_name: php7 + image: php:7.4-fpm-custom + build: + context: $DOCKERDIR/custom/ + dockerfile: Dockerfile-php7 + user: $PUID:$PGID # allows upgrading WP and plugins + volumes: + - $DOCKERDIR/sites/shb/html:/var/www/html/shb + - $DOCKERDIR/sites/shb/beta:/var/www/html/beta + - $DOCKERDIR/appdata/php/php7:/usr/local/etc/php + - $DOCKERDIR/sites/khub/html:/var/www/html/khub + - $DOCKERDIR/sites/dash/html:/var/www/html/dash + + ########################### UTILITIES + + # VSCode - VSCode Editing + vscode: + <<: *common-keys-basic # See EXTENSION FIELDS at the top + image: codercom/code-server:latest + container_name: vscode + volumes: + - $USERDIR/server:/home/coder/server + - $DOCKERDIR:/home/coder/docker + - $DOCKERDIR/appdata/vscode:/home/coder + environment: + PASSWORD: $VSCODE_PASSWORD + # Run as root first, create the directories, then change permissions to user:docker and 775. Disable run as root below. + user: $PUID:$PGID + #user: "0" + DOCKER_HOST: tcp://socket-proxy:2375 + labels: + - "traefik.enable=true" + ## HTTP Routers + - "traefik.http.routers.vscode-rtr.entrypoints=https" + - "traefik.http.routers.vscode-rtr.rule=Host(`code.$DOMAINNAME0`)" + ## Middlewares + - "traefik.http.routers.vscode-rtr.middlewares=chain-oauth@file" + ## HTTP Services + - "traefik.http.routers.vscode-rtr.service=vscode-svc" + - "traefik.http.services.vscode-svc.loadbalancer.server.port=8080" + + ############################# MAINTENANCE + + # Docker-GC - Automatic Docker Garbage Collection + # Create docker-gc-exclude file + dockergc: + <<: *common-keys-apps # See EXTENSION FIELDS at the top + image: clockworksoul/docker-gc-cron:latest + container_name: docker-gc + networks: + - socket_proxy + volumes: + # - /var/run/docker.sock:/var/run/docker.sock # Use Docker Socket Proxy instead for improved security + - $DOCKERDIR/appdata/docker-gc/docker-gc-exclude:/etc/docker-gc-exclude + environment: + CRON: 12 0 0 * * ? # Everyday at midnight. + FORCE_IMAGE_REMOVAL: 1 + FORCE_CONTAINER_REMOVAL: 0 + GRACE_PERIOD_SECONDS: 604800 + DRY_RUN: 0 + CLEAN_UP_VOLUMES: 1 + TZ: $TZ + DOCKER_HOST: tcp://socket-proxy:2375