# How to cluster the 4ALLPORTAL with Docker Compose

# General requirements for clustering

If you want to cluster the 4ALLPORTAL, you need the following setups:

  • A shared file system for the assets and data (config) folder
  • Caching should be disabled, so the cluster members work on the exact same data at any point in time
  • A reverse proxy in front of the cluster members to route traffic and provide SSL

# Shared file system

Each cluster member needs access to the same assets and data folder. Both folders must be read- and writeable to user 1000:1000.

  • The assets folder lies in /4allportal/assets per default
  • The data folder lies in /4allportal/data

A shared file system can be achieved via various means, most commonly via a smb / nfs mount.

Make sure to disable caching in the mount configuration.

# Reverse proxy

The cluster needs a reverse proxy in between the user and the cluster itself to provide routing to the members and SSL.

We recommend træfik (opens new window), as it is easy to configure and has a modern feature set.

# Examples for Docker clusters

# Local cluster without SSL for cluster testing purposes

Create the following docker-compose.yaml

version: "3"

services:
  4allportal:
    image: registry.4allportal.net/4allportal:SNAPSHOT
    volumes:
      - ./assets:/4allportal/assets
      - ./data:/4allportal/data
    labels:
      traefik.enable: "true"
      traefik.http.services.4allportal.loadbalancer.server.port: 8181
      traefik.http.routers.4allportal.rule: Host(`localhost`)

  db:
    image: mariadb
    environment: 
      MYSQL_ROOT_PASSWORD: toor
    volumes:
      - ./db:/var/lib/mysql

  traefik:
    image: "traefik:v2.2"
    container_name: "traefik"
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

After that, create and own the assets and data folder for user 1000:1000:

mkdir assets data
chown 1000:1000 assets data

Then start the cluster with four members:

docker-compose up -d --scale 4allportal=4

To access the test cluster, open http://localhost in your browser. You can access træfik's dashboard via http://localhost:8080.

For a complete Docker configuration reference, take a look at the docker documentation.

# Production cluster with SSL

# Share database

For a production cluster, you need to run the database once in order to share it for all cluster members.

Sharing the database between cluster members can be achieved by using the following configuration for one cluster member. Replace toor with a secure password, replace STABLE with the latest stable version and fill in the GENERAL_EXTERNAL_URL variable:

version: "3"

services:
  4allportal:
    image: registry.4allportal.net/4allportal:STABLE
    ports:
      - "8181:8181"
    environment:
      GENERAL_EXTERNAL_URL:
    volumes:
      - ./assets:/4allportal/assets
      - ./data:/4allportal/data

  db:
    image: mariadb
    environment: 
      MYSQL_ROOT_PASSWORD: toor
    ports:
      - "3306:3306"
    volumes:
      - ./db:/var/lib/mysql

For all other members use the following configuration. Replace STABLE with the latest stable version and complete the empty variables in the environment section:

version: "3"

services:
  4allportal:
    image: registry.4allportal.net/4allportal:STABLE
    ports:
      - "8181:8181"
    environment:
      DATABASE_HOST:
      DATABASE_USER: root
      DATABASE_PASSWORD:
      GENERAL_EXTERNAL_URL:
    volumes:
      - ./assets:/4allportal/assets
      - ./data:/4allportal/data

# Share file system

Share the file system for the folders assets and data. Make sure to make it read- and writeable to user 1000:1000.

# Run reverse proxy

Finally, to provide SSL and routing for the members, run a reverse proxy on a machine. Configure it to point to the members IPs / hostnames on port 8181 and setup SSL.

Note: You can also do this in Docker, e.g. in one of the member's docker-compose.yaml file. Or even in all of them for redundancy.

# Using an external database

Of course, you can also run the database on a completely different host, just use the second production configuration for all members and replace the DATABASE_HOST, DATABASE_USER and DATABASE_PASSWORD variables with the database's access information.

Request missing documentation