47 Installation
deon edited this page 2024-10-23 05:29:45 +00:00

Prerequisites

Clearing houz (clrghouz) is current configured to run on Linux systems under docker. The docker host only needs to have docker installed, and networking configured.

If you have a single IPv4 address, your docker host will receive connections (on appropriate web and FTN ports), and proxy those connections through to the docker containers that respond to those ports.

If you have IPv6, then the docker containers can be configured with a public IPv6 address and receive connections directly.

Installing Docker

It is recommended to install docker from docker directly (as often linux distribution implementations are often behind the current release). To do so, it can be achieved with a simple command:

curl -sSL https://get.docker.com | sudo sh

To test that installation was successful, run sudo docker info and you should see something similar to below:

Client: Docker Engine - Community
 Version:    24.0.6
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.11.2
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.21.0
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 4
  Running: 2
  Paused: 0
  Stopped: 2
...
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

Running docker as a user

Normally docker commands can only be run as the root user. However, to run docker commands with your (non-root) user id - add your user to the docker group.

sudo usermod -aG docker [your_user_id]

will do it. You'll need to log off and log on again for it to be effective.

You can confirm with id

> id fred
uid=500(fred) gid=500(admin) groups=500(admin),10(wheel),27(sudo),498(docker)

(In the above example, you can see fred is a member of GID: 498 docker.)

Storage directory

You will want all your data to persist between container restarts. Create a directory to store all the container data - something like /srv/docker (or something you prefer). The top level directories can be owned as root (/srv/docker) with access 755.

Storage space

Make sure your docker container directory (/srv/docker/clrghouz) and /var/lib/docker has sufficient space.

If your linux doesnt use mount points, and all your space is mounted under /, then you should be OK. But if you do have mount points, then you'll need to have lots of space reserved for those directories.

Create a directory for Clearing houz

In your storage directory (/srv/docker/clrghouz) create a directory to store Clearing houz files (eg:/srv/docker/clrghouz). Everything from here on will assume you are working from this directory.

The clrghouz dir can be owned with your user id, so that you can get into that dir as your normal logged in user.

EG:

> ls -al /srv/docker/clrghouz
drwxr-xr-x 11 fred admin 4096 May 26 13:59 /srv/docker/clrghouz

docker compose

To make restarting containers easier, here is a docker compose file that you can use - this will go in your Clearing houz directory.

You can name it anything you like, and typically they have an extension of .yml or .yaml. (If you name it docker-compose.yml it'll be found automatically when you run start the container with docker compose up.)

Make adjustments as appropriate.

services:
  web:
    image: ${IMAGE:-gitea.dege.au/bbs/clrghouz}
    #cap_add:
    #- SYS_ADMIN
    #- NET_ADMIN
    #- NET_RAW
    depends_on:
    - postgres
    deploy:
      resources:
        limits:
          memory: 256M
    #devices:
    #- /dev/net/tun
    environment:
      APP_KEY: ${APP_KEY}
      APP_TIMEZONE: ${APP_TIMEZONE:-Australia/Melbourne}
      APP_URL: https://${WEB_HOSTNAME}/
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_ENDPOINT: ${AWS_ENDPOINT:-http://minio:9000/}
      AWS_BUCKET: ${AWS_BUCKET:-clrghouz}
      DB_DATABASE: ${DB_DATABASE:-clrghouz}
      DB_USERNAME: ${DB_USERNAME:-clrghouz}
      DB_PASSWORD: ${DB_PASSWORD}
      FIDO_DNS_NS: ${FIDO_DNS_NS}
      FIDO_HAPROXY: ${FIDO_HAPROXY:-"FALSE"}
      FIDO_PACKET_KEEP: ${FIDO_PACKET_KEEP:-"TRUE"}
      LOG_LEVEL: ${LOG_LEVEL:-info}
      MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS}
      MAIL_FROM_NAME: ${MAIL_FROM_NAME}
      MEMCACHED_START: ${MEMCACHED_START:-"FALSE"}
      #ZEROTIER_START: "TRUE"
    networks:
      default:
      public:
        ipv6_address: ${IP6_PREFIX}:${IP6_SUFFIX}:2
        aliases:
          - clrghouz
    hostname: ${WEB_HOSTNAME}
    ports:
    - 53:53/udp
    #- 80:80
    #- 24554:24554
    #- 60179:60179
    sysctls:
    - "net.ipv6.conf.all.disable_ipv6=0"
    volumes:
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/cache:/var/www/html/storage/framework/cache/data
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/sessions:/var/www/html/storage/framework/sessions
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/logs:/var/www/html/storage/logs
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/data:/var/www/html/data
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/fido:/var/www/html/storage/app/fido
    #- ${VOL_PREFIX:-/srv/docker/clrghouz}/zerotier:/var/lib/zerotier-one

  queue:
    image: ${IMAGE:-gitea.dege.au/bbs/clrghouz}
    #cap_add:
    #- SYS_ADMIN
    #- NET_ADMIN
    depends_on:
    - postgres
    deploy:
      replicas: 1
      resources:
        limits:
          memory: 256M
    #devices:
    #- /dev/net/tun
    environment:
      APP_KEY: ${APP_KEY}
      APP_TIMEZONE: ${APP_TIMEZONE:-Australia/Melbourne}
      APP_URL: https://${WEB_HOSTNAME}/
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_ENDPOINT: ${AWS_ENDPOINT:-http://minio:9000/}
      AWS_BUCKET: ${AWS_BUCKET:-clrghouz}
      CONTAINER_ROLE: queue
      DB_DATABASE: ${DB_DATABASE:-clrghouz}
      DB_USERNAME: ${DB_USERNAME:-clrghouz}
      DB_PASSWORD: ${DB_PASSWORD}
      FIDO_PACKET_KEEP: ${FIDO_PACKET_KEEP:-"TRUE"}
      LOG_LEVEL: ${LOG_LEVEL:-info}
      MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS}
      MAIL_FROM_NAME: ${MAIL_FROM_NAME}
      WORK_QUEUES: default,poll,mail,tic
      WORK_TIMEOUT: 900
      #ZEROTIER_START: "TRUE"
    networks:
      default:
      public:
        ipv6_address: ${IP6_PREFIX}:${IP6_SUFFIX}:3
    sysctls:
    - "net.ipv6.conf.all.disable_ipv6=0"
    volumes:
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/logs:/var/www/html/storage/logs
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/fido:/var/www/html/storage/app/fido
    #- ${VOL_PREFIX:-/srv/docker/clrghouz}/zerotier.queue:/var/lib/zerotier-one

  schedule:
    image: ${IMAGE:-gitea.dege.au/bbs/clrghouz}
    deploy:
      resources:
        limits:
          memory: 128M
    depends_on:
    - postgres
    environment:
      APP_KEY: ${APP_KEY}
      APP_TIMEZONE: ${APP_TIMEZONE:-Australia/Melbourne}
      CONTAINER_ROLE: scheduler
      DB_DATABASE: ${DB_DATABASE:-clrghouz}
      DB_USERNAME: ${DB_USERNAME:-clrghouz}
      DB_PASSWORD: ${DB_PASSWORD}
      LOG_LEVEL: ${LOG_LEVEL:-info}
    volumes:
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/app/logs:/var/www/html/storage/logs

  memcached:
    image: memcached:alpine
    command: -e /memcached/memory_file
    deploy:
      resources:
        limits:
          memory: 128M
    stop_signal: SIGUSR1
    volumes:
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/memcached:/memcached

  postgres:
    image: postgres:15-alpine
    deploy:
      resources:
        limits:
          memory: 512M
    environment:
      POSTGRES_DB: ${DB_DATABASE:-clrghouz}
      POSTGRES_USER: ${DB_USERNAME:-clrghouz}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    #labels:
    #  cron.container.daily: "root#pg_dumpall -U clrghouz#S3_BUCKET=restic.docker restic -q --no-cache backup --stdin --stdin-filename docker-clrghouz-database"
    #  backup.stack.daily: "${VOL_PREFIX:-/srv/docker/clrghouz}"
    shm_size: 1g
    volumes:
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/postgres:/var/lib/postgresql/data

  minio:
    image: minio/minio
    command: ["server", "--console-address", ":9001", "/data"]
    deploy:
      resources:
        limits:
          memory: 256M
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
    healthcheck:
      test: [ "CMD", "curl", "--fail", "http://localhost:9000/minio/health/live" ]
      interval: 60s
      timeout: 10s
      retries: 3
    networks:
      default:
    ports:
    - 9001:9001 # Console
    volumes:
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/minio:/data

  haproxy:
    image: haproxy:alpine
    command: -f /usr/local/etc/haproxy/config
    deploy:
      resources:
        limits:
          memory: 128M
    hostname: ${FIDO_DNS_NS}
    networks:
      default:
      public:
        ipv6_address: ${IP6_PREFIX}:${IP6_SUFFIX}:f
    ports:
    - "24553:24553"
    - "24554:24554"
    - "60179:60179"
    # "53:53/udp"
    - "80:80"
    - "443:443"
    ulimits:
      nofile:
        soft: 1024
        hard: 1024
    volumes:
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/haproxy:/usr/local/etc/haproxy/config
    - ${VOL_PREFIX:-/srv/docker/clrghouz}/nginx/ssl/:/usr/local/etc/haproxy/ssl

networks:
  public:
    enable_ipv6: true
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "true"
    ipam:
      driver: default
      config:
      - subnet: ${IP6_PREFIX}:${IP6_SUFFIX}::/112
        gateway: ${IP6_PREFIX}:${IP6_SUFFIX}:1

Also make an .env file, that is placed in your clrghouz directory (/srv/docker/clrghouz), make any adjustments as appropriate.

# Clrghouz Details
#IMAGE=gitea.dege.au/bbs/clrghouz
IP6_PREFIX=[IP6_PREFIX]
IP6_SUFFIX=0d0c:0100:f1d0
#VOL_PREFIX=/srv/docker/clrghouz

APP_KEY=[APP_KEY]
#APP_TIMEZONE=Australia/Melbourne
#LOG_LEVEL=info
WEB_HOSTNAME=clrghouz.example.com

# Where files are stored
AWS_ACCESS_KEY_ID=[MINIO_ACCESS_KEY]
AWS_SECRET_ACCESS_KEY=[MINIO_SECRET_KEY]
#AWS_ENDPOINT=http://minio:9000/
#AWS_BUCKET=clrghouz

# Database configuration
#DB_DATABASE=clrghouz
#DB_USERNAME=clrghouz
DB_PASSWORD=[DB_PASSWORD]

# Fido Details
FIDO_DNS_NS=haproxy.example.com
#FIDO_HAPROXY="FALSE"
#FIDO_PACKET_KEEP="TRUE"

# Email Details
MAIL_FROM_ADDRESS="[YOUR EMAIL]"
MAIL_FROM_NAME="[YOUR NAME]"

# Minio
MINIO_ROOT_USER=clrghouz
MINIO_ROOT_PASSWORD=[MINIO_PASSWORD]

# Other Items
#MEMCACHED_START="FALSE"

NOTES:

  • Items commented out in the .env file are defaults, that will be used in the docker-compose.yml file automatically
  • This docker compose file should be called docker-compose.yml for it to be found automatically.
  • Items surrounded in [] brackets need to be changed (including removing the [])
  • Values that have a space in them, need to be surrounded in ", eg: MAIL_FROM_NAME="Bart Simpson"
  • You'll defined the [APP_KEY] below
  • Update the [IPv6_PREFIX] as appropriate for your setup. This assumes you have your IPv6 setup, and you have configured your router to route this prefix to this host running clrghouz. The example I use here [IPv6_PREFIX]:0d0c:100:f1d0::/112 is because my docker hosts run many applications, and I want each application to have its own segment. So I route [IPv6_PREFIX]:0d0c:0100::/88 to the docker host, which ultimately provides me with lots of /112 networks, with each network having more than enough addresses I can use.
  • Create a suitable [DB_PASSWORD] and update your docker-compose file.
  • We'll define [MINIO_ACCESS_KEY] and [MINIO_SECRET_KEY] later - and you'll update your docker-compose file with those details.
  • If you dont want to use haproxy, then you can comment/delete out this section in the docker-compose file. You'll also need to uncomment the post definitions in the web: section.
  • If you dont want to use nginx, or already have nginx as a front end to your web hosts elsewhere, then you can comment/delete it from your docker-compose file. (You'll configure your existing nginx to terminate SSL and/or proxy to the web: container on port 80.)

Make necessary directories

> mkdir app app/cache app/data app/fido app/logs app/sessions haproxy memcached minio postgres nginx
> sudo chown -R 82:82 app/
> sudo chown 11211:11211 memcached

Create the app encryption key

> docker run --rm -e CONTAINER_ROLE=none -e APP_TIMEZONE=UTC gitea.dege.au/bbs/clrghouz ./artisan key:generate --show

* Starting NGINX...
? NO container role "none", AND/OR no laravel install, just starting php-fpm
base64:iT+8vM9p0X8oupGPKF+/ZqAxqyIQY5dWd72TaAlfcdY= <--- WHAT IS HERE IS YOUR KEY

And update the docker-compose file and replace [APP_KEY] with this key.

Create a start/stop script (optional, but helpful)

Create a script "up" to fresh the container images (if they have been updated) and start clrghouz.

#!/bin/sh

docker compose pull
docker compose up --no-start
docker compose start

If you want a corresponding "down" script,

#!/bin/sh

docker compose down

Ultimately you can name these whatever you like, I name mine up.sh and down.sh respectively. (Dont forget to make them executable with chmod +x up.sh down.sh.

Start clrghouz

Using your new script, you can start clrghouz (you dont need to do this as root, if your user id is a member of the docker group - which was an earlier step).

(Or if you didnt make a script docker compose up will do it.)

> ./up.sh
[+] Pulling 7/7
 ✔ queue Skipped - Image is already being pulled by web
 ✔ schedule Skipped - Image is already being pulled by web
 ✔ postgres Pulled
 ✔ haproxy Pulled
 ✔ web Pulled
 ✔ memcached Pulled
 ✔ minio Pulled
[+] Creating 9/9
 ✔ Network clrghouz_default        Created
 ✔ Network clrghouz_public         Created
 ✔ Container clrghouz-haproxy-1    Created
 ✔ Container clrghouz-memcached-1  Created
 ✔ Container clrghouz-postgres-1   Created
 ✔ Container clrghouz-minio-1      Created
 ✔ Container clrghouz-schedule-1   Created
 ✔ Container clrghouz-web-1        Created
 ✔ Container clrghouz-queue-1      Created
[+] Running 7/7
 ✔ Container clrghouz-haproxy-1    Started
 ✔ Container clrghouz-memcached-1  Started
 ✔ Container clrghouz-postgres-1   Started
 ✔ Container clrghouz-minio-1      Started
 ✔ Container clrghouz-queue-1      Started
 ✔ Container clrghouz-schedule-1   Started
 ✔ Container clrghouz-web-1        Started

And finally make sure everything is running OK

> docker ps
CONTAINER ID   IMAGE                        COMMAND                  CREATED         STATUS                   PORTS                                                 NAMES
2da87a2e37ea   gitea.dege.au/bbs/clrghouz   "/sbin/init php-fpm"     4 minutes ago   Up 4 minutes             80/tcp, 9000/tcp                                      clrghouz-schedule-1
7a63ce1ba0b6   gitea.dege.au/bbs/clrghouz   "/sbin/init php-fpm"     4 minutes ago   Up 4 minutes             80/tcp, 0.0.0.0:53->53/udp, :::53->53/udp, 9000/tcp   clrghouz-web-1
8b2215a8b374   gitea.dege.au/bbs/clrghouz   "/sbin/init php-fpm"     4 minutes ago   Up 4 minutes             80/tcp, 9000/tcp                                      clrghouz-queue-1
0db2f7b8adba   tobi312/minio                "/usr/bin/docker-ent…"   4 minutes ago   Up 4 minutes (healthy)   9000/tcp, 0.0.0.0:9001->9001/tcp, :::9001->9001/tcp   clrghouz-minio-1
a29cf9497ca0   postgres:15-alpine           "docker-entrypoint.s…"   4 minutes ago   Up 4 minutes             5432/tcp                                              clrghouz-postgres-1
009ff7e52ddc   memcached:alpine             "docker-entrypoint.s_"   4 minutes ago   Up 4 minutes             11211/tcp                                            clrghouz-memcached-1

NOTE: The haproxy container wont be running, as we need to give it some config files below.

Final Setup

Some final steps that we need to do.

  • Initialise the database with docker exec -it clrghouz-web-1 ./artisan migrate --force, you should see a bunch of
   INFO  Preparing database.

  Creating migration table .............................................................................. 36.91ms DONE

   INFO  Running migrations.

  2014_10_12_000000_create_users_table .................................................................. 31.18ms DONE
  2014_10_12_100000_create_password_resets_table ........................................................ 17.76ms DONE
  2021_06_18_133000_update_users ......................................................................... 8.55ms DONE
...
  • Seed the DB with some defaults
> docker exec -it clrghouz-web-1 ./artisan db:seed InitialSetup --force
  • Configure minio, see Minio Configuration
  • Configure haproxy if you are using it, see see Haproxy Configuration
  • Restart all the containers with docker compose restart (you should have 7 runnning: web, queue, schedular, postgres, haproxy, minio and memcached
  • Update your DNS servers, make sure your WEB_HOSTNAME (in .env) resolves to the docker hosts IPv4 address and the haproxy's container IPv6 address (as defined in docker-compose.yml)

Now you are ready

You should be able to get to the clrghouz home page http://[WEB_HOSTNAME]. Initial login details are admin@clrghouz/password