Docker Stack

My main server machine, pages about what is running and how it is configured

AdminTools

AdminTools

Portainer

Docker container management

All containers are in docker compose, but this is a good overview screen

 

  portainer:
    image: portainer/portainer-ce:latest
    container_name: "portainer"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /mnt/user/Share/Docker/portainer:/data
    restart: always
    links:
      - traefik
    networks:
      web:
        ipv4_address: 172.18.0.253
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.portainer-web.rule=Host(`docker.kevinsloan.net`)"
      - "traefik.http.routers.portainer-web.entrypoints=web"
      - "traefik.http.routers.portainer-secured.rule=Host(`docker.kevinsloan.net`)"
      - "traefik.http.routers.portainer-secured.entrypoints=web-secured"
      - "traefik.http.routers.portainer-secured.tls.certresolver=mytlschallenge"
      - "traefik.http.services.portainer.loadbalancer.server.port=9000"
AdminTools

Traefik

Traefik used for ingress and cert management

traefik:
    image: traefik:v3
    restart: always
    container_name: traefik
    ports:
      - "80:80" # <== http
      #- "8080:8080" # <== :8080 is where the dashboard runs on
      - "443:443" # <== https
    command:
      #### These are the CLI commands that will configure Traefik and tell it how to work! ####
      ## API Settings - https://docs.traefik.io/operations/api/, endpoints - https://docs.traefik.io/operations/api/#endpoints ##
      - --api=true # <== Enabling insecure api, NOT RECOMMENDED FOR PRODUCTION
      - --api.dashboard=true # <== Enabling the dashboard to view services, middlewares, routers, etc...
      - --api.debug=true # <== Enabling additional endpoints for debugging and profiling
      - --serverstransport.insecureskipverify=true
      - --log.level=INFO
      #- --log.filepath=/var/logs/traefik.log
      - --accesslog=true
      #- --accesslog.filepath=/var/logs/traefik-access.log

      ## Log Settings (options: ERROR, DEBUG, PANIC, FATAL, WARN, INFO) - https://docs.traefik.io/observability/logs/ ##
      #- --log.level=DEBUG # <== Setting the level of the logs from traefik

      ## Provider Settings - https://docs.traefik.io/providers/docker/#provider-configuration ##
      - --providers.docker=true # <== Enabling docker as the provider for traefik
      - --providers.docker.exposedbydefault=false # <== Don't expose every container to traefik, only expose enabled ones
      - --providers.file.filename=/dynamic.yml # <== Referring to a dynamic configuration file
      - --providers.file.directory=/rules
      - --providers.docker.network=web # <== Operate on the docker network named web

      ## Entrypoints Settings - https://docs.traefik.io/routing/entrypoints/#configuration ##
      - --entrypoints.web.address=:80 # <== Defining an entrypoint for port :80 named web
      - --entrypoints.web-secured.address=:443 # <== Defining an entrypoint for https on port :443 named web-secured
      - --entrypoints.web.http.redirections.entrypoint.to=web-secured
      - --entryPoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.web-secured.asDefault=true
      - --entrypoints.web-secured.http.tls.certResolver=mytlschallenge

      ## Certificate Settings (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesResolvers.mytlschallenge.acme.httpChallenge.entryPoint=web
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== Enable TLS-ALPN-01 to generate and renew ACME certs
      - --certificatesresolvers.mytlschallenge.acme.email=kevin@kevinsloan.net # <== Setting email for certs
      - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== Defining acme file to store cert information

    volumes:
      - ./.letsencrypt:/letsencrypt # <== Volume for certs (TLS)
      - /var/run/docker.sock:/var/run/docker.sock # <== Volume for docker admin
      - ./dynamic.yml:/dynamic.yml # <== Volume for dynamic conf file, **ref: line 27
      - ./rules:/rules
      - /mnt/user/Share/Docker/Traefik/logs:/var/logs

    networks:
      ## Placing traefik on the network named web, to access containers on this network
      web:
        ipv4_address: 172.18.0.2

    labels:
      #### Labels define the behavior and rules of the traefik proxy for this container ####
      - traefik.enable=true # <== Enable traefik on itself to view dashboard and assign subdomain to view it
      - traefik.http.routers.traefik-web.rule=Host(`traefik.kevinsloan.net`) # <== Setting the domain for the dashboard
      - traefik.http.routers.traefik-web.entrypoints=web
      - traefik.http.routers.traefik-secured.rule=Host(`traefik.kevinsloan.net`)
      - traefik.http.routers.traefik-secured.entrypoints=web-secured
      - traefik.http.routers.traefik-secured.service=api@internal # <== Enabling the api to be a service to access

 

rules directory to setup custom entrypoints

aoo-hassio.toml

[http.routers]
  [http.routers.hassio-rtr]
      entryPoints = ["web-secured"]
      rule = "Host(`homeassist.kevinsloan.net`)"
      service = "hassio-svc"
      [http.routers.hassio-rtr.tls]
        certresolver = "mytlschallenge"

[http.services]
  [http.services.hassio-svc]
    [http.services.hassio-svc.loadBalancer]
      passHostHeader = true
      [[http.services.hassio-svc.loadBalancer.servers]]
        url = "http://192.168.123.108:8123" # or whatever your external host's IP:port is

app-kuma.toml

[http.routers]
  [http.routers.kuma-rtr]
      entryPoints = ["web-secured"]
      rule = "Host(`kuma-uptime.kevinsloan.net`)"
      service = "kuma-svc"
      [http.routers.kuma-rtr.tls]
        certresolver = "mytlschallenge"

[http.services]
  [http.services.kuma-svc]
    [http.services.kuma-svc.loadBalancer]
      [[http.services.kuma-svc.loadBalancer.servers]]
        url = "http://192.168.123.101:80" # or whatever your external host's IP:port is

app-pihole.toml

[http.routers]
  [http.routers.pihole-rtr]
      entryPoints = ["web-secured"]
      rule = "Host(`pihole.kevinsloan.net`)"
      service = "pihole-svc"
      [http.routers.pihole-rtr.tls]
        certresolver = "mytlschallenge"

[http.services]
  [http.services.pihole-svc]
    [http.services.pihole-svc.loadBalancer]
      [[http.services.pihole-svc.loadBalancer.servers]]
        url = "http://192.168.123.107:80" # or whatever your external host's IP:port is

 

AdminTools

MySql

mysql db server used for other apps

  mysql:
    image: mysql:8.0
    container_name: "mysql"
    restart: "always"
    ports:
      - "3306:3306"
    volumes:
      - /mnt/user/Share/Docker/Webhost/mysql/data:/var/lib/mysql
      - /mnt/user/Share/Docker/Webhost/mysql/logs:/var/log/mysql
      - /mnt/user/Share/Docker/ombi/config:/tempombi/config
    environment:
      MYSQL_ROOT_PASSWORD: ${PASSWORD}
      MYSQL_DATABASE: website
      MYSQL_USER: ${USERNAME}
      MYSQL_PASSWORD: ${PASSWORD}
    networks:
      web:
        ipv4_address: 172.18.0.13
AdminTools

Guacamole

GuacD

Guacamole Daemon used for VNC, RDP, and SSH remotely

guacd:
    image: guacamole/guacd
    container_name: "guacd"
    restart: always
    networks:
      web:
        ipv4_address: 172.18.0.3

Guacamole

Apache Guacamole used for VNC, RDP, and SSH remotely requires GuacD

guacamole:
    image: guacamole/guacamole
    container_name: "guacamole"
    restart: always
    networks:
      web:
        ipv4_address: 172.18.0.4
    links:
      - guacd
      - traefik
    environment:
      - GUACD_HOSTNAME=guacd
      - MYSQL_HOSTNAME=mysql
      - MYSQL_DATABASE=guacamole_db
      - MYSQL_USER=${USERNAME}
      - MYSQL_PASSWORD=${PASSWORD}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.guac-web.rule=Host(`guac.kevinsloan.net`)"
      - "traefik.http.routers.guac-web.entrypoints=web"
      - "traefik.http.middlewares.add-guacamole.addprefix.prefix=/guacamole"
      - "traefik.http.routers.guac-secured.middlewares=add-guacamole"
      - "traefik.http.routers.guac-secured.rule=Host(`guac.kevinsloan.net`)"
      - "traefik.http.routers.guac-secured.entrypoints=web-secured"
AdminTools

Duplicati

Duplicati used for backups

Backing up both locally and to google drive all app configs

docker compose backup handled by github

  duplicati:
    image: linuxserver/duplicati
    container_name: duplicati
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    volumes:
      - /mnt/user/Share/Docker/duplicati/config:/config
      - /mnt/user/FTP/backups:/backups
      - /mnt/user/Share/Docker:/source
    restart: unless-stopped
    links:
      - traefik
    networks:
      web:
        ipv4_address: 172.18.0.254
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.duplicati-web.rule=Host(`backup.kevinsloan.net`)"
      - "traefik.http.routers.duplicati-web.entrypoints=web"
      - "traefik.http.routers.duplicati-secured.rule=Host(`backup.kevinsloan.net`)"
      - "traefik.http.routers.duplicati-secured.entrypoints=web-secured"
AdminTools

Visual Studio Code

Web version of VSCode

  vscode:
    image: ksloan90/code-server:latest
    container_name: vscode
    restart: unless-stopped
    links:
      - traefik
    networks:
      web:
        ipv4_address: 172.18.0.20
    environment:
      - PUID=1000
      - GUID=1000
      - PASSWORD=${PASSWORD}
    volumes:
      - /mnt/user/Share/Docker/vscode:/config
      - /mnt/user/Share:/share
      #- /home/sloan:/home/sloan
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vscode-web.rule=Host(`vscode.kevinsloan.net`)"
      - "traefik.http.routers.vscode-web.entrypoints=web"
      - "traefik.http.routers.vscode-secured.rule=Host(`vscode.kevinsloan.net`)"
      - "traefik.http.routers.vscode-secured.entrypoints=web-secured"
      - "com.centurylinklabs.watchtower.enable=false"
AdminTools

Bookstack

Bookstack pages used for documentation

  bookstack:
    image: linuxserver/bookstack
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - DB_HOST=mysql
      - DB_USER=${USERNAME}
      - DB_PASS=${PASSWORD}
      - DB_DATABASE=bookstack
      - APP_URL=https://wiki.kevinsloan.net
    networks:
      web:
        ipv4_address: 172.18.0.23
    volumes:
      - /mnt/user/Share/Docker/bookstack/config:/config
    restart: unless-stopped
    depends_on:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.bookstack-web.rule=Host(`wiki.kevinsloan.net`)"
      - "traefik.http.routers.bookstack-web.entrypoints=web"
      - "traefik.http.routers.bookstack-secured.rule=Host(`wiki.kevinsloan.net`)"
      - "traefik.http.routers.bookstack-secured.entrypoints=web-secured"

AdminTools

Droppy

droppy app for quickly sharing files

  droppy:
    image: silverwind/droppy
    container_name: droppy
    restart: unless-stopped
    networks:
      web:
        ipv4_address: 172.18.0.15
    volumes:
      - /mnt/user/Share/Docker/droppy/config:/config
      - /mnt/user/FTP:/files
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=${TZ}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.droppy-web.rule=Host(`cloud.kevinsloan.net`)"
      - "traefik.http.routers.droppy-web.entrypoints=web"
      - "traefik.http.routers.droppy-secured.rule=Host(`cloud.kevinsloan.net`)"
      - "traefik.http.routers.droppy-secured.entrypoints=web-secured"

 

AdminTools

watchtower

Watchtower to auto-update containers

  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - TZ=${TZ}
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_SCHEDULE=0 0 7 * * *
      #- WATCHTOWER_POLL_INTERVAL=10      
      - WATCHTOWER_NOTIFICATIONS=slack
      - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL=${Slack_Watchtower_URL}
    restart: unless-stopped

 

AdminTools

OSTicket

Ticket app to help organize plex issues for working

  osticket:
    image: devinsolutions/osticket
    container_name: "osticket"
    restart: always
    networks:
      web:
        ipv4_address: 172.18.0.12
    links:
      - mysql:mysql
      - traefik
    environment:
      - MYSQL_HOST=mysql
      - MYSQL_DATABASE=osticket_db
      - MYSQL_USER=${USERNAME}
      - MYSQL_PASSWORD=${PASSWORD}
      - TZ=${TZ}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.osticket-web.rule=Host(`help.kevinsloan.net`)"
      - "traefik.http.routers.osticket-web.entrypoints=web"
      - "traefik.http.routers.osticket-secured.rule=Host(`help.kevinsloan.net`)"
      - "traefik.http.routers.osticket-secured.tls=true"
      - "traefik.http.routers.osticket-secured.entrypoints=web-secured"

 

Plex

Plex related apps

Plex

Transmission

  transmission:
    container_name: transmission
    image: haugene/transmission-openvpn
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    restart: unless-stopped
    ports:
      - 9091:9091
      - 51413:51413
      - 51413:51413/udp
    dns:
      - 8.8.4.4
      - 8.8.8.8
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /drivespace/movies/downloads:/data
    environment:
      - OPENVPN_PROVIDER=PIA
      - OPENVPN_CONFIG=CA Montreal
      - OPENVPN_USERNAME=${OPENVPN_USERNAME}
      - OPENVPN_PASSWORD=${PASSWORD}
      - OPENVPN_OPTS=--inactive 3600 --ping 10 --ping-exit 60 --mssfix 1300 #mssfix will hopefully resolve bad packet id errors
      - LOCAL_NETWORK=192.168.120.0/22
      - TRANSMISSION_RATIO_LIMIT_ENABLED=true #was true but trying false and manual monitoring
      - TRANSMISSION_RATIO_LIMIT=5
      - TRANSMISSION_WEB_UI=kettu #sexier UI
      - TRANSMISSION_SCRAPE_PAUSED_TORRENTS_ENABLED=false #useful if having issue with pulling down torrent info
      - TRANSMISSION_DHT_ENABLED=false #disallows sharing outside of private tracker
      - TRANSMISSION_PEX_ENABLED=false #similar to above
      - TRANSMISSION_ENCRYPTION=1 #prefer encrypted connections
      - TRANSMISSION_WATCH_DIR_ENABLED=true 
      - TRANSMISSION_WATCH_DIR=/data/watching
      - TRANSMISSION_INCOMPLETE_DIR=/data/incomplete
      - TRANSMISSION_INCOMPLETE_DIR_ENABLED=true 
      - TRANSMISSION_DOWNLOAD_DIR=/data/completed
      - TRANSMISSION_DOWNLOAD_QUEUE_ENABLED=1 #enables download queue to go beyond limit of 5
      - TRANSMISSION_DOWNLOAD_QUEUE_SIZE=50 #increase download queue to 50 assuming
      - TRANSMISSION_QUEUE_STALLED_ENABLED=false #stop downloads pausing when stalled
      - TRANSMISSION_SCRIPT_TORRENT_DONE_ENABLED=true #enable script on download completion
      - TRANSMISSION_SCRIPT_TORRENT_DONE_FILENAME=/data/unrar #script to run
      - PGID=1000
      - PUID=1000 
    networks:
      web:
        ipv4_address: 172.18.0.5
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.transmission-web.rule=Host(`downloads.kevinsloan.net`)"
      - "traefik.http.routers.transmission-web.entrypoints=web"
      - "traefik.http.routers.transmission-web.middlewares=redirect@file"
      - "traefik.http.routers.transmission-secured.rule=Host(`downloads.kevinsloan.net`)"
      - "traefik.http.routers.transmission-secured.entrypoints=web-secured"
      - "traefik.http.routers.transmission-secured.tls.certresolver=mytlschallenge"
      - "traefik.http.routers.transmission-secured.middlewares=test-auth@file"
      - "traefik.http.services.transmission.loadbalancer.server.port=9091"
Plex

Sonarr

  sonarr:
    image: linuxserver/sonarr
    container_name: sonarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - UMASK_SET=022 #optional
    volumes:
      - /Docker/trackers/Sonarr:/config
      - /drivespace/TV:/tv
      - /drivespace/movies/downloads/completed:/downloads
      - /drivespace/movies/downloads/completed:/data/completed
    restart: unless-stopped
    networks:
      web:
        ipv4_address: 172.18.0.7
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.sonarr-web.rule=Host(`sonarr.kevinsloan.net`)"
      - "traefik.http.routers.sonarr-web.entrypoints=web"
      - "traefik.http.routers.sonarr-web.middlewares=redirect@file"
      - "traefik.http.routers.sonarr-secured.rule=Host(`sonarr.kevinsloan.net`)"
      - "traefik.http.routers.sonarr-secured.entrypoints=web-secured"
      - "traefik.http.routers.sonarr-secured.tls.certresolver=mytlschallenge"
      - "traefik.http.routers.sonarr-secured.middlewares=test-auth@file"
Plex

Radarr

  radarr:
    image: linuxserver/radarr
    container_name: radarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - UMASK_SET=022 #optional
    volumes:
      - /Docker/trackers/Radarr:/config
      - /drivespace/movies/movies_real:/movies
      - /drivespace/movies/downloads/completed:/downloads
      - /drivespace/movies/downloads/completed:/data/completed #adding this because importer was looking for "data"
    restart: unless-stopped
    networks:
      web:
        ipv4_address: 172.18.0.8
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.radarr-web.rule=Host(`radarr.kevinsloan.net`)"
      - "traefik.http.routers.radarr-web.entrypoints=web"
      - "traefik.http.routers.radarr-web.middlewares=redirect@file"
      - "traefik.http.routers.radarr-secured.rule=Host(`radarr.kevinsloan.net`)"
      - "traefik.http.routers.radarr-secured.entrypoints=web-secured"
      - "traefik.http.routers.radarr-secured.tls.certresolver=mytlschallenge"    
      - "traefik.http.routers.radarr-secured.middlewares=test-auth@file"
Plex

Jackett

  jackett:
    image: linuxserver/jackett
    container_name: jackett 
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    volumes:
      - /Docker/trackers/Jackett:/config
      - /drivespace/movies/downloads/completed:/downloads
    restart: unless-stopped
    networks:
      web:
        ipv4_address: 172.18.0.6
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.jackett-web.rule=Host(`jackett.kevinsloan.net`)"
      - "traefik.http.routers.jackett-web.entrypoints=web"
      - "traefik.http.routers.jackett-web.middlewares=redirect@file"
      - "traefik.http.routers.jackett-secured.rule=Host(`jackett.kevinsloan.net`)"
      - "traefik.http.routers.jackett-secured.entrypoints=web-secured"
      - "traefik.http.routers.jackett-secured.tls.certresolver=mytlschallenge"
Plex

Plex

  plex:
    image: linuxserver/plex
    container_name: plex
    environment:
      - PUID=1000
      - PGID=1000
      - VERSION=docker
      - UMASK_SET=022 #optional
      - PLEX_CLAIM="claim-TC4UsrTshyZ2qCUWPy7o"
    volumes:
      - /Docker/Plex/Library:/config
      - /drivespace/TV:/tv
      - /drivespace/movies:/movies
      - /mnt/RAMDISK:/transcode
    restart: unless-stopped
    networks:
      web:
        ipv4_address: 172.18.0.9
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plex-web.rule=Host(`plex.kevinsloan.net`)"
      - "traefik.http.routers.plex-web.entrypoints=web"
      - "traefik.http.routers.plex-web.middlewares=redirect@file"
      - "traefik.http.routers.plex-secured.rule=Host(`plex.kevinsloan.net`)"
      - "traefik.http.routers.plex-secured.entrypoints=web-secured"
      - "traefik.http.routers.plex-secured.tls.certresolver=mytlschallenge"    
      - "traefik.http.services.plex.loadbalancer.server.port=32400"
Plex

Tautulli

  tautulli:
    image: tautulli/tautulli
    container_name: tautulli
    volumes:
      - /Docker/tautulli:/config
      - /Docker/Plex/Library/Library/Application Support/Plex Media Server/Logs:/plex_logs:ro
    environment:
      - PGID=1000
      - PUID=1000
      - TZ=America/New_York
    networks:
      web:
        ipv4_address: 172.18.0.10
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.tautulli-web.rule=Host(`monitorplex.kevinsloan.net`)"
      - "traefik.http.routers.tautulli-web.entrypoints=web"
      - "traefik.http.routers.tautulli-web.middlewares=redirect@file"
      - "traefik.http.routers.tautulli-secured.rule=Host(`monitorplex.kevinsloan.net`)"
      - "traefik.http.routers.tautulli-secured.entrypoints=web-secured"
      - "traefik.http.routers.tautulli-secured.tls.certresolver=mytlschallenge"
    restart: unless-stopped
Plex

Ombi

  ombi:
    image: linuxserver/ombi
    container_name: ombi
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - BASE_URL=/ombi
    volumes:
      - /Docker/ombi/config:/config
    restart: unless-stopped
    networks:
      web:
        ipv4_address: 172.18.0.17
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ombi-web.rule=Host(`plexRequest.kevinsloan.net`)"
      - "traefik.http.routers.ombi-web.entrypoints=web"
      - "traefik.http.routers.ombi-web.middlewares=redirect@file"
      - "traefik.http.routers.ombi-secured.rule=Host(`plexRequest.kevinsloan.net`)"
      - "traefik.http.routers.ombi-secured.entrypoints=web-secured"
      - "traefik.http.routers.ombi-secured.tls.certresolver=mytlschallenge"

Web

Web

Apache2

Docker-Compose

  webserver:
    build: 
      context: ./bin/webserver
    container_name: 'apache2'
    restart: 'always'
    volumes: 
      - /Docker/Webhost/apache2/www:/var/www/html
      - /Docker/Webhost/apache2/config/php/php.ini:/usr/local/etc/php/php.ini
      - /Docker/Webhost/apache2/config/vhosts:/etc/apache2/sites-enabled
      - /Docker/Webhost/apache2/logs:/var/log/apache2
    ports:
      - 8888:80
    networks:
      web:
        ipv4_address: 172.18.0.11
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.apache-web.rule=Host(`kevinsloan.net`)"
      - "traefik.http.routers.apache-web.entrypoints=web"
      - "traefik.http.routers.apache-web.middlewares=redirect@file"
      - "traefik.http.routers.apache-secured.rule=Host(`kevinsloan.net`)"
      - "traefik.http.routers.apache-secured.entrypoints=web-secured"
      - "traefik.http.routers.apache-secured.tls.certresolver=mytlschallenge"

DockerFile

FROM php:7.1.20-apache

RUN apt-get -y update --fix-missing
RUN apt-get upgrade -y

# Install useful tools
RUN apt-get -y install apt-utils nano wget dialog

# Install important libraries
RUN apt-get -y install --fix-missing apt-utils build-essential git curl libcurl3 libcurl3-dev zip

# Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Install xdebug
RUN pecl install xdebug-2.5.0
RUN docker-php-ext-enable xdebug

# Other PHP7 Extensions

RUN apt-get -y install libmcrypt-dev
RUN docker-php-ext-install mcrypt

RUN apt-get -y install libsqlite3-dev libsqlite3-0 mysql-client
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install pdo_sqlite
RUN docker-php-ext-install mysqli

RUN docker-php-ext-install curl
RUN docker-php-ext-install tokenizer
RUN docker-php-ext-install json

RUN apt-get -y install zlib1g-dev
RUN docker-php-ext-install zip

RUN apt-get -y install libicu-dev
RUN docker-php-ext-install -j$(nproc) intl

RUN docker-php-ext-install mbstring

RUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install -j$(nproc) gd

# Enable apache modules
RUN a2enmod rewrite headers
Web

PHPMyAdmin

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: 'phpmyadmin'
    environment:
      PMA_HOST: mysql
      PMA_PORT: 3306
    volumes: 
      - /sessions
    networks:
      web:
        ipv4_address: 172.18.0.14
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.phpmyadmin-web.rule=Host(`sql.kevinsloan.net`)"
      - "traefik.http.routers.phpmyadmin-web.entrypoints=web"
      - "traefik.http.routers.phpmyadmin-web.middlewares=redirect@file"
      - "traefik.http.routers.phpmyadmin-secured.rule=Host(`sql.kevinsloan.net`)"
      - "traefik.http.routers.phpmyadmin-secured.entrypoints=web-secured"
      - "traefik.http.routers.phpmyadmin-secured.tls.certresolver=mytlschallenge"
    restart: unless-stopped
Web

Organizr

  organizr:
    image: organizrtools/organizr-v2
    container_name: organizr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
    volumes:
      - /Docker/organizr:/config
    networks:
      web:
        ipv4_address: 172.18.0.16
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.organizr-web.rule=Host(`home.kevinsloan.net`)"
      - "traefik.http.routers.organizr-web.entrypoints=web"
      - "traefik.http.routers.organizr-web.middlewares=redirect@file"
      - "traefik.http.routers.organizr-secured.rule=Host(`home.kevinsloan.net`)"
      - "traefik.http.routers.organizr-secured.entrypoints=web-secured"
      - "traefik.http.routers.organizr-secured.tls.certresolver=mytlschallenge"
    restart: unless-stopped