Prepare recipe release #14

Merged
stevensting merged 19 commits from recipe-release into main 2026-07-08 10:12:54 +00:00
20 changed files with 516 additions and 307 deletions
+138 -109
View File
@@ -1,45 +1,13 @@
TYPE=bonfire
# choose what flavour of Bonfire to run
FLAVOUR=social
APP_VERSION=latest
LETS_ENCRYPT_ENV=production
# choose what extra services you want to run
COMPOSE_FILE="compose.yml:compose.meilisearch.yml"
# To use Sonic instead of Meilisearch as the search backend:
# COMPOSE_FILE="compose.yml:compose.sonic.yml"
# Enable `compose.mail.yml` to set secrets for sending emails (remember to also include your chosen search backend's compose file):
# COMPOSE_FILE="compose.yml:compose.mail.yml"
# Enable `compose.postgres.tune.yml` for Postgres tuning (can only be enabled *after* your instance already is deployed and working) (and remember to also include your chosen search backend and mailer's compose files)
# COMPOSE_FILE="compose.yml:compose.postgres.tune.yml"
APP_VERSION_FLAVOUR=${APP_VERSION}-${FLAVOUR}
# Different flavours/forks or architectures may require different builds of bonfire:
# for ARM (manual build):
# APP_DOCKER_IMAGE=bonfirenetworks/bonfire:${APP_VERSION_FLAVOUR}-aarch64
# for x86 (built by CI):
APP_DOCKER_IMAGE=bonfirenetworks/bonfire:${APP_VERSION_FLAVOUR}-amd64
# multi-arch image (built by CI, but currently not working):
#APP_DOCKER_IMAGE=bonfirenetworks/bonfire:${APP_VERSION_FLAVOUR}
DB_DOCKER_VERSION=17-3.5
# note that different flavours or architectures may require different postgres builds:
# For ARM or x86:
DB_DOCKER_IMAGE=ghcr.io/baosystems/postgis:${DB_DOCKER_VERSION}
# for x86:
# DB_DOCKER_IMAGE=postgis/postgis:${DB_DOCKER_VERSION}-alpine
# multiarch (but doesn't have required Postgis extension)
#DB_DOCKER_IMAGE=postgres:${DB_DOCKER_VERSION}-alpine
# TODO: maybe to use for Upgrading to a new Postgres version? (NOTE: does not work with postgis data)
# DB_DOCKER_IMAGE=pgautoupgrade/pgautoupgrade:16-alpine
## BASIC_AUTH
## Use 'echo $(htpasswd -nB username)' to generate the secret and store it in secret 'usersfile', multiple user/hashedpassword combinations can be added as comma separated list
#COMPOSE_FILE="$COMPOSE_FILE:compose.basicauth.yml"
#SECRET_USERSFILE_VERSION=v1
# choose what flavour of Bonfire to run. default: social
#APP_FLAVOUR=social
# uncomment to run specific version e.g. 1.0.4 or latest release branch. available: latest, latest-rc, latest-beta, latest-alpha
stevensting marked this conversation as resolved Outdated
Outdated
Review

also latest-rc

also latest-rc
Outdated
Review

and version without the v, eg: 1.0.4

and version without the v, eg: 1.0.4
#APP_VERSION=latest
# choose specific build. default: amd64, available: aarch64
#APP_PLATFORM=aarch64
# enter your instance's domain name
DOMAIN=bonfire.example.com
@@ -50,42 +18,72 @@ DOMAIN=bonfire.example.com
# enable abra backups
ENABLE_BACKUPS=true
COMPOSE_FILE="compose.yml"
# uncomment in order to NOT automatically change the database schema when you upgrade the app
# DISABLE_DB_AUTOMIGRATION=true
# ====================================
# DATABASE CONFIG
# max file upload size - default is 20 meg
UPLOAD_LIMIT=20000000
COMPOSE_FILE="$COMPOSE_FILE:compose.postgres.yml"
SECRET_POSTGRES_PASSWORD_VERSION=v1
# upper limit for how much RAM you want the DB to use, in megabytes (the same amount of swap will also be allocated to the DB container)
DB_MEMORY_LIMIT=5000
# upper limit for how much RAM you want the DB to use, in megabytes (the same amount of swap will also be allocated to the DB container) As a rule of thumb use 25% of system RAM.
DB_MEMORY_LIMIT=1024
#DB_MAX_CONNECTIONS=200
# set to true *after* your initial deployment to enable concurrent index creation for faster migrations in future upgrades
DB_MIGRATE_INDEXES_CONCURRENTLY=false
# how much info to include in app logs (from less to more: emergency, alert, critical, error, warning, notice, info, debug); default is warning — note that debug-level entries are removed from release builds entirely, so the most verbose usable level here is info
# PROD_LOG_LEVEL=warning
# for manual selection of DB version and docker image uncomment
#DB_DOCKER_VERSION=17-3.5
# note that different flavours or architectures may require different postgres builds:
# For ARM or x86:
#DB_DOCKER_IMAGE=ghcr.io/baosystems/postgis
# for x86:
#DB_DOCKER_IMAGE=postgis/postgis
#DB_DOCKER_VERSION=17-3.5-alpine
# uncomment in order to NOT automatically change the database schema when you upgrade the app
# DISABLE_DB_AUTOMIGRATION=true
# Enable `compose.postgres.tune.yml` for Postgres tuning (can only be enabled *after* your instance already is deployed and working)
# COMPOSE_FILE="$COMPOSE_FILE:postgres/compose.postgres.tune.yml"
# ====================================
# SECRETS
## BASIC_AUTH
stevensting marked this conversation as resolved Outdated
Outdated
Review

should this be uncommented by default, given they make skip giving sonic a PW, so could be one step in docs: uncomment these two lines and set a PW to enable search

should this be uncommented by default, given they make skip giving sonic a PW, so could be one step in docs: uncomment these two lines and set a PW to enable search
# please make sure you change everything to your own secrets!
# and do not check your env file into any public git repo
# change ALL the values:
## Use 'echo $(htpasswd -nB username)' to generate the secret and store it in secret 'usersfile', multiple user/hashedpassword combinations can be added as comma separated list
#COMPOSE_FILE="$COMPOSE_FILE:compose.basicauth.yml"
#SECRET_USERSFILE_VERSION=v1
# ====================================
# SEARCH BACKEND
# recommended search backend sonic
#COMPOSE_FILE="$COMPOSE_FILE:compose.sonic.yml"
# docker secret cannot be used due to distroless image, threfore add secret here
#SONIC_PASSWORD=
stevensting marked this conversation as resolved Outdated
Outdated
Review

is the reminder unnecessary since doing COMPOSE_FILE="$COMPOSE_FILE: ?

is the reminder unnecessary since doing ` COMPOSE_FILE="$COMPOSE_FILE:` ?
# alternative search service
#COMPOSE_FILE="$COMPOSE_FILE:compose.meilisearch.yml"
#SECRET_MEILI_MASTER_KEY_VERSION=v1
# ====================================
# MAIL
# COMPOSE_FILE="$COMPOSE_FILE:compose.mail.yml"
# SECRET_MAIL_KEY_VERSION=v1
# private key only necessary for some mail provider
# COMPOSE_FILE="$COMPOSE_FILE:compose.mail.privatekey.yml"
# SECRET_MAIL_PRIVATE_KEY_VERSION=v1
# what service to use for sending out emails (eg. smtp, mailgun, none) NOTE: you should also set the corresponding keys below for the relevant service you choose, and uncomment the COMPOSE_FILE line for the relevant service if needed
MAIL_BACKEND=none
#COMPOSE_FILE="$COMPOSE_FILE:compose.mail.yml"
#SECRET_MAIL_PASSWORD_VERSION=v1
#MAIL_BACKEND=none
mayel marked this conversation as resolved Outdated
Outdated
Review

seems like an invalid char here?

seems like an invalid char here?
# signup to an email service and edit with relevant info, see: https://docs.bonfirenetworks.org/Bonfire.Mailer.html
# MAIL_DOMAIN=mgo.example.com
# MAIL_KEY=xyz
# NOTE: please add `compose.mail.yml` to COMPOSE_FILE above and use the abra secret instead of env for secrets ^
# MAIL_FROM=admin@example.com
# MAIL_PROJECT_ID=
# MAIL_PRIVATE_KEY=
# MAIL_BASE_URI=
# MAIL_REGION=
# MAIL_SESSION_TOKEN=
@@ -98,94 +96,125 @@ MAIL_BACKEND=none
# MAIL_RETRIES=
# MAIL_ARGS=
# Store uploads in S3-compatible service:
# UPLOADS_S3_BUCKET=
# UPLOADS_S3_ACCESS_KEY_ID=
# UPLOADS_S3_SECRET_ACCESS_KEY=
# TODO: please use the abra secret instead of env for secrets ^
# UPLOADS_S3_REGION=fr-par
# UPLOADS_S3_HOST=s3.fr-par.scw.cloud
# UPLOADS_S3_SCHEME=https://
# UPLOADS_S3_URL=
# UPLOADS_S3_DEFAULT_URL=
# AWS_ROLE_ARN=
# AWS_WEB_IDENTITY_TOKEN_FILE=
# ====================================
# UPLOADS
# GHOST Integration
#GHOST_URL=https://example.ghost.io
#GHOST_CONTENT_API_KEY=
#GHOST_ADMIN_API_KEY=
#IFRAME_ALLOWED_ORIGINS=https://example.com
# max file upload size - default is 20 meg
UPLOAD_LIMIT=20000000
# Store uploads in S3-compatible service:
#COMPOSE_FILE="$COMPOSE_FILE:compose.s3.yml"
#SECRET_UPLOADS_S3_ACCESS_KEY_ID_VERSION=v1
#SECRET_UPLOADS_S3_SECRET_ACCESS_KEY_VERSION=v1
#UPLOADS_S3_BUCKET=
#UPLOADS_S3_REGION=fr-par
#UPLOADS_S3_HOST=s3.fr-par.scw.cloud
#UPLOADS_S3_SCHEME=https://
#UPLOADS_S3_URL=
#UPLOADS_S3_DEFAULT_URL=
#AWS_ROLE_ARN=
Outdated
Review

can uncomment by default?

can uncomment by default?
Outdated
Review

Is it necessary to uncomment by default? what for?

Is it necessary to uncomment by default? what for?
Outdated
Review

for the OAuth & OpenID provider (different from the clients that are in seperate compose files)

for the OAuth & OpenID provider (different from the clients that are in seperate compose files)
Outdated
Review

ok, but does every instance need this?

ok, but does every instance need this?
Outdated
Review

I guess we can instead do it in code from the domain, and leave it commented for people who want to override

I guess we can instead do it in code from the domain, and leave it commented for people who want to override
Outdated
Review

I guess I'm fine uncommenting it. I was just wondering if the oauth issuer is always active on every instance and this env var works as the switch to activate it.

I guess I'm fine uncommenting it. I was just wondering if the oauth issuer is always active on every instance and this env var works as the switch to activate it.
# Optionally use AWS identity token file
#COMPOSE_FILE="$COMPOSE_FILE:compose.s3.tokenfile.yml"
stevensting marked this conversation as resolved Outdated
Outdated
Review
url changed to https://yourinstance.tld/openid/client/openid_1
#SECRET_AWS_WEB_IDENTITY_TOKEN_VERSION=v1
# ====================================
# SSO
# Enable using Bonfire as an SSO provider for external apps to sign in with?
# ENABLE_SSO_PROVIDER=false
OAUTH_ISSUER=https://${DOMAIN}
#OAUTH_ISSUER=https://${DOMAIN}
# OpenID Connect: connect as a client to the OpenID Connect provider with callback url https://yourinstance.tld/oauth/client/openid_1
# OpenID Connect: connect as a client to the OpenID Connect provider with callback url https://yourinstance.tld/openid/client/openid_1
#COMPOSE_FILE="$COMPOSE_FILE:compose.auth.openid.yml"
stevensting marked this conversation as resolved Outdated
Outdated
Review
url changed to https://yourinstance.tld/openid/client/orcid
#SECRET_OPENID_CLIENT_SECRET_VERSION=v1
# OPENID_1_DISCOVERY=
# OPENID_1_DISPLAY_NAME=
# OPENID_1_CLIENT_ID=
# OPENID_1_CLIENT_SECRET=
# OPENID_1_SCOPE=
# OPENID_1_RESPONSE_TYPE=code
# OPENID_1_ENABLE_SIGNUP=false
# ^ can be code, token or id_token
# orcid.org SSO: connect as a client to the orcid.org OpenID Connect provider with callback url https://yourinstance.tld/oauth/client/orcid
# orcid.org SSO: connect as a client to the orcid.org OpenID Connect provider with callback url https://yourinstance.tld/openid/client/orcid
#COMPOSE_FILE="$COMPOSE_FILE:compose.auth.orcid.yml"
#SECRET_ORCID_CLIENT_SECRET_VERSION=v1
# ORCID_CLIENT_ID=
# ORCID_CLIENT_SECRET=
# OAuth2 provider: connect as a client to the OAuth2 provider with callback url https://yourinstance.tld/oauth/client/oauth_1
#COMPOSE_FILE="$COMPOSE_FILE:compose.auth.oauth.yml"
# SECRET_OAUTH_CLIENT_SECRET_VERSION=v1
# OAUTH_1_DISPLAY_NAME=
# OAUTH_1_CLIENT_ID=
stevensting marked this conversation as resolved Outdated
Outdated
Review

can add one more

# Zenodo SSO: connect as a client to the Zenodo OAuth2 provider with callback url https://yourinstance.tld/oauth/client/zenodo
# ZENODO_CLIENT_ID=
# ZENODO_CLIENT_SECRET=
# ZENODO_GRANT_TYPE=
# ZENODO_SCOPE=
# ZENODO_ENV=
can add one more ``` # Zenodo SSO: connect as a client to the Zenodo OAuth2 provider with callback url https://yourinstance.tld/oauth/client/zenodo # ZENODO_CLIENT_ID= # ZENODO_CLIENT_SECRET= # ZENODO_GRANT_TYPE= # ZENODO_SCOPE= # ZENODO_ENV=
# OAUTH_1_CLIENT_SECRET=
# OAUTH_1_AUTHORIZE_URI=
# OAUTH_1_ACCESS_TOKEN_URI=
# OAUTH_1_USER_INFO_URI=
# OAUTH_1_ENABLE_SIGNUP=false
# github.com SSO: connect as a client to the github.com OAuth2 provider with callback url https://yourinstance.tld/oauth/client/github
#COMPOSE_FILE="$COMPOSE_FILE:compose.auth.github.yml"
# SECRET_GITHUB_CLIENT_SECRET_VERSION=v1
stevensting marked this conversation as resolved Outdated
Outdated
Review

IFRAME_ALLOWED_ORIGINS is not specific to just ghost, but in general what websites you want to allow embeding a bonfire widget in iframe

IFRAME_ALLOWED_ORIGINS is not specific to just ghost, but in general what websites you want to allow embeding a bonfire widget in iframe
# GITHUB_APP_CLIENT_ID=
# GITHUB_CLIENT_SECRET=
# More Bonfire extensions configs:
# Zenodo SSO: connect as a client to the Zenodo OAuth2 provider with callback url https://yourinstance.tld/oauth/client/zenodo
# ZENODO_CLIENT_ID=
# ZENODO_CLIENT_SECRET=
# ZENODO_GRANT_TYPE=
# ZENODO_SCOPE=
# ZENODO_ENV=
# ====================================
# GHOST INTEGRATION
#COMPOSE_FILE="$COMPOSE_FILE:compose.ghost.yml"
#SECRET_GHOST_CONTENT_API_KEY_VERSION=v1
#SECRET_GHOST_ADMIN_API_KEY_VERSION=v1
#SECRET_GHOST_WEBHOOK_SECRET_VERSION=v1
#GHOST_URL=https://example.ghost.io
# ====================================
# OPEN TELEMETRY
#COMPOSE_FILE="$COMPOSE_FILE:compose.otel.yml"
#SECRET_HONEYCOMB_API_KEY_VERSION=v1
#SECRET_LIGHTSTEP_API_KEY_VERSION=v1
# ====================================
# BONFIRE EXTENSIONS AND MISC
#COMPOSE_FILE="$COMPOSE_FILE:compose.webpush.yml"
# SECRET_WEBPUSH_PRIVATE_KEY_VERSION=v1
# WEB_PUSH_SUBJECT=mailto:admin@example.com
# WEB_PUSH_PUBLIC_KEY=xyz
# WEB_PUSH_PRIVATE_KEY=abc
# GEOLOCATE_OPENCAGEDATA=
# GITHUB_TOKEN=xyz
# AKISMET_API_KEY=
WITH_LV_NATIVE=0
WITH_IMAGE_VIX=1
WITH_AI=0
LIVE_DASHBOARD_LOGGER=false
#COMPOSE_FILE="$COMPOSE_FILE:compose.github.yml"
#SECRET_GITHUB_TOKEN_VERSION=v1
#COMPOSE_FILE="$COMPOSE_FILE:compose.akismet.yml"
#SECRET_AKISMET_API_KEY_VERSION=v1
#COMPOSE_FILE="$COMPOSE_FILE:compose.mapbox.yml"
#SECRET_MAPBOX_API_KEY_VERSION=v1
# GEOLOCATE_OPENCAGEDATA=
#IFRAME_ALLOWED_ORIGINS=https://example.com
# how much info to include in app logs (from less to more: emergency, alert, critical, error, warning, notice, info, debug); default is warning — note that debug-level entries are removed from release builds entirely, so the most verbose usable level here is info
# PROD_LOG_LEVEL=warning
# how much info to include in logs (from less to more: emergency, alert, critical, error, warning, notice, info, debug)
LOG_LEVEL=info
# error reporting:
# SENTRY_DSN=
# ====================================
# these secrets will be autogenerated/managed by abra and docker"
SECRET_POSTGRES_PASSWORD_VERSION=v1
SECRET_MEILI_MASTER_KEY_VERSION=v1
SECRET_SONIC_PASSWORD_VERSION=v1
# SECRETS
# these secrets will be autogenerated/managed by abra and docker
SECRET_SEEDS_PW_VERSION=v1
SECRET_LIVEBOOK_PASSWORD_VERSION=v1
SECRET_MAIL_KEY_VERSION=v1
SECRET_SECRET_KEY_BASE_VERSION=v1 # length=128
SECRET_SIGNING_SALT_VERSION=v1 # length=128
SECRET_ENCRYPTION_SALT_VERSION=v1 # length=128
SECRET_RELEASE_COOKIE_VERSION=v1
# ====================================
# You should not have to edit any of the following ones:
APP_NAME=Bonfire
LANG=en_US.UTF-8
SEEDS_USER=root
ERLANG_COOKIE=bonfire_cookie
REPLACE_OS_VARS=true
LIVEVIEW_ENABLED=true
ACME_AGREE=true
SHOW_DEBUG_IN_DEV=true
LETS_ENCRYPT_ENV=production
HOSTNAME=$DOMAIN
#PLUG_SERVER=bandit
14
+1 -1
View File
@@ -1,4 +1,4 @@
export APP_ENTRYPOINT_VERSION=v3
export APP_ENTRYPOINT_VERSION=v4
export PG_BACKUP_VERSION=v6
export MEILI_BACKUP_VERSION=v4
export SONIC_CFG_VERSION=v1
+14
View File
@@ -0,0 +1,14 @@
version: "3.8"
services:
app:
environment:
- AKISMET_API_KEY_FILE=/run/secrets/akismet_api_key
secrets:
- akismet_api_key
secrets:
akismet_api_key:
external: true
name: ${STACK_NAME}_akismet_api_key_${SECRET_AKISMET_API_KEY_VERSION:-v1}
+14
View File
@@ -0,0 +1,14 @@
version: "3.8"
services:
app:
environment:
- GITHUB_APP_CLIENT_ID
- GITHUB_CLIENT_SECRET_FILE=/run/secrets/github_client_secret
secrets:
- github_client_secret
secrets:
oauth_client_secret:
external: true
name: ${STACK_NAME}_github_client_secret_${SECRET_GITHUB_CLIENT_SECRET_VERSION:-v1}
+19
View File
@@ -0,0 +1,19 @@
version: "3.8"
services:
app:
environment:
- OAUTH_1_DISPLAY_NAME
- OAUTH_1_CLIENT_ID
- OAUTH_1_CLIENT_SECRET_FILE=/run/secrets/oauth_client_secret
- OAUTH_1_AUTHORIZE_URI
- OAUTH_1_ACCESS_TOKEN_URI
- OAUTH_1_USER_INFO_URI
- OAUTH_1_ENABLE_SIGNUP
secrets:
- oauth_client_secret
secrets:
oauth_client_secret:
external: true
name: ${STACK_NAME}_oauth_client_secret_${SECRET_OAUTH_CLIENT_SECRET_VERSION:-v1}
+19
View File
@@ -0,0 +1,19 @@
version: "3.8"
services:
app:
environment:
- OPENID_1_DISPLAY_NAME
- OPENID_1_DISCOVERY
- OPENID_1_CLIENT_ID
- OPENID_1_CLIENT_SECRET_FILE=/run/secrets/openid_client_secret
- OPENID_1_SCOPE
- OPENID_1_RESPONSE_TYPE
- OPENID_1_ENABLE_SIGNUP
secrets:
- openid_client_secret
secrets:
openid_client_secret:
external: true
name: ${STACK_NAME}_openid_client_secret_${SECRET_OPENID_CLIENT_SECRET_VERSION:-v1}
+14
View File
@@ -0,0 +1,14 @@
version: "3.8"
services:
app:
environment:
- ORCID_CLIENT_ID
- ORCID_CLIENT_SECRET_FILE=/run/secrets/orchid_client_secret
secrets:
- orchid_client_secret
secrets:
orchid_client_secret:
external: true
name: ${STACK_NAME}_orchid_client_secret_${SECRET_ORCID_CLIENT_SECRET_VERSION:-v1}
+24
View File
@@ -0,0 +1,24 @@
version: "3.8"
services:
app:
environment:
- GHOST_URL
- GHOST_CONTENT_API_KEY_FILE=/run/secrets/ghost_content_api_key
- GHOST_ADMIN_API_KEY_FILE=/run/secrets/ghost_admin_api_key
- GHOST_WEBHOOK_SECRET_FILE=/run/secrets/ghost_webhook_secret
stevensting marked this conversation as resolved Outdated
Outdated
Review

this should be on main compose

this should be on main compose
secrets:
- ghost_content_api_key
- ghost_admin_api_key
- ghost_webhook_secret
stevensting marked this conversation as resolved
Review

need an extra secret: GHOST_WEBHOOK_SECRET

need an extra secret: GHOST_WEBHOOK_SECRET
secrets:
ghost_content_api_key:
external: true
name: ${STACK_NAME}_ghost_content_api_key_${SECRET_GHOST_CONTENT_API_KEY_VERSION:-v1}
ghost_admin_api_key:
external: true
name: ${STACK_NAME}_ghost_admin_api_key_${SECRET_GHOST_ADMIN_API_KEY_VERSION:-v1}
ghost_webhook_secret:
external: true
name: ${STACK_NAME}_ghost_webhook_secret_${SECRET_GHOST_WEBHOOK_SECRET_VERSION:-v1}
+14
View File
@@ -0,0 +1,14 @@
version: "3.8"
services:
app:
environment:
- GITHUB_TOKEN_FILE=/run/secrets/github_token
secrets:
- github_token
secrets:
github_token:
external: true
name: ${STACK_NAME}_github_token_${SECRET_GITHUB_TOKEN_VERSION:-v1}
+13
View File
@@ -0,0 +1,13 @@
version: "3.8"
services:
app:
environment:
- MAIL_PRIVATE_KEY_FILE=/run/secrets/mail_private_key
secrets:
- mail_private_key
secrets:
mail_private_key:
external: true
name: ${STACK_NAME}_mail_private_key_${SECRET_MAIL_PRIVATE_KEY_VERSION:-v1}
+16 -4
View File
@@ -2,14 +2,26 @@ version: "3.8"
services:
app:
environment:
- MAIL_BACKEND=${MAIL_BACKEND:-none}
- MAIL_DOMAIN
- MAIL_FROM
- MAIL_KEY_FILE=/run/secrets/mail_key
- MAIL_PROJECT_ID
- MAIL_BASE_URI
- MAIL_REGION
- MAIL_SERVER
- MAIL_USER
- MAIL_PORT
- MAIL_TLS
- MAIL_SSL
- MAIL_SMTP_AUTH
- MAIL_RETRIES
- MAIL_ARGS
secrets:
- mail_password
- mail_key
secrets:
mail_password:
external: true
name: ${STACK_NAME}_mail_password_${SECRET_MAIL_PASSWORD_VERSION:-v1}
mail_key:
external: true
name: ${STACK_NAME}_mail_key_${SECRET_MAIL_KEY_VERSION:-v1}
+14
View File
@@ -0,0 +1,14 @@
version: "3.8"
services:
app:
environment:
- MAPBOX_API_KEY_FILE=/run/secrets/mapbox_api_key
secrets:
- mapbox_api_key
secrets:
mapbox_api_key:
external: true
name: ${STACK_NAME}_mapbox_api_key_${SECRET_MAPBOX_API_KEY_VERSION:-v1}
+7
View File
@@ -7,6 +7,8 @@ services:
- search
environment:
- SEARCH_MEILI_INSTANCE=http://${STACK_NAME}_search:7700
secrets:
- meili_master_key
search:
image: getmeili/meilisearch:v1.14 # WIP: upgrade from v1.11 to 1.14
@@ -42,3 +44,8 @@ configs:
meili_backup:
name: ${STACK_NAME}_meili_backup_${MEILI_BACKUP_VERSION:-v4}
file: meili_backup.sh
secrets:
meili_master_key:
external: true
name: ${STACK_NAME}_meili_master_key_${SECRET_MEILI_MASTER_KEY_VERSION:-v1}
+21
View File
@@ -0,0 +1,21 @@
version: "3.8"
services:
app:
environment:
- OTEL_ENABLED
- OTEL_SERVICE_NAME
- OTEL_HONEYCOMB_API_KEY_FILE=/run/secrets/honeycomb_api_key
- OTEL_LIGHTSTEP_API_KEY_FILE=/run/secrets/lightstep_api_key
secrets:
- honeycomb_api_key
- lightstep_api_key
secrets:
honeycomb_api_key:
external: true
name: ${STACK_NAME}_honeycomb_api_key_${SECRET_HONEYCOMB_API_KEY_VERSION:-v1}
lightstep_api_key:
external: true
name: ${STACK_NAME}_lightstep_api_key_${SECRET_LIGHTSTEP_API_KEY_VERSION:-v1}
+93
View File
@@ -0,0 +1,93 @@
version: '3.8'
x-postgres-env: &postgres-env
mayel marked this conversation as resolved
Review

curious what this does?

curious what this does?
POSTGRES_DB: bonfire_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
services:
app:
environment:
<<: *postgres-env
mayel marked this conversation as resolved
Review

ah I see!

ah I see!
POSTGRES_HOST: ${STACK_NAME}_db
secrets:
- postgres_password
db:
image: ${DB_DOCKER_IMAGE:-ghcr.io/baosystems/postgis}:${DB_DOCKER_VERSION:-17-3.5}
# give Postgres time to shut down cleanly: the Swarm default (10s) force-kills it mid-shutdown on every redeploy, which wipes the cumulative stats (pg_stat_*) that autovacuum's triggers depend on — a root cause of autovacuum never running on big tables
stop_grace_period: 2m # NOTE: abra validates the schema before env interpolation, so this duration field can't be env-parameterized
# static tuning defaults for deployments NOT using the postgres tuner overlay (NOTE: `compose.postgres.tune.yml` computes these from your system resources instead of hardcoding them, so please use it!)
stevensting marked this conversation as resolved Outdated
Outdated
Review

maybe max_connections can be changed in ENV?

maybe max_connections can be changed in ENV?
# Notes:
Outdated
Review

should we put a default for DB_MEMORY_LIMIT as fallback?

should we put a default for DB_MEMORY_LIMIT as fallback?
Outdated
Review

also good to add PG_STORAGE_TYPE, DISK_STORAGE_TYPE and PG_RAM_PERCENT, and in general may be useful to rebase as quite a few changes were made (including default tuning on this compose for anyone not using the autotune one)

also good to add PG_STORAGE_TYPE, DISK_STORAGE_TYPE and PG_RAM_PERCENT, and in general may be useful to rebase as quite a few changes were made (including default tuning on this compose for anyone not using the autotune one)
# memory defaults are deliberately SAFE-SMALL (fit a 1 or 2GB VPS with the app co-hosted): shared_buffers is allocated at boot and maintenance_work_mem is per vacuum worker, so oversizing can prevent startup or OOM small machines — the tuner overlay right-sizes them instead (~25% / ~6% of the DB's RAM budget);
# max_connections is deliberately low because Bonfire's Ecto pool is the connection pooler (~25-50 conns; oversizing shrinks usable work_mem);
# jit off = measured per-query compile tax on Bonfire's many-join queries with no benefit;
# the autovacuum settings suit Bonfire's soft-delete/append workload where default thresholds never trigger on big tables.
command: >
postgres
-c max_connections=${PG_MAX_CONNECTIONS:-100}
-c shared_buffers=${PG_SHARED_BUFFERS_MB:-256}MB
-c effective_cache_size=${PG_EFFECTIVE_CACHE_SIZE_MB:-768}MB
-c work_mem=${PG_WORK_MEM_MB:-16}MB
Outdated
Review

maybe size can be changed in ENV?

maybe size can be changed in ENV?
-c maintenance_work_mem=${PG_MAINTENANCE_WORK_MEM_MB:-128}MB
-c random_page_cost=${PG_RANDOM_PAGE_COST:-1.1}
-c effective_io_concurrency=${PG_EFFECTIVE_IO_CONCURRENCY:-200}
stevensting marked this conversation as resolved Outdated
Outdated
Review

ditto

ditto
-c jit=${PG_JIT:-off}
-c wal_compression=${PG_WAL_COMPRESSION:-lz4}
-c default_toast_compression=${PG_TOAST_COMPRESSION:-lz4}
-c shared_preload_libraries=${PG_PRELOAD_LIBS:-pg_stat_statements}
-c pg_stat_statements.track=all
-c track_io_timing=on
-c track_activity_query_size=16384
-c autovacuum_vacuum_scale_factor=0.05
-c autovacuum_vacuum_insert_scale_factor=0.05
-c autovacuum_vacuum_cost_limit=1000
-c log_autovacuum_min_duration=0
-c log_min_duration_statement=${PG_LOG_MIN_DURATION_STATEMENT:-2000}
-c log_lock_waits=on
-c log_temp_files=0
# -c statement_timeout=1800000
#entrypoint: ['tail', '-f', '/dev/null'] # uncomment when the Postgres DB is corrupted and won't start
volumes:
- db-data:/var/lib/postgresql/data
- type: tmpfs
target: /dev/shm
tmpfs:
size: 1000000000
# about 1 GB in bytes
tmpfs:
- /tmp:size=${DB_MEMORY_LIMIT:-1024}M^
networks:
- internal
environment:
<<: *postgres-env
secrets:
- postgres_password
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"]
interval: 10s
timeout: 5s
retries: 5
deploy:
labels:
backupbot.backup: ${ENABLE_BACKUPS:-true}
backupbot.backup.pre-hook: "/pg_backup.sh backup"
backupbot.backup.volumes.db-data.path: "backup.sql"
backupbot.restore.post-hook: '/pg_backup.sh restore'
configs:
- source: pg_backup
target: /pg_backup.sh
mode: 0555
volumes:
db-data:
configs:
pg_backup:
name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION}
file: pg_backup.sh
secrets:
postgres_password:
external: true
name: ${STACK_NAME}_postgres_password_${SECRET_POSTGRES_PASSWORD_VERSION:-v1}
+14
View File
@@ -0,0 +1,14 @@
version: "3.8"
services:
app:
environment:
- AWS_WEB_IDENTITY_TOKEN_FILE=/run/secrets/aws_web_identity_token
secrets:
- aws_web_identity_token
secrets:
aws_web_identity_token:
external: true
name: ${STACK_NAME}_aws_web_identity_token_${SECRET_AWS_WEB_IDENTITY_TOKEN_VERSION:-v1}
+31
View File
@@ -0,0 +1,31 @@
version: "3.8"
services:
app:
environment:
- UPLOADS_S3_BUCKET
- UPLOADS_S3_ACCESS_KEY_ID_FILE=/run/secrets/uploads_s3_access_key_id
- UPLOADS_S3_SECRET_ACCESS_KEY_FILE=/run/secrets/uploads_s3_secret_access_key
- UPLOADS_S3_REGION
- UPLOADS_S3_HOST
- UPLOADS_S3_SCHEME
- UPLOADS_S3_URL
- UPLOADS_S3_DEFAULT_URL
- UPLOADS_S3_URL_EXPIRATION_TTL
- AWS_ROLE_ARN
stevensting marked this conversation as resolved
Review

the token file is optional though

the token file is optional though
secrets:
- mail_key
- uploads_s3_access_key_id
- uploads_s3_secret_access_key
secrets:
mail_key:
external: true
name: ${STACK_NAME}_mail_key_${SECRET_MAIL_KEY_VERSION:-v1}
uploads_s3_access_key_id:
external: true
name: ${STACK_NAME}_uploads_s3_access_key_id_${SECRET_UPLOADS_S3_ACCESS_KEY_ID_VERSION:-v1}
uploads_s3_secret_access_key:
external: true
name: ${STACK_NAME}_uploads_s3_secret_access_key_${SECRET_UPLOADS_S3_SECRET_ACCESS_KEY_VERSION:-v1}
+15
View File
@@ -0,0 +1,15 @@
version: "3.8"
services:
app:
environment:
- WEB_PUSH_SUBJECT
- WEB_PUSH_PUBLIC_KEY
- WEB_PUSH_PRIVATE_KEY_FILE=/run/secrets/webpush_private_key
secrets:
- webpush_private_key
secrets:
webpush_private_key:
external: true
name: ${STACK_NAME}_webpush_private_key_${SECRET_WEBPUSH_PRIVATE_KEY_VERSION:-v1}
+32 -176
View File
@@ -3,7 +3,7 @@ version: "3.8"
services:
app:
image: ${APP_DOCKER_IMAGE}
image: ${CONTAINER_REGISTRY:-bonfirenetworks/bonfire}:${APP_VERSION:-1.0.5}-${APP_FLAVOUR:-social}-${APP_PLATFORM:-amd64}
stevensting marked this conversation as resolved Outdated
Outdated
Review

I'd like to keep the bonfirenetworks/bonfire part in ENV too, so people can use a fork / custom flavour

I'd like to keep the `bonfirenetworks/bonfire` part in ENV too, so people can use a fork / custom flavour
logging:
driver: "json-file"
options:
@@ -12,28 +12,28 @@ services:
depends_on:
- db
environment:
- POSTGRES_HOST=${STACK_NAME}_db
- POSTGRES_USER=postgres
- POSTGRES_DB=bonfire_db
- PUBLIC_PORT=443
- MIX_ENV=prod
- HOSTNAME
- HOSTNAME=${DOMAIN}
- INSTANCE_DESCRIPTION
- DISABLE_DB_AUTOMIGRATION
- UPLOAD_LIMIT
- INVITE_KEY
- LANG
- SEEDS_USER
- ERLANG_COOKIE
- REPLACE_OS_VARS
- LIVEVIEW_ENABLED
- APP_NAME
- LANG=${LANG:-en_US.UTF-8}
- SEEDS_USER=${SEEDS_USER:-root}
- REPLACE_OS_VARS=${REPLACE_OS_VARS:-true}
stevensting marked this conversation as resolved
Review

can we change this to set RELEASE_COOKIE_FILE with a secret? and add RELEASE_DISTRIBUTION, RELEASE_NODE, RELEASE_MODE in env (these are for running multi-node deployments)

can we change this to set RELEASE_COOKIE_FILE with a secret? and add RELEASE_DISTRIBUTION, RELEASE_NODE, RELEASE_MODE in env (these are for running multi-node deployments)
- LIVEVIEW_ENABLED=${LIVEVIEW_ENABLED:-true}
- APP_NAME=${APP_NAME:-Bonfire}
- PLUG_SERVER
- WITH_LV_NATIVE
- WITH_IMAGE_VIX
- WITH_AI
- LIVE_DASHBOARD_LOGGER
- WITH_LV_NATIVE=${WITH_LV_NATIVE:-0}
- WITH_IMAGE_VIX=${WITH_IMAGE_VIX:-1}
- WITH_AI=${WITH_AI:-0}
- LIVE_DASHBOARD_LOGGER=${LIVE_DASHBOARD_LOGGER:-false}
- IFRAME_ALLOWED_ORIGINS
- RELEASE_DISTRIBUTION
- RELEASE_NODE
- RELEASE_MODE
- DB_SLOW_QUERY_MS
- DB_STATEMENT_TIMEOUT
@@ -42,92 +42,29 @@ services:
- DB_MIGRATE_INDEXES_CONCURRENTLY
- PROD_LOG_LEVEL
- MAIL_BACKEND
- MAIL_DOMAIN
- MAIL_FROM
- MAIL_KEY
- MAIL_PROJECT_ID
- MAIL_PRIVATE_KEY
- MAIL_BASE_URI
- MAIL_REGION
- MAIL_SERVER
- MAIL_USER
- MAIL_PASSWORD
- MAIL_PORT
- MAIL_TLS
- MAIL_SSL
- MAIL_SMTP_AUTH
- MAIL_RETRIES
- MAIL_ARGS
- SENTRY_DSN
stevensting marked this conversation as resolved Outdated
Outdated
Review

these four are secrets

these four are secrets
Outdated
Review

you mean all the api keys? so I would put OTEL_HONEYCOMB_API_KEY and OTEL_LIGHTSTEP_API_KEY in one yml, AKISMET_API_KEY in one and MAPBOX_API_KEY in another.

you mean all the api keys? so I would put OTEL_HONEYCOMB_API_KEY and OTEL_LIGHTSTEP_API_KEY in one yml, AKISMET_API_KEY in one and MAPBOX_API_KEY in another.
- OTEL_ENABLED
- OTEL_SERVICE_NAME
- OTEL_HONEYCOMB_API_KEY
- OTEL_LIGHTSTEP_API_KEY
- WEB_PUSH_SUBJECT
- WEB_PUSH_PUBLIC_KEY
- WEB_PUSH_PRIVATE_KEY
- AKISMET_API_KEY
- MAPBOX_API_KEY
- GEOLOCATE_OPENCAGEDATA
- GITHUB_TOKEN
- UPLOADS_S3_BUCKET
- UPLOADS_S3_ACCESS_KEY_ID
- UPLOADS_S3_SECRET_ACCESS_KEY
- UPLOADS_S3_REGION
- UPLOADS_S3_HOST
- UPLOADS_S3_SCHEME
- UPLOADS_S3_URL
- UPLOADS_S3_DEFAULT_URL
- UPLOADS_S3_URL_EXPIRATION_TTL
- AWS_ROLE_ARN
- AWS_WEB_IDENTITY_TOKEN_FILE
- ENABLE_SSO_PROVIDER
- OAUTH_ISSUER
- OPENID_1_DISPLAY_NAME
- OPENID_1_DISCOVERY
- OPENID_1_CLIENT_ID
- OPENID_1_CLIENT_SECRET
- OPENID_1_SCOPE
- OPENID_1_RESPONSE_TYPE
- OPENID_1_ENABLE_SIGNUP
- OAUTH_1_DISPLAY_NAME
- OAUTH_1_CLIENT_ID
- OAUTH_1_CLIENT_SECRET
- OAUTH_1_AUTHORIZE_URI
- OAUTH_1_ACCESS_TOKEN_URI
- OAUTH_1_USER_INFO_URI
- OAUTH_1_ENABLE_SIGNUP
- GITHUB_APP_CLIENT_ID
- GITHUB_CLIENT_SECRET
- SECRET_KEY_BASE_FILE=/run/secrets/secret_key_base
- SIGNING_SALT_FILE=/run/secrets/signing_salt
- ENCRYPTION_SALT_FILE=/run/secrets/encryption_salt
- SEEDS_PW_FILE=/run/secrets/seeds_pw
- LIVEBOOK_PASSWORD_FILE=/run/secrets/livebook_password
- RELEASE_COOKIE_FILE=/run/secrets/release_cookie
- ORCID_CLIENT_ID
- ORCID_CLIENT_SECRET
- GHOST_URL
- GHOST_CONTENT_API_KEY
- GHOST_ADMIN_API_KEY
- IFRAME_ALLOWED_ORIGINS
secrets:
- postgres_password
- secret_key_base
- signing_salt
- encryption_salt
- meili_master_key
- seeds_pw
- livebook_password
- release_cookie
volumes:
- upload-data:/opt/app/data/uploads
# - backup-data:/opt/app/data/backup
networks:
- proxy
- internal
@@ -144,95 +81,20 @@ services:
# and the db service's 2m stop_grace_period during redeploys
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-300}"
- "backupbot.backup=${ENABLE_BACKUPS:-true}"
#- backupbot.backup.volumes.upload-data: "true"
#- backupbot.backup.volumes.upload-data.path: "/opt/app/data/uploads"
- "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=4000"
- "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}"
#- "traefik.http.routers.${STACK_NAME}.middlewares=error-pages-middleware"
#- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
#- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect"
#- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true"
#- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}"
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost"]
# interval: 30s
# timeout: 10s
# retries: 10
# start_period: 1m
db:
image: ${DB_DOCKER_IMAGE}
# give Postgres time to shut down cleanly: the Swarm default (10s) force-kills it mid-shutdown on every redeploy, which wipes the cumulative stats (pg_stat_*) that autovacuum's triggers depend on — a root cause of autovacuum never running on big tables
stop_grace_period: 2m # NOTE: abra validates the schema before env interpolation, so this duration field can't be env-parameterized
environment:
# - POSTGRES_PASSWORD
- POSTGRES_USER=postgres
- POSTGRES_DB=bonfire_db
- POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
secrets:
- postgres_password
volumes:
- db-data:/var/lib/postgresql/data
- type: tmpfs
target: /dev/shm
tmpfs:
size: 1000000000
# about 1 GB in bytes ^
networks:
- internal
# shm_size: ${DB_MEMORY_LIMIT} # unsupported by docker swarm
tmpfs:
- /tmp:size=${DB_MEMORY_LIMIT}M
# static tuning defaults for deployments NOT using the postgres tuner overlay (NOTE: `compose.postgres.tune.yml` computes these from your system resources instead of hardcoding them, so please use it!)
# Notes:
# memory defaults are deliberately SAFE-SMALL (fit a 1 or 2GB VPS with the app co-hosted): shared_buffers is allocated at boot and maintenance_work_mem is per vacuum worker, so oversizing can prevent startup or OOM small machines — the tuner overlay right-sizes them instead (~25% / ~6% of the DB's RAM budget);
# max_connections is deliberately low because Bonfire's Ecto pool is the connection pooler (~25-50 conns; oversizing shrinks usable work_mem);
# jit off = measured per-query compile tax on Bonfire's many-join queries with no benefit;
# the autovacuum settings suit Bonfire's soft-delete/append workload where default thresholds never trigger on big tables.
command: >
postgres
-c max_connections=${PG_MAX_CONNECTIONS:-100}
-c shared_buffers=${PG_SHARED_BUFFERS_MB:-256}MB
-c effective_cache_size=${PG_EFFECTIVE_CACHE_SIZE_MB:-768}MB
-c work_mem=${PG_WORK_MEM_MB:-16}MB
-c maintenance_work_mem=${PG_MAINTENANCE_WORK_MEM_MB:-128}MB
-c random_page_cost=${PG_RANDOM_PAGE_COST:-1.1}
-c effective_io_concurrency=${PG_EFFECTIVE_IO_CONCURRENCY:-200}
-c jit=${PG_JIT:-off}
-c wal_compression=${PG_WAL_COMPRESSION:-lz4}
-c default_toast_compression=${PG_TOAST_COMPRESSION:-lz4}
-c shared_preload_libraries=${PG_PRELOAD_LIBS:-pg_stat_statements}
-c pg_stat_statements.track=all
-c track_io_timing=on
-c track_activity_query_size=16384
-c autovacuum_vacuum_scale_factor=0.05
-c autovacuum_vacuum_insert_scale_factor=0.05
-c autovacuum_vacuum_cost_limit=1000
-c log_autovacuum_min_duration=0
-c log_min_duration_statement=${PG_LOG_MIN_DURATION_STATEMENT:-2000}
-c log_lock_waits=on
-c log_temp_files=0
# -c statement_timeout=1800000
#entrypoint: ['tail', '-f', '/dev/null'] # uncomment when the Postgres DB is corrupted and won't start
deploy:
labels:
backupbot.backup: ${ENABLE_BACKUPS:-true}
# backupbot.backup.volumes.db-data: false
backupbot.backup.volumes.db-data.path: "backup.sql"
backupbot.backup.pre-hook: "/pg_backup.sh backup"
backupbot.restore.post-hook: '/pg_backup.sh restore'
configs:
- source: pg_backup
target: /pg_backup.sh
mode: 0555
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4000"]
interval: 30s
timeout: 10s
retries: 10
start_period: 15s
volumes:
db-data:
upload-data:
# backup-data:
networks:
proxy:
@@ -244,14 +106,8 @@ configs:
name: ${STACK_NAME}_app_entrypoint_${APP_ENTRYPOINT_VERSION:-v3}
file: entrypoint.sh.tmpl
template_driver: golang
pg_backup:
name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION:-v4}
file: pg_backup.sh
secrets:
postgres_password:
external: true
name: ${STACK_NAME}_postgres_password_${SECRET_POSTGRES_PASSWORD_VERSION:-v1}
secret_key_base:
external: true
name: ${STACK_NAME}_secret_key_base_${SECRET_SECRET_KEY_BASE_VERSION:-v1}
@@ -261,12 +117,12 @@ secrets:
encryption_salt:
external: true
name: ${STACK_NAME}_encryption_salt_${SECRET_ENCRYPTION_SALT_VERSION:-v1}
meili_master_key:
external: true
name: ${STACK_NAME}_meili_master_key_${SECRET_MEILI_MASTER_KEY_VERSION:-v1}
seeds_pw:
external: true
name: ${STACK_NAME}_seeds_pw_${SECRET_SEEDS_PW_VERSION:-v1}
livebook_password:
external: true
name: ${STACK_NAME}_livebook_password_${SECRET_LIVEBOOK_PASSWORD_VERSION:-v1}
release_cookie:
external: true
name: ${STACK_NAME}_release_cookie_${SECRET_RELEASE_COOKIE_VERSION:-v1}
+3 -17
View File
@@ -1,22 +1,8 @@
#!/bin/sh
# put secrets from files into env
export MEILI_MASTER_KEY=$(cat /run/secrets/meili_master_key)
export POSTGRES_PASSWORD=$(cat /run/secrets/postgres_password)
export SECRET_KEY_BASE=$(cat /run/secrets/secret_key_base)
export SIGNING_SALT=$(cat /run/secrets/signing_salt)
export ENCRYPTION_SALT=$(cat /run/secrets/encryption_salt)
export SEEDS_PW=$(cat /run/secrets/seeds_pw)
export LIVEBOOK_PASSWORD=$(cat /run/secrets/livebook_password)
# Only read the secret when the MAIL_PASSWORD was not set to remain backwards compatible
if [ -f /run/secrets/mail_password ] && [ -z "${MAIL_PASSWORD}" ]; then
export MAIL_PASSWORD=$(cat /run/secrets/mail_password)
fi
# Only read the secret when the MAIL_KEY was not set to remain backwards compatible
if [ -f /run/secrets/mail_key ] && [ -z "${MAIL_KEY}" ]; then
export MAIL_KEY=$(cat /run/secrets/mail_key)
# meilisearch does not support MEILI_MASTER_KEY_FILE, so we export it here for the search service
if [ -f /run/secrets/meili_master_key ]; then
export MEILI_MASTER_KEY=$(cat /run/secrets/meili_master_key)
fi
echo "....Secrets have been loaded, now run $@...."