diff --git a/.env.sample b/.env.sample index 8d62773..f6c5acc 100644 --- a/.env.sample +++ b/.env.sample @@ -6,3 +6,6 @@ DOMAIN=nodebb.example.com #EXTRA_DOMAINS=', `www.nodebb.example.com`' LETS_ENCRYPT_ENV=production + +SECRET_DB_PASSWORD_VERSION=v1 +SECRET_SECRET_VERSION=v1 diff --git a/README.md b/README.md index d992ac5..cc48eb5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # nodebb -> One line description of the recipe +> A better forum platform for the modern web. [nodebb.org](https://nodebb.org/) - +* **Maintainer**: [@p4u1](https://git.coopcloud.tech/p4u1) * **Category**: Apps * **Status**: 0 * **Image**: [`nodebb`](https://hub.docker.com/r/nodebb), 4, upstream diff --git a/abra.sh b/abra.sh index 13b5452..b2d5af6 100755 --- a/abra.sh +++ b/abra.sh @@ -1,2 +1,2 @@ -# Set any config versions here -# Docs: https://docs.coopcloud.tech/maintainers/handbook/#manage-configs +export CONFIG_JSON_VERSION=v2 +export PG_BACKUP_VERSION=v1 diff --git a/compose.yml b/compose.yml index b3d59e1..e3410e9 100644 --- a/compose.yml +++ b/compose.yml @@ -1,35 +1,87 @@ --- services: app: - image: nginx:1.27.5 + image: ghcr.io/nodebb/nodebb:latest + environment: + URL: "https://${DOMAIN}" + volumes: + - nodebb-build:/usr/src/app/build:rw + - nodebb-uploads:/usr/src/app/public/uploads:rw + - nodebb-nodemodules:/usr/src/app/node_modules:rw + - nodebb-config:/opt/config:rw + configs: + - source: config_json + target: /opt/config/config.json + secrets: + - db_password + - secret networks: - proxy + - internal deploy: restart_policy: condition: on-failure labels: - "traefik.enable=true" - - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80" + - "traefik.docker.network=proxy" + - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=4567" - "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})" - "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure" - "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}" - ## Redirect from EXTRA_DOMAINS to DOMAIN - #- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect" - ## Redirect HTTP to HTTPS - # - "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.scheme=https" - # - "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.permanent=true" - ## When you're ready for release, run "abra recipe sync " to set this - - "coop-cloud.${STACK_NAME}.version=" - ## Enable backups: https://docs.coopcloud.tech/maintainers/handbook/#how-do-i-configure-backuprestore - # - "backupbot.backup=true" - # - "backupbot.backup.path=/some/path" + - "coop-cloud.${STACK_NAME}.version=0.0.0-0.0.0" + + postgres: + image: postgres:17.6-alpine + environment: + POSTGRES_USER: nextcloud + POSTGRES_PASSWORD_FILE: /run/secrets/db_password + POSTGRES_DB: nextcloud + volumes: + - postgres-data:/var/lib/postgresql/data + networks: + - internal + secrets: + - db_password healthcheck: - test: ["CMD", "curl", "-f", "http://localhost"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 1m + test: ["CMD-SHELL", "pg_isready", "-U", "nodebb"] + interval: 10s + timeout: 5s + retries: 5 + deploy: + labels: + backupbot.backup.pre-hook: "/pg_backup.sh backup" + backupbot.backup.volumes.postgres.path: "backup.sql" + backupbot.restore.post-hook: '/pg_backup.sh restore' + configs: + - source: pg_backup + target: /pg_backup.sh + mode: 0555 + +volumes: + nodebb-build: + nodebb-uploads: + nodebb-config: + nodebb-nodemodules: + postgres-data: networks: + internal: proxy: external: true + +secrets: + db_password: + external: true + name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION} + secret: + external: true + name: ${STACK_NAME}_secret_${SECRET_SECRET_VERSION} + +configs: + config_json: + name: ${STACK_NAME}_config_json_${CONFIG_JSON_VERSION} + file: config.json.tmpl + template_driver: golang + pg_backup: + name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION} + file: pg_backup.sh diff --git a/config.json.tmpl b/config.json.tmpl new file mode 100644 index 0000000..09d808a --- /dev/null +++ b/config.json.tmpl @@ -0,0 +1,14 @@ +{ + "url": "http://{{ env "DOMAIN" }}", + "secret": "{{ secret "db_password" }}", + "database": "postgres", + "port": "4567", + "postgres": { + "host": "postgres", + "port": "5432", + "username": "nodebb", + "password": "{{ secret "db_password" }}", + "database": "nodebb", + "ssl": "false" + } +} diff --git a/pg_backup.sh b/pg_backup.sh new file mode 100644 index 0000000..e83074d --- /dev/null +++ b/pg_backup.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -e + +BACKUP_FILE='/var/lib/postgresql/data/backup.sql' + +function backup { + export PGPASSWORD=$(cat /run/secrets/db_password) + pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > $BACKUP_FILE +} + +function restore { + cd /var/lib/postgresql/data/ + restore_config(){ + # Restore allowed connections + cat pg_hba.conf.bak > pg_hba.conf + su postgres -c 'pg_ctl reload' + } + # Don't allow any other connections than local + cp pg_hba.conf pg_hba.conf.bak + echo "local all all trust" > pg_hba.conf + su postgres -c 'pg_ctl reload' + trap restore_config EXIT INT TERM + + # Recreate Database + psql -U ${POSTGRES_USER} -d postgres -c "DROP DATABASE ${POSTGRES_DB} WITH (FORCE);" + createdb -U ${POSTGRES_USER} ${POSTGRES_DB} + psql -U ${POSTGRES_USER} -d ${POSTGRES_DB} -1 -f $BACKUP_FILE + + trap - EXIT INT TERM + restore_config +} + +$@