From 63c4ea7fdd97c971eebae0ef385841944c2acc26 Mon Sep 17 00:00:00 2001 From: YuryHrytsuk Date: Wed, 18 Jun 2025 11:08:50 +0200 Subject: [PATCH 1/6] Update postgres exporter Make sure we use recent version that has export all fields used by existing community grafana Postgres dashboards Related Issue(s): * https://github.com/ITISFoundation/osparc-ops-environments/issues/1080 --- services/monitoring/docker-compose.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/monitoring/docker-compose.yml.j2 b/services/monitoring/docker-compose.yml.j2 index 09e4b814..1fad5a89 100644 --- a/services/monitoring/docker-compose.yml.j2 +++ b/services/monitoring/docker-compose.yml.j2 @@ -326,7 +326,7 @@ services: memory: 64M cpus: "0.1" postgres-exporter: - image: bitnami/postgres-exporter:0.15.0 + image: bitnami/postgres-exporter:0.17.1 networks: - monitored environment: From 4a79721fb448627a6873ff8811582080ebf60abc Mon Sep 17 00:00:00 2001 From: YuryHrytsuk Date: Wed, 25 Jun 2025 08:07:06 +0200 Subject: [PATCH 2/6] Add metabase stack Related Issue(s): * https://github.com/ITISFoundation/osparc-ops-environments/issues/1061 --- .gitignore | 2 +- scripts/common-services.Makefile | 3 ++ services/metabase/Makefile | 10 +++++ services/metabase/docker-compose.yml | 59 ++++++++++++++++++++++++++++ services/metabase/template.env | 8 ++++ 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 scripts/common-services.Makefile create mode 100644 services/metabase/Makefile create mode 100644 services/metabase/docker-compose.yml create mode 100644 services/metabase/template.env diff --git a/.gitignore b/.gitignore index f8be6f3f..9c16e8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -142,7 +142,7 @@ yq **/.env-devel **/.stack.*.yml **/.stack.*.yaml -docker-compose.yml + stack.yml stack_with_prefix.yml docker-compose.simcore.yml diff --git a/scripts/common-services.Makefile b/scripts/common-services.Makefile new file mode 100644 index 00000000..cbd30273 --- /dev/null +++ b/scripts/common-services.Makefile @@ -0,0 +1,3 @@ +STACK_NAME = $(notdir $(shell pwd)) +TEMP_COMPOSE=.stack.${STACK_NAME}.yaml +REPO_BASE_DIR := $(shell git rev-parse --show-toplevel) diff --git a/services/metabase/Makefile b/services/metabase/Makefile new file mode 100644 index 00000000..de94029f --- /dev/null +++ b/services/metabase/Makefile @@ -0,0 +1,10 @@ +REPO_BASE_DIR := $(shell git rev-parse --show-toplevel) + +include ${REPO_BASE_DIR}/scripts/common.Makefile +include ${REPO_BASE_DIR}/scripts/common-services.Makefile + +.PHONY: up +up: ${TEMP_COMPOSE} ## Deploys metabase stack + +${TEMP_COMPOSE}: docker-compose.yml .env + @${REPO_BASE_DIR}/scripts/docker-stack-config.bash -e .env $< > $@ diff --git a/services/metabase/docker-compose.yml b/services/metabase/docker-compose.yml new file mode 100644 index 00000000..bbf58471 --- /dev/null +++ b/services/metabase/docker-compose.yml @@ -0,0 +1,59 @@ +# https://www.metabase.com/docs/v0.54/installation-and-operation/running-metabase-on-docker + +# https://www.metabase.com/docs/v0.54/installation-and-operation/running-metabase-on-docker#example-docker-compose-yaml-file +services: + metabase: + image: metabase/metabase:v0.54.13.3 + networks: + - public + - monitored + environment: + # https://www.metabase.com/docs/v0.54/installation-and-operation/configuring-application-database + - MB_DB_TYPE=postgres + - MB_DB_DBNAME=metabase + - MB_DB_HOST=${POSTGRES_HOST} + - MB_DB_PORT=${POSTGRES_PORT} + - MB_DB_USER=${POSTGRES_USER} + - MB_DB_PASS=${POSTGRES_PASSWORD} + # https://www.metabase.com/docs/v0.54/installation-and-operation/running-metabase-on-docker#setting-the-java-timezone + - JAVA_TIMEZONE=UTC + deploy: + update_config: + parallelism: 1 + order: start-first + failure_action: rollback + delay: 30s + placement: + constraints: + - node.labels.ops==true + labels: + - traefik.enable=true + - traefik.docker.network=${PUBLIC_NETWORK} + # router + - traefik.http.routers.metabase.rule=Host(`${ADMIN_DOMAIN}`) && PathPrefix(`/metabase`) + - traefik.http.routers.metabase.entrypoints=https + - traefik.http.routers.metabase.tls=true + - traefik.http.middlewares.metabase_stripprefixregex.stripprefixregex.regex=^/metabase + - traefik.http.routers.metabase.middlewares=ops_whitelist_ips@swarm, ops_gzip@swarm, ops_auth@swarm, metabase_stripprefixregex + # service + - traefik.http.services.metabase.loadbalancer.server.port=3000 + # resources: + # limits: + # memory: 512M + # cpus: "1.0" + # reservations: + # memory: 128M + # cpus: "0.2" + healthcheck: + test: curl --fail -I http://localhost:3000/api/health || exit 1 + interval: 15s + timeout: 5s + retries: 5 + +networks: + public: + external: true + name: ${PUBLIC_NETWORK} + monitored: + name: ${MONITORED_NETWORK} + external: true diff --git a/services/metabase/template.env b/services/metabase/template.env new file mode 100644 index 00000000..31389f3d --- /dev/null +++ b/services/metabase/template.env @@ -0,0 +1,8 @@ +PUBLIC_NETWORK=${PUBLIC_NETWORK} +MONITORED_NETWORK=${MONITORED_NETWORK} +ADMIN_DOMAIN=${ADMIN_DOMAIN} + +POSTGRES_HOST=${POSTGRES_HOST} +POSTGRES_PORT=${POSTGRES_PORT} +POSTGRES_USER=${POSTGRES_USER} +POSTGRES_PASSWORD=${POSTGRES_PASSWORD} From 4e0817bba040be6e6dac8bcead2601db306a6a37 Mon Sep 17 00:00:00 2001 From: YuryHrytsuk Date: Fri, 27 Jun 2025 10:32:38 +0200 Subject: [PATCH 3/6] Add metabase stack --- services/metabase/.gitignore | 2 + services/metabase/Makefile | 7 +++ .../metabase/configure_metabase.sql.template | 7 +++ ...cker-compose.yml => docker-compose.yml.j2} | 36 ++++++++++++---- services/metabase/logging_configuration.xml | 43 +++++++++++++++++++ services/metabase/template.env | 9 +++- 6 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 services/metabase/.gitignore create mode 100644 services/metabase/configure_metabase.sql.template rename services/metabase/{docker-compose.yml => docker-compose.yml.j2} (60%) create mode 100644 services/metabase/logging_configuration.xml diff --git a/services/metabase/.gitignore b/services/metabase/.gitignore new file mode 100644 index 00000000..a0120e09 --- /dev/null +++ b/services/metabase/.gitignore @@ -0,0 +1,2 @@ +configure_metabase.sql +docker-compose.yml diff --git a/services/metabase/Makefile b/services/metabase/Makefile index de94029f..60539799 100644 --- a/services/metabase/Makefile +++ b/services/metabase/Makefile @@ -8,3 +8,10 @@ up: ${TEMP_COMPOSE} ## Deploys metabase stack ${TEMP_COMPOSE}: docker-compose.yml .env @${REPO_BASE_DIR}/scripts/docker-stack-config.bash -e .env $< > $@ + +docker-compose.yml: docker-compose.yml.j2 .env .venv + @$(call jinja, $<, .env, $@) + +configure_metabase.sql: .env + @set -o allexport; source $<; set +o allexport; \ + envsubst < $@.template > $@ diff --git a/services/metabase/configure_metabase.sql.template b/services/metabase/configure_metabase.sql.template new file mode 100644 index 00000000..0446927e --- /dev/null +++ b/services/metabase/configure_metabase.sql.template @@ -0,0 +1,7 @@ +CREATE USER ${METABASE_POSTGRES_USER} WITH PASSWORD '${METABASE_POSTGRES_PASSWORD}'; + +-- relies on readonly role aldready existing in the database +GRANT ${POSTGRES_DB}_readonly TO ${METABASE_POSTGRES_USER}; + +CREATE DATABASE ${METABASE_POSTGRES_DB} + WITH OWNER ${METABASE_POSTGRES_USER}; diff --git a/services/metabase/docker-compose.yml b/services/metabase/docker-compose.yml.j2 similarity index 60% rename from services/metabase/docker-compose.yml rename to services/metabase/docker-compose.yml.j2 index bbf58471..3400d6d1 100644 --- a/services/metabase/docker-compose.yml +++ b/services/metabase/docker-compose.yml.j2 @@ -8,16 +8,20 @@ services: - public - monitored environment: + # Metabase logsd doc: https://www.metabase.com/docs/v0.54/configuring-metabase/log-configuration + - JAVA_OPTS=-Dlog4j.configurationFile=file:/tmp/my_log4j2.xml # https://www.metabase.com/docs/v0.54/installation-and-operation/configuring-application-database - MB_DB_TYPE=postgres - MB_DB_DBNAME=metabase - MB_DB_HOST=${POSTGRES_HOST} - MB_DB_PORT=${POSTGRES_PORT} - - MB_DB_USER=${POSTGRES_USER} - - MB_DB_PASS=${POSTGRES_PASSWORD} + - MB_DB_USER=${METABASE_POSTGRES_USER} + - MB_DB_PASS=${METABASE_POSTGRES_PASSWORD} # https://www.metabase.com/docs/v0.54/installation-and-operation/running-metabase-on-docker#setting-the-java-timezone - JAVA_TIMEZONE=UTC deploy: + # we do not need high availability. This service is not critical + replicas: 1 update_config: parallelism: 1 order: start-first @@ -27,6 +31,7 @@ services: constraints: - node.labels.ops==true labels: + # TODO: add prometheus metrics - traefik.enable=true - traefik.docker.network=${PUBLIC_NETWORK} # router @@ -37,18 +42,31 @@ services: - traefik.http.routers.metabase.middlewares=ops_whitelist_ips@swarm, ops_gzip@swarm, ops_auth@swarm, metabase_stripprefixregex # service - traefik.http.services.metabase.loadbalancer.server.port=3000 - # resources: - # limits: - # memory: 512M - # cpus: "1.0" - # reservations: - # memory: 128M - # cpus: "0.2" + - traefik.http.services.metabase.loadbalancer.healthcheck.path=/api/health + - traefik.http.services.metabase.loadbalancer.healthcheck.interval=5s + - traefik.http.services.metabase.loadbalancer.healthcheck.timeout=1s + + # https://www.metabase.com/learn/metabase-basics/administration/administration-and-operation/metabase-in-production + resources: + limits: + memory: 2G + cpus: "2.0" + reservations: + memory: 1G + cpus: "1.0" healthcheck: test: curl --fail -I http://localhost:3000/api/health || exit 1 interval: 15s timeout: 5s retries: 5 + configs: + - source: logging_configuration + target: /tmp/my_log4j2.xml + +configs: + logging_configuration: + file: ./logging_configuration.xml + name: {{ STACK_NAME }}_logging_configuration_{{ "./logging_configuration.xml" | sha256file | substring(0,10) }} networks: public: diff --git a/services/metabase/logging_configuration.xml b/services/metabase/logging_configuration.xml new file mode 100644 index 00000000..7f0253b2 --- /dev/null +++ b/services/metabase/logging_configuration.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/services/metabase/template.env b/services/metabase/template.env index 31389f3d..8d5780e9 100644 --- a/services/metabase/template.env +++ b/services/metabase/template.env @@ -1,8 +1,13 @@ +STACK_NAME=${STACK_NAME} + PUBLIC_NETWORK=${PUBLIC_NETWORK} MONITORED_NETWORK=${MONITORED_NETWORK} ADMIN_DOMAIN=${ADMIN_DOMAIN} POSTGRES_HOST=${POSTGRES_HOST} POSTGRES_PORT=${POSTGRES_PORT} -POSTGRES_USER=${POSTGRES_USER} -POSTGRES_PASSWORD=${POSTGRES_PASSWORD} +POSTGRES_DB=${POSTGRES_DB} + +METABASE_POSTGRES_USER=${METABASE_POSTGRES_USER} +METABASE_POSTGRES_PASSWORD=${METABASE_POSTGRES_PASSWORD} +METABASE_POSTGRES_DB=${METABASE_POSTGRES_DB} From 7e30b6f998e6d65f38b799068ada4f86351c8e26 Mon Sep 17 00:00:00 2001 From: YuryHrytsuk Date: Mon, 30 Jun 2025 08:53:42 +0200 Subject: [PATCH 4/6] Add replicas and fix browser errors --- services/metabase/docker-compose.yml.j2 | 19 ++++++++++++++----- services/metabase/template.env | 5 ++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/services/metabase/docker-compose.yml.j2 b/services/metabase/docker-compose.yml.j2 index 3400d6d1..9136a86f 100644 --- a/services/metabase/docker-compose.yml.j2 +++ b/services/metabase/docker-compose.yml.j2 @@ -8,8 +8,11 @@ services: - public - monitored environment: - # Metabase logsd doc: https://www.metabase.com/docs/v0.54/configuring-metabase/log-configuration - - JAVA_OPTS=-Dlog4j.configurationFile=file:/tmp/my_log4j2.xml + # Avoid: site URL basename "/" does not match the actual basename + # https://www.metabase.com/docs/latest/configuring-metabase/environment-variables#mb_site_url + - MB_SITE_URL=https://${ADMIN_DOMAIN}/metabase/ + # Metabase logs: https://www.metabase.com/docs/v0.54/configuring-metabase/log-configuration + - JAVA_OPTS=-Dlog4j.configurationFile=file:/etc/metabase/log4j2.xml # https://www.metabase.com/docs/v0.54/installation-and-operation/configuring-application-database - MB_DB_TYPE=postgres - MB_DB_DBNAME=metabase @@ -19,9 +22,11 @@ services: - MB_DB_PASS=${METABASE_POSTGRES_PASSWORD} # https://www.metabase.com/docs/v0.54/installation-and-operation/running-metabase-on-docker#setting-the-java-timezone - JAVA_TIMEZONE=UTC + # https://www.metabase.com/docs/latest/installation-and-operation/observability-with-prometheus + - MB_PROMETHEUS_SERVER_PORT=9191 deploy: - # we do not need high availability. This service is not critical - replicas: 1 + # https://www.metabase.com/learn/metabase-basics/administration/administration-and-operation/metabase-at-scale + replicas: ${METABASE_REPLICAS} update_config: parallelism: 1 order: start-first @@ -31,6 +36,10 @@ services: constraints: - node.labels.ops==true labels: + # prometheus only keeps jobs with `prometheus-job` label + - prometheus-job=metabase + # Set in `MB_PROMETHEUS_SERVER_PORT` environment variable + - prometheus-port=9191 # TODO: add prometheus metrics - traefik.enable=true - traefik.docker.network=${PUBLIC_NETWORK} @@ -61,7 +70,7 @@ services: retries: 5 configs: - source: logging_configuration - target: /tmp/my_log4j2.xml + target: /etc/metabase/log4j2.xml configs: logging_configuration: diff --git a/services/metabase/template.env b/services/metabase/template.env index 8d5780e9..02212e44 100644 --- a/services/metabase/template.env +++ b/services/metabase/template.env @@ -1,8 +1,11 @@ STACK_NAME=${STACK_NAME} +METABASE_REPLICAS=${METABASE_REPLICAS} + +ADMIN_DOMAIN=${ADMIN_DOMAIN} + PUBLIC_NETWORK=${PUBLIC_NETWORK} MONITORED_NETWORK=${MONITORED_NETWORK} -ADMIN_DOMAIN=${ADMIN_DOMAIN} POSTGRES_HOST=${POSTGRES_HOST} POSTGRES_PORT=${POSTGRES_PORT} From e89220935e2449d0835e729e7cd6de8576b68681 Mon Sep 17 00:00:00 2001 From: YuryHrytsuk Date: Mon, 30 Jun 2025 11:39:07 +0200 Subject: [PATCH 5/6] Reduce logging noise --- services/metabase/docker-compose.yml.j2 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/metabase/docker-compose.yml.j2 b/services/metabase/docker-compose.yml.j2 index 9136a86f..2faaca2b 100644 --- a/services/metabase/docker-compose.yml.j2 +++ b/services/metabase/docker-compose.yml.j2 @@ -8,6 +8,7 @@ services: - public - monitored environment: + - MB_HEALTH_CHECK_LOGGING_ENABLED=false # Avoid: site URL basename "/" does not match the actual basename # https://www.metabase.com/docs/latest/configuring-metabase/environment-variables#mb_site_url - MB_SITE_URL=https://${ADMIN_DOMAIN}/metabase/ @@ -52,7 +53,11 @@ services: # service - traefik.http.services.metabase.loadbalancer.server.port=3000 - traefik.http.services.metabase.loadbalancer.healthcheck.path=/api/health - - traefik.http.services.metabase.loadbalancer.healthcheck.interval=5s + - traefik.http.services.metabase.loadbalancer.healthcheck.interval=10s + # GET method sometimes fails (`Request canceled before finishing`) log + # This does not happen with HEAD method. Official healthcheck documentation + # defines HEAD as well + - traefik.http.services.metabase.loadbalancer.healthcheck.method=HEAD - traefik.http.services.metabase.loadbalancer.healthcheck.timeout=1s # https://www.metabase.com/learn/metabase-basics/administration/administration-and-operation/metabase-in-production From 21c1950f7896625de74079051919f8921d5e3912 Mon Sep 17 00:00:00 2001 From: YuryHrytsuk Date: Mon, 30 Jun 2025 11:50:39 +0200 Subject: [PATCH 6/6] Remove comments --- services/metabase/logging_configuration.xml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/services/metabase/logging_configuration.xml b/services/metabase/logging_configuration.xml index 7f0253b2..fcc286b9 100644 --- a/services/metabase/logging_configuration.xml +++ b/services/metabase/logging_configuration.xml @@ -8,19 +8,6 @@ - - -