❔Deploy new Container Stack

Required Knowledge

Create Compose file in Github

All compose files are stored in the Docker-Compose folder inside GitHub with format .yml

Refer to GitHub / GitOps

Handling Variables

When variables are used, such as variables for Ports, please use the ${VARIABLENAME:-DefaultValue} structure. This ensures that if the variable is not set, it will be set to the default rather than null. Some containers will not start with null variables. Some example use cases;

ports:
  - ${PORT:-8200}:8200  #If a $PORT variable is not provided, it will default to 8200
environment:
  - CONFIGFILE=${CONFIGFILE:-/path/to/config.yml} #if the $CONFIGFILE variable is not provided, it will default to /path/to/config.yml

Logging

Each container should have the below to ensure that logging is reduced. The settings can be tweaked where required.

    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3" 

DockFlare

DockFlare is a container that automates creation and removal of Cloudflare Zero Trust Tunnels using labels, refer to DockFlare (CF Zero Trust)

In the below example, we'll configure this for the "overseerr" container. Refer to Overseerr to see a complete compose file

HTTP

Labels for the container
      - dockflare.enable=${CFTUNNEL:-true}
      - dockflare.0.hostname=${CFSUBDOMAIN}${CFDOMAIN}
      - dockflare.0.service=http://${HOSTNAME}:${PORT:-5055}
      - dockflare.0.access.policy=${CFPOLICY:-default_tld}
      - dockflare.0.zonename=${CFDOMAIN}
      - dockflare.0.path=${CFURLPATH:-}

HTTPS

Labels for the container
      - dockflare.0.hostname=${CFSUBDOMAIN}${CFDOMAIN}
      - dockflare.0.service=http://${HOSTNAME}:${PORT:-5055}
      - dockflare.0.access.policy=${CFPOLICY:-default_tld}
      - dockflare.0.zonename=${CFDOMAIN}
      - dockflare.0.path=${CFURLPATH:-}
      - dockflare.0.no_tls_verify=true

Don't forget to ammend the default value for the port variable

As you may see, you can have multiple tunnels assigned to 1 container using the numeric value, eg dockflare.0.x, dockflare.1.x etc

On stacks without networks, it is also worth mapping to the cloudflare-net network;

services:
    myapp:
        networks:
            - cloudflare-net
networks:
    cloudflare-net:
        name: cloudflare-net
        external: true

And the variables to make DockFlare automate the creation of the tunnel,

Subdomain with URL path

.env
CFSUBDOMAIN= #Include a . at the end - MANDATORY
CFDOMAIN=
CFURLPATH=/
HOSTNAME=

Subdomain

.env
CFSUBDOMAIN= #Include a . at the end - MANDATORY
CFDOMAIN=
HOSTNAME=

Root domain

.env
CFDOMAIN=
HOSTNAME=

Root domain with URL path

.env
CFDOMAIN=
CFURLPATH=/
HOSTNAME=

The HOSTNAME variable is the IP or local DNS address for the host, eg myserver.local or 192.168.1.10

Health Checks

Where possible, all containers should have health checks. We utilize the AutoHeal container which will restart unhealthy containers. The intention of this is to automate DR.

Here are some examples of health checks;

Web UI

Port (80 below) needs to be set as the containers port (right hand side of the port mapping)

        healthcheck:
      test: curl --connect-timeout 15 --silent --show-error --fail -k http://LOCALHOST:80
      interval: 30s
      retries: 3
      start_period: 30s
      timeout: 20s
    labels:
      - autoheal=true
        healthcheck:
      test: wget --no-verbose --tries=1 --spider http://LOCALHOST:80 -O /dev/null || exit 1
      interval: 30s
      retries: 3
      start_period: 30s
      timeout: 20s
    labels:
      - autoheal=true

MongoDB

        healthcheck:
      test: ["CMD", "mongo", "--eval", "db.adminCommand('ping')"]
      interval: 30s
      timeout: 10s
      retries: 5
    labels:
      - autoheal=true
        healthcheck:
      test: ["CMD-SHELL", "pidof mongod || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
    labels:
      - autoheal=true

MariaDB

    healthcheck:
      test: ["CMD", "mariadb-admin", "ping", "-proot", "--password=$MYSQL_PASS_ROOT"]
      interval: 30s
      timeout: 10s
      retries: 5
    labels:
      - autoheal=true

Deploy Stack

What server?

Pick a server that is relevant to the use-case.

  • If the app relates to Plex, the container should be installed on the same host as the Plex server

  • If the app requires a GPU, the container should be on a server with a GPU

  • If the app relates to Pterodactyl, it should be installed on the same server as either the panel or wings.

  • Etc

Deploy Stack

ENV file required?

If an ENV file is required,

  1. Run the below command to CD into the Portainer files

    cd /var/snap/docker/common/var-lib-docker/volumes/portainer/_data/env
  2. Run the below command (correct the file name) to create a new ENV file,

    nano myapp.env
  3. Paste the contents of the ENV file and save it

  4. Update the Docker Compose file to reference the env file per below

        env_file:
          - $ENV
  5. Update the stack and set the ENV variable as below (correct the file name)

    /data/env/myapp.env
  6. Save and stop the stack

  7. Delete and related docker volumes

  8. Pull and deploy the stack

Last updated

Was this helpful?