From dee046461808c2d85a4e53b13a30da3ce7c4180c Mon Sep 17 00:00:00 2001 From: ecobytes Date: Fri, 10 May 2024 17:04:08 +0200 Subject: [PATCH] Feat: add legacy docker-compose example --- .gitignore | 5 +- README.md | 8 + compose/docker-compose.README.md | 135 +++++++++++++ compose/docker-compose.env.example | 13 ++ compose/docker-compose.env.pretalx.example | 40 ++++ compose/docker-compose.yml.example | 225 +++++++++++++++++++++ 6 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 compose/docker-compose.README.md create mode 100644 compose/docker-compose.env.example create mode 100644 compose/docker-compose.env.pretalx.example create mode 100644 compose/docker-compose.yml.example diff --git a/.gitignore b/.gitignore index be8e99c..cf3202f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ -.env +*.swp +.env* +.state pretalx.cfg +docker-compose.yml diff --git a/README.md b/README.md index 25e391b..b248753 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ This repository contains a Container image and a Docker Compose setup for a - [Management commands](#management-commands) - [Initialisation](#initialisation) - [Recycle](#recycle) +- [Legacy](#legacy) - [Authors](#authors) - [License](#license) - [Copyright](#copyright) @@ -314,6 +315,13 @@ docker compose down -v --remove-orphans rm .env ``` +## Legacy + +The repository contains an example configuration for supporting the legacy version of Docker Compose. +Due to the different feature set, an independent manifest is used. + +Please refer to [`compose/docker-compose.README.md`](./compose/docker-compose.README.md) to learn more. + ## Authors - Bastian Hodapp diff --git a/compose/docker-compose.README.md b/compose/docker-compose.README.md new file mode 100644 index 0000000..dd94af5 --- /dev/null +++ b/compose/docker-compose.README.md @@ -0,0 +1,135 @@ +# Legacy docker-compose support + +This example demonstrates a setup that is compatible with the legacy version of Docker Compose. + +It assumes: + +- availability of the image specified by `PRETALX_IMAGE` and `PRETALX_TAG` + +It contains changes that accommodate for a specific environment: + +- removes SELinux settings +- uses host-mounted volumes +- uses only a single Compose manifest to launch without multiple `-f` flags +- adds a separate `.env.pretalx` environment file, due to unsupported YAML interpolation syntax +- deactivates running the automatic migrations container and turns its function into a manual step, due to unsupported `service_completed_successfully` +- adapts the healthcheck interpolation syntax by escaping `$` escape signs + +Please use the example as a basis for your own modifications. + +## Preparation + +Run these commands from the root of the repository. + +Copy the example files in place: + +```sh +cp compose/docker-compose.yml.example docker-compose.yml +cp compose/docker-compose.env.example .env +cp compose/docker-compose.env.pretalx.example .env.pretalx +``` + +Remove the now redundant original configuration: + +```sh +rm compose.yml +``` + +Create the directories which will be used as host-mounted volumes. + +```sh +grep VOLUME .env | cut -d"=" -f2 | xargs -I% sh -c 'set -x; if [ ! -d "%" ]; then echo "Create: %"; mkdir -p "%"; else echo "Exists: %"; fi' +``` + +Apply the expected permissions: + +```sh +grep -e 'DATA' -e 'PUBLIC' .env | cut -d"=" -f2 | xargs -L1 chown 999:999 +``` + +Rootful Docker cannot perform subuid/-gid mapping. + +## Environment + +This legacy Docker Compose setup for running the Pretalx system brings two configuration files for adapting the environment. + +- `.env`, used for Docker Compose, the Traefik Reverse Proxy and the database credentials. +- `.env.pretalx`, used for all application-specific configuration options. Refer to the original documentation for details. + +### .env + +- Modify the `VOLUME`s as needed. +- Use a valid and available `IMAGE`/`TAG` combination. +- Set the `FQDN`. +- Specify the database credentials. + +### .env.pretalx + +- Adapt the `SITE_URL` to match the `FQDN` and the expected scheme. +- Set a preferred `LANGUAGE_CODE`. +- Choose the expected `TIME_ZONE`. +- Choose a `LOGGING_EMAIL`. +- Configure `MAIL` settings. + +## Build + +This setup is using a custom build with selected plugins, which are defined in the [`context/plugins/Dockerfile`](./context/plugins/Dockerfile). + +Prepare the application image: + +```sh +docker-compose build app +``` + +## First run + +Due to missing exit code evaluation of service dependencies, we need a more cautious approach to applying state to the containers. + +Begin with initialising the databases: + +```sh +docker-compose up -d postgres redis +``` + +Run the database migrations and implied build of static assets, if applicable: + +```sh +docker-compose run --rm migrations +``` + +This is needed, since missing static assets will lead to errors when starting the other application containers. + +You are now ready to start the rest of the whole application. + +## Run + +This will take a moment, due to the dependencies between containers and the latency of the healthchecks intervals. + +```sh +docker-compose up -d +``` + +Then prepare your initial user and the initial conference organiser: + +```sh +docker-compose exec app python -m pretalx init +``` + +You can now login at `$PRETALX_SITE_URL/orga/`. + +One useful initial step is to navitagte to `$PRETALX_SITE_URL/orga/me` after login and to provide a username, which was omitted during the `init` step. + +## Validate + +Validate your configuration on `$PRETALX_SITE_URL/orga/admin`. + +Try to invite other members to your organiser and send yourself a password reset email to test email deliverability. + +Otherwise use the Django built-in: + +```sh +docker-compose exec app python -m pretalx sendtestemail +``` + +Congratulations, you have setup a fully working Pretalx instance! + diff --git a/compose/docker-compose.env.example b/compose/docker-compose.env.example new file mode 100644 index 0000000..beb7a5d --- /dev/null +++ b/compose/docker-compose.env.example @@ -0,0 +1,13 @@ +PRETALX_VOLUME_DATA=./.state/data +PRETALX_VOLUME_PUBLIC=./.state/public +PRETALX_VOLUME_POSTGRES=./.state/postgres +PRETALX_VOLUME_REDIS=./.state/redis + +PRETALX_IMAGE=docker.io/pretalx/pretalx +PRETALX_TAG=latest + +FQDN=localhost.local + +POSTGRES_PASSWORD= +POSTGRES_USER=pretalx +POSTGRES_DB=pretalx diff --git a/compose/docker-compose.env.pretalx.example b/compose/docker-compose.env.pretalx.example new file mode 100644 index 0000000..3c9ebb0 --- /dev/null +++ b/compose/docker-compose.env.pretalx.example @@ -0,0 +1,40 @@ +PRETALX_LOG_LEVEL=info + +PRETALX_DEBUG=False +PRETALX_SITE_URL=https://fqdn + +PRETALX_LANGUAGE_CODE=en +PRETALX_TIME_ZONE=UTC + +PRETALX_DATA_DIR=/data +PRETALX_FILESYSTEM_LOGS=/data/logs + +PRETALX_FILESYSTEM_MEDIA=/public/media +PRETALX_FILESYSTEM_STATIC=/public/static + +PRETALX_SITE_CSP= +PRETALX_SITE_CSP_STYLE= +PRETALX_SITE_CSP_SCRIPT= +PRETALX_SITE_CSP_IMG= +PRETALX_SITE_CSP_FORM= + +PRETALX_LOGGING_EMAIL= +PRETALX_LOGGING_EMAIL_LEVEL=ERROR + +#PRETALX_MAIL_FROM=admin@localhost +#PRETALX_MAIL_HOST=localhost +#PRETALX_MAIL_PORT=25 +#PRETALX_MAIL_USER= +#PRETALX_MAIL_PASSWORD= +#PRETALX_MAIL_TLS=False +#PRETALX_MAIL_SSL=False + +PRETALX_DB_TYPE=postgresql +PRETALX_DB_HOST=postgres +PRETALX_DB_PORT=5432 + +PRETALX_REDIS=redis://redis/0 +PRETALX_REDIS_SESSIONS=true + +PRETALX_CELERY_BACKEND=redis://redis/1 +PRETALX_CELERY_BROKER=redis://redis/2 diff --git a/compose/docker-compose.yml.example b/compose/docker-compose.yml.example new file mode 100644 index 0000000..9f10f57 --- /dev/null +++ b/compose/docker-compose.yml.example @@ -0,0 +1,225 @@ +networks: + data: + web: + external: true + +services: + + web: + image: nginx:alpine + restart: unless-stopped + + deploy: + replicas: 1 + + healthcheck: + test: ['CMD-SHELL', 'ash -c "[[ $$(curl -s -o /dev/null -w \"%{http_code}\" http://localhost:80) == \"200\" ]]" || exit 1'] + start_period: 10s + interval: 30s + retries: 5 + timeout: 3s + + depends_on: + app: + condition: service_healthy + + networks: + - data + - web + volumes: + - ./config/nginx.conf:/etc/nginx/nginx.conf:ro + - ${PRETALX_VOLUME_PUBLIC}:/public + + labels: + traefik.enable: true + traefik.http.routers.fqdn-pretalx-web.entrypoints: web + traefik.http.routers.fqdn-pretalx-web.rule: Host(`${FQDN}`) + traefik.http.routers.fqdn-pretalx-web.middlewares: http-to-https + traefik.http.middlewares.http-to-https.redirectscheme.scheme: https + traefik.http.middlewares.http-to-https.redirectscheme.permanent: true + traefik.http.routers.fqdn-pretalx-webs.entrypoints: webs + traefik.http.routers.fqdn-pretalx-webs.rule: Host(`${FQDN}`) + traefik.http.routers.fqdn-pretalx-webs.tls: true + traefik.http.routers.fqdn-pretalx-webs.tls.certresolver: letsencrypt + + + app: +# image: ${PRETALX_IMAGE}:${PRETALX_TAG} + image: pretalx-${FQDN} + build: + context: ./context/plugins + args: + PRETALX_IMAGE: ${PRETALX_IMAGE} + PRETALX_TAG: ${PRETALX_TAG} + command: gunicorn + restart: unless-stopped + + deploy: + replicas: 1 + + healthcheck: + test: ['CMD-SHELL', 'bash -c "[[ $$(curl -s -o /dev/null -w \"%{http_code}\" http://localhost:8080) == \"200\" ]]" || exit 1'] + start_period: 10s + interval: 30s + retries: 5 + timeout: 3s + + depends_on: + redis: + condition: service_healthy + postgres: + condition: service_healthy + + networks: + - data + volumes: + - ${PRETALX_VOLUME_DATA}:/data + - ${PRETALX_VOLUME_PUBLIC}:/public + env_file: [".env.pretalx"] + environment: + PRETALX_LOG_LEVEL: ${PRETALX_LOG_LEVEL} + PRETALX_DB_NAME: ${POSTGRES_DB} + PRETALX_DB_USER: ${POSTGRES_USER} + PRETALX_DB_PASS: ${POSTGRES_PASSWORD} + + worker: +# image: ${PRETALX_IMAGE}:${PRETALX_TAG} + image: pretalx-${FQDN} + build: + context: ./context/plugins + args: + PRETALX_IMAGE: ${PRETALX_IMAGE} + PRETALX_TAG: ${PRETALX_TAG} + command: celery + restart: unless-stopped + + deploy: + replicas: 1 + + healthcheck: + test: ['CMD-SHELL', 'bash -c "[[ \"$$(pgrep celery)\" != \"\" ]]" || exit 1'] + start_period: 10s + interval: 30s + retries: 5 + timeout: 3s + + depends_on: + redis: + condition: service_healthy + postgres: + condition: service_healthy + + networks: + - data + volumes: + - ${PRETALX_VOLUME_DATA}:/data + - ${PRETALX_VOLUME_PUBLIC}:/public + env_file: [".env.pretalx"] + environment: + PRETALX_LOG_LEVEL: ${PRETALX_LOG_LEVEL} + PRETALX_DB_NAME: ${POSTGRES_DB} + PRETALX_DB_USER: ${POSTGRES_USER} + PRETALX_DB_PASS: ${POSTGRES_PASSWORD} + + cron: +# image: ${PRETALX_IMAGE}:${PRETALX_TAG} + image: pretalx-${FQDN} + build: + context: ./context/plugins + args: + PRETALX_IMAGE: ${PRETALX_IMAGE} + PRETALX_TAG: ${PRETALX_TAG} + command: cron + user: root + init: true + restart: unless-stopped + + healthcheck: + test: ['CMD-SHELL', 'bash -c "[[ \"$$(pgrep cron)\" != \"\" ]]" || exit 1'] + start_period: 10s + interval: 30s + retries: 5 + timeout: 3s + + depends_on: + redis: + condition: service_healthy + postgres: + condition: service_healthy + + networks: + - data + volumes: + - ${PRETALX_VOLUME_DATA}:/data + - ${PRETALX_VOLUME_PUBLIC}:/public + env_file: [".env.pretalx"] + environment: + PRETALX_DB_NAME: ${POSTGRES_DB} + PRETALX_DB_USER: ${POSTGRES_USER} + PRETALX_DB_PASS: ${POSTGRES_PASSWORD} + + migrations: +# image: ${PRETALX_IMAGE}:${PRETALX_TAG} + image: pretalx-${FQDN} + build: + context: ./context/plugins + args: + PRETALX_IMAGE: ${PRETALX_IMAGE} + PRETALX_TAG: ${PRETALX_TAG} + command: migrate + restart: "no" + + deploy: + replicas: 0 + + depends_on: + redis: + condition: service_healthy + postgres: + condition: service_healthy + + networks: + - data + volumes: + - ${PRETALX_VOLUME_DATA}:/data + - ${PRETALX_VOLUME_PUBLIC}:/public + env_file: [".env.pretalx"] + environment: + PRETALX_DB_NAME: ${POSTGRES_DB} + PRETALX_DB_USER: ${POSTGRES_USER} + PRETALX_DB_PASS: ${POSTGRES_PASSWORD} + + + postgres: + image: docker.io/library/postgres:15-alpine + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 5s + networks: + - data + volumes: + - ${PRETALX_VOLUME_POSTGRES}:/var/lib/postgresql/data + environment: + - POSTGRES_PASSWORD + - POSTGRES_USER + - POSTGRES_DB + + redis: + image: docker.io/library/redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 10s + interval: 30s + retries: 5 + timeout: 3s + networks: + - data + volumes: + - ${PRETALX_VOLUME_REDIS}:/data +