From 95a8ef8db2529b38df0b9182c8e3d9f42ac1cd20 Mon Sep 17 00:00:00 2001 From: "anatoly.shipitz" Date: Tue, 29 Apr 2025 14:00:14 +0200 Subject: [PATCH 1/4] feat(docker): configure n8n and Temporal to use shared PostgreSQL backend - Set up environment variables for n8n and Temporal PostgreSQL connections - Ensure both services use separate databases and credentials - Add persistent Docker volumes for PostgreSQL data - Update docker-compose and .env.example for clarity and security Refs #64541 --- docker-compose.prod.yml | 17 ++++++++++++--- docker-compose.yml | 48 ++++++++++++++++++++++++++--------------- scripts/init-db.sh | 12 +++++++++++ 3 files changed, 57 insertions(+), 20 deletions(-) create mode 100755 scripts/init-db.sh diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index b3aa14d..e3a0d36 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,3 +1,13 @@ +x-environment: + &db-env + POSTGRES_DB_TEMPORAL: ${POSTGRES_DB_TEMPORAL:?POSTGRES_DB_TEMPORAL is required} + POSTGRES_USER_TEMPORAL: ${POSTGRES_USER_TEMPORAL:?POSTGRES_USER_TEMPORAL is required} + POSTGRES_PASSWORD_TEMPORAL: ${POSTGRES_PASSWORD_TEMPORAL:?POSTGRES_PASSWORD_TEMPORAL is required} + POSTGRES_DB_N8N: ${POSTGRES_DB_N8N:?POSTGRES_DB_N8N is required} + POSTGRES_USER_N8N: ${POSTGRES_USER_N8N:?POSTGRES_USER_N8N is required} + POSTGRES_PASSWORD_N8N: ${POSTGRES_PASSWORD_N8N:?POSTGRES_PASSWORD_N8N is required} + POSTGRES_PORT: ${POSTGRES_PORT:?POSTGRES_PORT is required} + services: n8n: environment: @@ -10,9 +20,10 @@ services: postgresql: environment: - - POSTGRES_USER=${POSTGRES_USER:?POSTGRES_USER is required} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} - - POSTGRES_DB=${POSTGRES_DB:?POSTGRES_DB is required} + <<: *db-env + volumes: + - postgresql-data:/var/lib/postgresql/data + - ./postgres-init:/docker-entrypoint-initdb.d temporal: environment: diff --git a/docker-compose.yml b/docker-compose.yml index 613f4e5..8d2b9db 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,9 @@ services: restart: unless-stopped ports: - "${N8N_PORT:-5678}:5678" + depends_on: + postgresql: + condition: service_healthy environment: - WEBHOOK_URL=${N8N_WEBHOOK_URL:-http://localhost:5678/} - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:-a_random_string_for_encryption} @@ -18,6 +21,14 @@ services: - N8N_METRICS=true - N8N_HEALTH_CHECK_ENDPOINT=true - N8N_EXPRESS_TRUST_PROXY=true + - DB_TYPE=postgresdb + - DB_POSTGRESDB_HOST=postgresql + - DB_POSTGRESDB_PORT=5432 + - DB_POSTGRESDB_DATABASE=${POSTGRES_DB_N8N:-n8n} + - DB_POSTGRESDB_USER=${POSTGRES_USER_N8N:-n8n} + - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD_N8N:-n8n_password} + - N8N_LOG_LEVEL=debug + - N8N_LOG_OUTPUT=console volumes: - n8n_data:/home/node/.n8n networks: @@ -60,18 +71,23 @@ services: image: postgres:14 restart: unless-stopped environment: - POSTGRES_USER: ${POSTGRES_USER:-temporal} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-temporal} - POSTGRES_DB: ${POSTGRES_DB:-temporal} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + POSTGRES_DB_N8N: ${POSTGRES_DB_N8N:-n8n} + POSTGRES_USER_N8N: ${POSTGRES_USER_N8N:-n8n} + POSTGRES_PASSWORD_N8N: ${POSTGRES_PASSWORD_N8N:-n8n_password} + POSTGRES_DB_TEMPORAL: ${POSTGRES_DB_TEMPORAL:-temporal} + POSTGRES_USER_TEMPORAL: ${POSTGRES_USER_TEMPORAL:-temporal} + POSTGRES_PASSWORD_TEMPORAL: ${POSTGRES_PASSWORD_TEMPORAL:-temporal} ports: - ${POSTGRES_PORT:-5432}:5432 volumes: - postgresql-data:/var/lib/postgresql/data + - ./scripts/init-db.sh:/docker-entrypoint-initdb.d/init-db.sh networks: - app-network user: postgres healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-temporal}"] + test: ["CMD-SHELL", "psql -U ${POSTGRES_USER_N8N:-n8n} -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname='${POSTGRES_DB_N8N:-n8n}'\" | grep -q 1 && psql -U ${POSTGRES_USER_TEMPORAL:-temporal} -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname='${POSTGRES_DB_TEMPORAL:-temporal}'\" | grep -q 1"] interval: 5s timeout: 5s retries: 5 @@ -92,19 +108,17 @@ services: opensearch: condition: service_healthy environment: - - TEMPORAL_PORT=${TEMPORAL_PORT:-7233} - - DB_PORT=${POSTGRES_PORT:-5432} - - POSTGRES_USER=${POSTGRES_USER:-temporal} - - POSTGRES_PWD=${POSTGRES_PASSWORD:-temporal} - - ES_SEEDS=opensearch - - ES_VERSION=v7 - - DB=postgresql - - DB_PORT=${POSTGRES_PORT} - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_PWD=${POSTGRES_PASSWORD} - - POSTGRES_SEEDS=postgresql - - ENABLE_ES=true - - HOST=temporal + TEMPORAL_PORT: ${TEMPORAL_PORT:-7233} + POSTGRES_SEEDS: postgresql + DB_PORT: ${POSTGRES_PORT:-5432} + DBNAME: ${POSTGRES_DB_TEMPORAL:-temporal} + POSTGRES_USER: ${POSTGRES_USER_TEMPORAL:-temporal} + POSTGRES_PWD: ${POSTGRES_PASSWORD_TEMPORAL:-temporal} + ES_SEEDS: opensearch + ES_VERSION: v7 + DB: postgresql + ENABLE_ES: "true" + HOST: temporal ports: - "${TEMPORAL_PORT:-7233}:7233" networks: diff --git a/scripts/init-db.sh b/scripts/init-db.sh new file mode 100755 index 0000000..cf0aa554 --- /dev/null +++ b/scripts/init-db.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +psql -v ON_ERROR_STOP=1 --username "postgres" <<-EOSQL + CREATE USER "$POSTGRES_USER_N8N" WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD_N8N'; + CREATE DATABASE "$POSTGRES_DB_N8N" OWNER "$POSTGRES_USER_N8N"; + GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB_N8N" TO "$POSTGRES_USER_N8N"; + + CREATE USER "$POSTGRES_USER_TEMPORAL" WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD_TEMPORAL'; + CREATE DATABASE "$POSTGRES_DB_TEMPORAL" OWNER "$POSTGRES_USER_TEMPORAL"; + GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB_TEMPORAL" TO "$POSTGRES_USER_TEMPORAL"; +EOSQL \ No newline at end of file From 2f48547edb02a2d31fa815ee463301226edca3d6 Mon Sep 17 00:00:00 2001 From: "anatoly.shipitz" Date: Tue, 29 Apr 2025 18:07:32 +0200 Subject: [PATCH 2/4] feat(docker): enhance production environment configuration for n8n and Temporal - Updated .env.example to include production environment variables for n8n and Temporal - Refined docker-compose.prod.yml to streamline PostgreSQL configuration and remove unnecessary volume definitions - Ensured all required environment variables are clearly defined for production deployment Refs #64541 --- .env.example | 44 ++++++++++++++++++++++++++++++++++++----- docker-compose.prod.yml | 33 +++++++++++-------------------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/.env.example b/.env.example index 51f15d5..d2adc8e 100644 --- a/.env.example +++ b/.env.example @@ -1,21 +1,55 @@ -# PostgreSQL Configuration +# ============================= +# Development Environment +# ============================= +# PostgreSQL (development) POSTGRES_USER=temporal POSTGRES_PASSWORD=temporal POSTGRES_DB=temporal POSTGRES_PORT=5432 +POSTGRES_DB_N8N=n8n +POSTGRES_USER_N8N=n8n +POSTGRES_PASSWORD_N8N=n8n_password +POSTGRES_DB_TEMPORAL=temporal +POSTGRES_USER_TEMPORAL=temporal +POSTGRES_PASSWORD_TEMPORAL=temporal -# n8n Configuration +# n8n (development) N8N_WEBHOOK_URL=http://localhost:5678/ N8N_ENCRYPTION_KEY=a_random_string_for_encryption N8N_PORT=5678 -# OpenSearch Configuration +# OpenSearch (development) DISABLE_SECURITY_PLUGIN=true OPENSEARCH_PORT=9200 -# Temporal Configuration +# Temporal (development) TEMPORAL_PORT=7233 TEMPORAL_UI_PORT=8080 -# GitHub MCP Server configuration +# GitHub MCP Server (development) GITHUB_PERSONAL_ACCESS_TOKEN=github_access_token + +# ============================= +# Production Environment +# ============================= +# n8n (production) +N8N_WEBHOOK_URL= +N8N_ENCRYPTION_KEY= +N8N_HOST= +POSTGRES_HOST= +POSTGRES_PORT=5432 +POSTGRES_DB_N8N= +POSTGRES_USER_N8N= +POSTGRES_PASSWORD_N8N= + +# opensearch (production) +OPENSEARCH_PORT=9200 + +# temporal (production) +TEMPORAL_PORT=7233 + +# temporal-ui (production) +TEMPORAL_UI_PORT=8080 +POSTGRES_DB_TEMPORAL= +POSTGRES_USER_TEMPORAL= +POSTGRES_PASSWORD_TEMPORAL= diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index e3a0d36..d81fb62 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,29 +1,19 @@ -x-environment: - &db-env - POSTGRES_DB_TEMPORAL: ${POSTGRES_DB_TEMPORAL:?POSTGRES_DB_TEMPORAL is required} - POSTGRES_USER_TEMPORAL: ${POSTGRES_USER_TEMPORAL:?POSTGRES_USER_TEMPORAL is required} - POSTGRES_PASSWORD_TEMPORAL: ${POSTGRES_PASSWORD_TEMPORAL:?POSTGRES_PASSWORD_TEMPORAL is required} - POSTGRES_DB_N8N: ${POSTGRES_DB_N8N:?POSTGRES_DB_N8N is required} - POSTGRES_USER_N8N: ${POSTGRES_USER_N8N:?POSTGRES_USER_N8N is required} - POSTGRES_PASSWORD_N8N: ${POSTGRES_PASSWORD_N8N:?POSTGRES_PASSWORD_N8N is required} - POSTGRES_PORT: ${POSTGRES_PORT:?POSTGRES_PORT is required} - services: n8n: environment: - WEBHOOK_URL=${N8N_WEBHOOK_URL:?N8N_WEBHOOK_URL is required} - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:?N8N_ENCRYPTION_KEY is required} - N8N_HOST=n8n.speedandfunction.com + - DB_POSTGRESDB_HOST=${POSTGRES_HOST:?POSTGRES_HOST is required} + - DB_POSTGRESDB_PORT=${POSTGRES_PORT:-5432} + - DB_POSTGRESDB_DATABASE=${POSTGRES_DB_N8N:?POSTGRES_DB_N8N is required} + - DB_POSTGRESDB_USER=${POSTGRES_USER_N8N:?POSTGRES_USER_N8N is required} + - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD_N8N:?POSTGRES_PASSWORD_N8N is required} opensearch: environment: - OPENSEARCH_PORT=${OPENSEARCH_PORT:?OPENSEARCH_PORT is required} - postgresql: - environment: - <<: *db-env - volumes: - - postgresql-data:/var/lib/postgresql/data - - ./postgres-init:/docker-entrypoint-initdb.d + postgresql: !reset null temporal: environment: @@ -32,6 +22,11 @@ services: temporal-ui: environment: - TEMPORAL_UI_PORT=${TEMPORAL_UI_PORT:?TEMPORAL_UI_PORT is required} + - POSTGRES_SEEDS=${POSTGRES_HOST:?POSTGRES_HOST is required} + - DB_PORT=${POSTGRES_PORT:-5432} + - DBNAME=${POSTGRES_DB_TEMPORAL:?POSTGRES_DB_TEMPORAL is required} + - POSTGRES_USER=${POSTGRES_USER_TEMPORAL:?POSTGRES_USER_TEMPORAL is required} + - POSTGRES_PWD=${POSTGRES_PASSWORD_TEMPORAL:?POSTGRES_PASSWORD_TEMPORAL is required} volumes: n8n_data: @@ -46,9 +41,3 @@ volumes: type: none o: bind device: /data/opensearch - postgresql-data: - driver: local - driver_opts: - type: none - o: bind - device: /data/postgresql From 1b84440a8c4facd12b530a8d5bb736db27fecf0b Mon Sep 17 00:00:00 2001 From: "anatoly.shipitz" Date: Tue, 29 Apr 2025 19:18:32 +0200 Subject: [PATCH 3/4] feat(docker): update production configuration for n8n and Temporal - Added required environment variables for n8n and Temporal services in docker-compose.prod.yml - Set dependencies for n8n and Temporal services to ensure proper startup order - Improved clarity by using environment variable placeholders for host and database configurations This update enhances the production setup for better reliability and configuration management. --- docker-compose.prod.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 71c3a84..e60a760 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,9 +1,10 @@ services: n8n: + depends_on: !reset null environment: - WEBHOOK_URL=${N8N_WEBHOOK_URL:?N8N_WEBHOOK_URL is required} - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:?N8N_ENCRYPTION_KEY is required} - - N8N_HOST=n8n.speedandfunction.com + - N8N_HOST=${N8N_HOST:?N8N_HOST is required} - DB_POSTGRESDB_HOST=${POSTGRES_HOST:?POSTGRES_HOST is required} - DB_POSTGRESDB_PORT=${POSTGRES_PORT:-5432} - DB_POSTGRESDB_DATABASE=${POSTGRES_DB_N8N:?POSTGRES_DB_N8N is required} @@ -16,8 +17,18 @@ services: postgresql: !reset null temporal: + depends_on: !reset null environment: - TEMPORAL_PORT=${TEMPORAL_PORT:?TEMPORAL_PORT is required} + - POSTGRES_SEEDS=${POSTGRES_HOST:?POSTGRES_HOST is required} + - DB_PORT=${POSTGRES_PORT:-5432} + - DBNAME=${POSTGRES_DB_TEMPORAL:?POSTGRES_DB_TEMPORAL is required} + - POSTGRES_USER=${POSTGRES_USER_TEMPORAL:?POSTGRES_USER_TEMPORAL is required} + - POSTGRES_PWD=${POSTGRES_PASSWORD_TEMPORAL:?POSTGRES_PASSWORD_TEMPORAL is required} + - ES_SEEDS=opensearch + - ES_VERSION=v7 + - DB=postgresql + - ENABLE_ES=true temporal-ui: environment: From 4ab69a3748111c5b5576e7dc23249dc19c444177 Mon Sep 17 00:00:00 2001 From: "anatoly.shipitz" Date: Tue, 29 Apr 2025 19:41:55 +0200 Subject: [PATCH 4/4] fix(init-db): add missing newline at end of init-db.sh - Added a newline at the end of the init-db.sh script to ensure proper file formatting and prevent potential issues in execution. This change improves the script's compatibility and adheres to best practices for shell scripts. --- scripts/init-db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/init-db.sh b/scripts/init-db.sh index cf0aa554..eda439b 100755 --- a/scripts/init-db.sh +++ b/scripts/init-db.sh @@ -9,4 +9,4 @@ psql -v ON_ERROR_STOP=1 --username "postgres" <<-EOSQL CREATE USER "$POSTGRES_USER_TEMPORAL" WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD_TEMPORAL'; CREATE DATABASE "$POSTGRES_DB_TEMPORAL" OWNER "$POSTGRES_USER_TEMPORAL"; GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB_TEMPORAL" TO "$POSTGRES_USER_TEMPORAL"; -EOSQL \ No newline at end of file +EOSQL