Table of Contents
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 thedocker-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 indocker-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