From e0eaa96a23d29a270f931eb8a77607b3fe75a65d Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 06:48:23 +0200 Subject: [PATCH 01/16] Add Docker setup and CI pipeline for n8n and Temporal workflow automation with documentation. - Added GitHub Actions workflow with Dockerfile linting - Created Dockerfiles for n8n and Temporal services - Added docker-compose.yml for orchestration - Updated .gitignore to exclude volumes - Enhanced README with setup instructions --- .github/workflows/code-quality.yml | 20 ++++- .gitignore | 1 + Dockerfile.n8n | 15 ++++ Dockerfile.temporal | 20 +++++ README.md | 117 ++++++++++++++++++++++++++++- docker-compose.yml | 99 ++++++++++++++++++++++++ 6 files changed, 267 insertions(+), 5 deletions(-) create mode 100644 Dockerfile.n8n create mode 100644 Dockerfile.temporal create mode 100644 docker-compose.yml diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 933c2ae..752b1da 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -12,19 +12,31 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout + - name: Checkout code uses: actions/checkout@v4 - - name: Lint + - name: Run linting run: echo "Linting..." sonarqube: name: SonarQube runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: SonarQube Scan + - name: Run SonarQube scan uses: SonarSource/sonarqube-scan-action@v5 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + hadolint: + name: Dockerfile Linting + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Lint Dockerfile.n8n + run: docker run --rm -i hadolint/hadolint < Dockerfile.n8n + - name: Lint Dockerfile.temporal + run: docker run --rm -i hadolint/hadolint < Dockerfile.temporal diff --git a/.gitignore b/.gitignore index 1170717..0d658f6 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,4 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* +volumes diff --git a/Dockerfile.n8n b/Dockerfile.n8n new file mode 100644 index 0000000..5b610cb --- /dev/null +++ b/Dockerfile.n8n @@ -0,0 +1,15 @@ +FROM n8nio/n8n:latest + +# Add custom environment variables +ENV N8N_PORT=5678 \ + NODE_ENV=production + +# Create app directory +WORKDIR /home/node/.n8n + +# Add custom healthcheck +HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ + CMD wget -q --spider http://localhost:5678/healthz || exit 1 + +# The entrypoint script is already defined in the base image +# Don't override the CMD \ No newline at end of file diff --git a/Dockerfile.temporal b/Dockerfile.temporal new file mode 100644 index 0000000..f9e3c17 --- /dev/null +++ b/Dockerfile.temporal @@ -0,0 +1,20 @@ +FROM temporalio/auto-setup:1.20 + +# Set up environment variables for PostgreSQL and Elasticsearch +ENV DB=postgresql \ + DB_PORT=5432 \ + POSTGRES_USER=temporal \ + POSTGRES_PWD=temporal \ + POSTGRES_SEEDS=postgresql \ + ENABLE_ES=true \ + ES_SEEDS=elasticsearch \ + ES_VERSION=v7 + +# Add custom healthcheck +HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ + CMD temporal operator cluster health | grep -q SERVING || exit 1 + +# Expose the gRPC port +EXPOSE 7233 + +# The entrypoint script is already defined in the base image \ No newline at end of file diff --git a/README.md b/README.md index 40862b3..c8948d9 100644 --- a/README.md +++ b/README.md @@ -1 +1,116 @@ -# automatization \ No newline at end of file +# n8n and Temporal Docker Compose Setup + +This repository contains a Docker Compose configuration to run n8n and Temporal services together. + +## Services + +The setup includes: + +- **n8n**: An automation tool that allows you to create workflows visually +- **Temporal**: A workflow orchestration platform with the following components: + - Temporal server + - Temporal UI + - PostgreSQL (database) + - Elasticsearch (for visibility features) + +## Custom Docker Images + +This project uses custom Docker images built from the following Dockerfiles: + +- **Dockerfile.n8n**: Extends the official n8n image with custom configurations +- **Dockerfile.temporal**: Extends the official Temporal auto-setup image + +## Usage + +### Starting the services + +```bash +docker compose up -d +``` + +This will start all services in detached mode. + +### Building custom images + +If you've made changes to the Dockerfiles, you'll need to rebuild the images: + +```bash +docker compose build +``` + +Or to rebuild and start in one command: + +```bash +docker compose down && docker compose build && docker compose up -d +``` + +### Verifying services are running + +Check that all containers are running: + +```bash +docker compose ps +``` + +You should see containers for: +- n8n +- temporal +- temporal-ui +- temporal-postgresql +- temporal-elasticsearch + +### Accessing the services + +- **n8n**: http://localhost:5678 +- **Temporal UI**: http://localhost:8080 + +You can verify the services are responding with: + +```bash +# Check n8n is responding +curl -I http://localhost:5678 + +# Check Temporal UI is responding +curl -I http://localhost:8080 +``` + +### Stopping the services + +```bash +docker compose down +``` + +To completely remove all data volumes: + +```bash +docker compose down -v +``` + +## Data Persistence + +All data is stored in local volumes under the `./volumes/` directory: + +- `./volumes/n8n_data` - n8n data and workflows +- `./volumes/elasticsearch-data` - Elasticsearch data for Temporal +- `./volumes/postgresql-data` - PostgreSQL database for Temporal + +## Service Ports + +- n8n: 5678 +- Temporal server: 7233 (gRPC API, not HTTP) +- Temporal UI: 8080 +- PostgreSQL: 5432 +- Elasticsearch: 9200 + +## Troubleshooting + +If you encounter any issues: + +1. Check container logs: + ```bash + docker logs temporal + docker logs automatization-n8n-1 + ``` + +2. Ensure all required ports are available on your system +3. Make sure Docker has sufficient resources allocated \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..64a0d7e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,99 @@ +services: + # n8n service + n8n: + build: + context: . + dockerfile: Dockerfile.n8n + ports: + - "5678:5678" + environment: + - WEBHOOK_URL=http://localhost:5678/ + volumes: + - ./volumes/n8n_data:/home/node/.n8n + networks: + - app-network + + # Temporal services + elasticsearch: + container_name: temporal-elasticsearch + image: opensearchproject/opensearch:2.5.0 + environment: + - discovery.type=single-node + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xms256m -Xmx256m" + - "DISABLE_SECURITY_PLUGIN=true" + - "DISABLE_INSTALL_DEMO_CONFIG=true" + ports: + - 9200:9200 + ulimits: + memlock: + soft: -1 + hard: -1 + volumes: + - ./volumes/elasticsearch-data:/usr/share/opensearch/data + networks: + - app-network + + postgresql: + container_name: temporal-postgresql + image: postgres:14 + environment: + POSTGRES_USER: temporal + POSTGRES_PASSWORD: temporal + POSTGRES_DB: temporal + ports: + - 5432:5432 + volumes: + - ./volumes/postgresql-data:/var/lib/postgresql/data + networks: + - app-network + + temporal: + container_name: temporal + build: + context: . + dockerfile: Dockerfile.temporal + depends_on: + - postgresql + - elasticsearch + ports: + - 7233:7233 + networks: + - app-network + + temporal-ui: + container_name: temporal-ui + image: temporalio/ui:2.10.3 + depends_on: + - temporal + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_PERMIT_WRITE_API=true + ports: + - 8080:8080 + networks: + - app-network + +volumes: + n8n_data: + driver: local + driver_opts: + type: none + o: bind + device: ${PWD}/volumes/n8n_data + elasticsearch-data: + driver: local + driver_opts: + type: none + o: bind + device: ${PWD}/volumes/elasticsearch-data + postgresql-data: + driver: local + driver_opts: + type: none + o: bind + device: ${PWD}/volumes/postgresql-data + +networks: + app-network: + driver: bridge \ No newline at end of file From a33801e9306b671c433c9f6db6e0bfbcc896af2e Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 07:00:03 +0200 Subject: [PATCH 02/16] Pin n8n Docker image to version 1.22.0 for improved stability. --- Dockerfile.n8n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.n8n b/Dockerfile.n8n index 5b610cb..da584c4 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -1,4 +1,4 @@ -FROM n8nio/n8n:latest +FROM n8nio/n8n:1.22.0 # Add custom environment variables ENV N8N_PORT=5678 \ From 4b7a21ea0d69b6e1086c913cbb34e25c0d4f66db Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 07:04:23 +0200 Subject: [PATCH 03/16] Fix n8n healthcheck to use N8N_PORT environment variable instead of hardcoded port --- Dockerfile.n8n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.n8n b/Dockerfile.n8n index da584c4..593ab60 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -9,7 +9,7 @@ WORKDIR /home/node/.n8n # Add custom healthcheck HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ - CMD wget -q --spider http://localhost:5678/healthz || exit 1 + CMD wget -q --spider http://localhost:${N8N_PORT}/healthz || exit 1 # The entrypoint script is already defined in the base image # Don't override the CMD \ No newline at end of file From e9990be5ee9c30c20a4257a015fa129708f8c25f Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 07:33:28 +0200 Subject: [PATCH 04/16] Update Docker volume configurations to use named volumes - Replace direct path mapping for n8n_data volume with named volume reference - Replace direct path mapping for elasticsearch-data volume with named volume reference - Replace direct path mapping for postgresql-data volume with named volume reference --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 64a0d7e..a380c7e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: environment: - WEBHOOK_URL=http://localhost:5678/ volumes: - - ./volumes/n8n_data:/home/node/.n8n + - n8n_data:/home/node/.n8n networks: - app-network @@ -30,7 +30,7 @@ services: soft: -1 hard: -1 volumes: - - ./volumes/elasticsearch-data:/usr/share/opensearch/data + - elasticsearch-data:/usr/share/opensearch/data networks: - app-network @@ -44,7 +44,7 @@ services: ports: - 5432:5432 volumes: - - ./volumes/postgresql-data:/var/lib/postgresql/data + - postgresql-data:/var/lib/postgresql/data networks: - app-network From 43c47a48947f00f4aecb379f542932face1c4721 Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 08:13:18 +0200 Subject: [PATCH 05/16] Improve Docker security and introduce service health checks - Enhanced Dockerfiles with explicit non-root users for n8n and Temporal - Added health check endpoints and metrics configuration to n8n - Improved healthcheck commands with proper shell form in Dockerfiles - Added service dependencies with health conditions in docker-compose.yml - Created check_services.sh script to verify all services accessibility - Added PostgreSQL and Elasticsearch healthcheck configurations - Updated README with service health checking documentation - Added IPC_LOCK capability for Elasticsearch container --- Dockerfile.n8n | 11 +++++--- Dockerfile.temporal | 7 ++++-- README.md | 30 ++++++++++++++++++++++ docker-compose.yml | 28 ++++++++++++++++++--- scripts/check_services.sh | 53 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 8 deletions(-) create mode 100755 scripts/check_services.sh diff --git a/Dockerfile.n8n b/Dockerfile.n8n index 593ab60..bc213f4 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -2,14 +2,19 @@ FROM n8nio/n8n:1.22.0 # Add custom environment variables ENV N8N_PORT=5678 \ - NODE_ENV=production + NODE_ENV=production \ + N8N_METRICS=true \ + N8N_HEALTH_CHECK_ENDPOINT=true # Create app directory WORKDIR /home/node/.n8n -# Add custom healthcheck +# Add custom healthcheck - using shell form to ensure || works correctly HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ - CMD wget -q --spider http://localhost:${N8N_PORT}/healthz || exit 1 + CMD /bin/sh -c "curl -s http://localhost:${N8N_PORT}/healthz || exit 1" + +# Explicitly set the user to the non-root 'node' user (which is already set up in the base image) +USER node # The entrypoint script is already defined in the base image # Don't override the CMD \ No newline at end of file diff --git a/Dockerfile.temporal b/Dockerfile.temporal index f9e3c17..4e1b8d5 100644 --- a/Dockerfile.temporal +++ b/Dockerfile.temporal @@ -10,9 +10,12 @@ ENV DB=postgresql \ ES_SEEDS=elasticsearch \ ES_VERSION=v7 -# Add custom healthcheck +# Add custom healthcheck - using shell form to ensure || works correctly HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ - CMD temporal operator cluster health | grep -q SERVING || exit 1 + CMD /bin/sh -c "temporal operator cluster health --address 0.0.0.0:7233 | grep -q SERVING || exit 1" + +# Explicitly set the user to the non-root 'temporal' user (already defined in the base image) +USER temporal # Expose the gRPC port EXPOSE 7233 diff --git a/README.md b/README.md index c8948d9..f29a577 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,36 @@ You should see containers for: - temporal-postgresql - temporal-elasticsearch +### Checking Service Health + +Use the provided script to verify that all services are accessible: + +```bash +./check_services.sh +``` + +This will check: +- n8n health endpoint +- Temporal UI web interface +- Elasticsearch API +- Temporal server gRPC port +- PostgreSQL database connection + +Example output: +``` +Checking service availability... +Checking n8n at http://localhost:5678/healthz... ACCESSIBLE ✅ (HTTP 200) +Checking temporal-ui at http://localhost:8080... ACCESSIBLE ✅ (HTTP 200) +Checking elasticsearch at http://localhost:9200... ACCESSIBLE ✅ (HTTP 200) +Checking temporal at localhost:7233... ACCESSIBLE ✅ +Checking postgresql at localhost:5432... ACCESSIBLE ✅ + +Service URLs: +- n8n: http://localhost:5678 +- Temporal UI: http://localhost:8080 +- Elasticsearch: http://localhost:9200 +``` + ### Accessing the services - **n8n**: http://localhost:5678 diff --git a/docker-compose.yml b/docker-compose.yml index a380c7e..46601ba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,10 @@ services: - n8n_data:/home/node/.n8n networks: - app-network + user: node + depends_on: + postgresql: + condition: service_healthy # Temporal services elasticsearch: @@ -25,6 +29,8 @@ services: - "DISABLE_INSTALL_DEMO_CONFIG=true" ports: - 9200:9200 + cap_add: + - IPC_LOCK ulimits: memlock: soft: -1 @@ -33,6 +39,11 @@ services: - elasticsearch-data:/usr/share/opensearch/data networks: - app-network + healthcheck: + test: ["CMD-SHELL", "curl -sSf http://localhost:9200/ || exit 1"] + interval: 30s + timeout: 10s + retries: 5 postgresql: container_name: temporal-postgresql @@ -47,6 +58,13 @@ services: - postgresql-data:/var/lib/postgresql/data networks: - app-network + user: postgres + healthcheck: + test: ["CMD-SHELL", "pg_isready -U temporal"] + interval: 5s + timeout: 5s + retries: 5 + start_period: 10s temporal: container_name: temporal @@ -54,18 +72,22 @@ services: context: . dockerfile: Dockerfile.temporal depends_on: - - postgresql - - elasticsearch + postgresql: + condition: service_healthy + elasticsearch: + condition: service_healthy ports: - 7233:7233 networks: - app-network + user: temporal temporal-ui: container_name: temporal-ui image: temporalio/ui:2.10.3 depends_on: - - temporal + temporal: + condition: service_started environment: - TEMPORAL_ADDRESS=temporal:7233 - TEMPORAL_PERMIT_WRITE_API=true diff --git a/scripts/check_services.sh b/scripts/check_services.sh new file mode 100755 index 0000000..e73ebc2 --- /dev/null +++ b/scripts/check_services.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +echo "Checking service availability..." + +# Check if docker-compose is running +if ! docker compose ps >/dev/null 2>&1; then + echo "Error: Docker services are not running. Start them with 'docker compose up -d'" + exit 1 +fi + +# Function to check HTTP service +check_http_service() { + local service=$1 + local url=$2 + echo -n "Checking $service at $url... " + + response=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null) + if [[ $response -ge 200 && $response -lt 500 ]]; then + echo "ACCESSIBLE ✅ (HTTP $response)" + else + echo "NOT ACCESSIBLE ❌ (HTTP $response)" + fi +} + +# Check n8n +check_http_service "n8n" "http://localhost:5678/healthz" + +# Check temporal-ui +check_http_service "temporal-ui" "http://localhost:8080" + +# Check elasticsearch +check_http_service "elasticsearch" "http://localhost:9200" + +# Check temporal service +echo -n "Checking temporal at localhost:7233... " +if nc -z localhost 7233 >/dev/null 2>&1; then + echo "ACCESSIBLE ✅" +else + echo "NOT ACCESSIBLE ❌" +fi + +# Check PostgreSQL +echo -n "Checking postgresql at localhost:5432... " +if docker compose exec postgresql pg_isready -h localhost -p 5432 -U temporal >/dev/null 2>&1; then + echo "ACCESSIBLE ✅" +else + echo "NOT ACCESSIBLE ❌" +fi + +echo -e "\nService URLs:" +echo "- n8n: http://localhost:5678" +echo "- Temporal UI: http://localhost:8080" +echo "- Elasticsearch: http://localhost:9200" \ No newline at end of file From 04932c78ecc23ff814a8340f787472e385531cac Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 08:35:27 +0200 Subject: [PATCH 06/16] Add service availability check to CI workflow - Added new 'service-check' job in GitHub workflow - Implemented steps to build and start docker services for testing - Added verification step using scripts/check_services.sh - Included cleanup to ensure services are stopped after testing --- .github/workflows/code-quality.yml | 18 ++++++++++++++++++ docker-compose.yml | 3 --- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 752b1da..f7fa7de 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -40,3 +40,21 @@ jobs: run: docker run --rm -i hadolint/hadolint < Dockerfile.n8n - name: Lint Dockerfile.temporal run: docker run --rm -i hadolint/hadolint < Dockerfile.temporal + + service-check: + name: Service Availability Check + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Docker Compose + uses: docker/setup-buildx-action@v2 + - name: Build services with no cache + run: docker compose build --no-cache + - name: Start services + run: docker compose up -d + - name: Verify services + run: bash scripts/check_services.sh + - name: Stop services + run: docker compose down + if: always() diff --git a/docker-compose.yml b/docker-compose.yml index 46601ba..8ad0cc1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,9 +13,6 @@ services: networks: - app-network user: node - depends_on: - postgresql: - condition: service_healthy # Temporal services elasticsearch: From 289c8993e62d043cf7ae704e3dade741e1e8e196 Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 08:52:15 +0200 Subject: [PATCH 07/16] Update Docker Buildx action from v2 to v3 in CI workflow - Changed Docker setup-buildx-action from v2 to v3 - Fixed step name from "Set up Docker Compose" to "Set up Docker Buildx" --- .github/workflows/code-quality.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index f7fa7de..53b9be0 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -47,8 +47,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Docker Compose - uses: docker/setup-buildx-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Build services with no cache run: docker compose build --no-cache - name: Start services From 47461d0f24848de739d1f14eb2999697832d2fab Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 09:59:36 +0200 Subject: [PATCH 08/16] Update HEALTHCHECK format to use exec form in Docker configurations - Changed healthcheck in Dockerfile.n8n from shell form to exec form for better practice - Changed healthcheck in Dockerfile.temporal from shell form to exec form for better practi --- Dockerfile.n8n | 4 ++-- Dockerfile.temporal | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile.n8n b/Dockerfile.n8n index bc213f4..eea4d7a 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -9,9 +9,9 @@ ENV N8N_PORT=5678 \ # Create app directory WORKDIR /home/node/.n8n -# Add custom healthcheck - using shell form to ensure || works correctly +# Add custom healthcheck using exec form HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ - CMD /bin/sh -c "curl -s http://localhost:${N8N_PORT}/healthz || exit 1" + CMD ["/bin/sh", "-c", "curl -s http://localhost:${N8N_PORT}/healthz || exit 1"] # Explicitly set the user to the non-root 'node' user (which is already set up in the base image) USER node diff --git a/Dockerfile.temporal b/Dockerfile.temporal index 4e1b8d5..4526a10 100644 --- a/Dockerfile.temporal +++ b/Dockerfile.temporal @@ -10,9 +10,9 @@ ENV DB=postgresql \ ES_SEEDS=elasticsearch \ ES_VERSION=v7 -# Add custom healthcheck - using shell form to ensure || works correctly +# Add custom healthcheck using exec form HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ - CMD /bin/sh -c "temporal operator cluster health --address 0.0.0.0:7233 | grep -q SERVING || exit 1" + CMD ["/bin/sh", "-c", "temporal operator cluster health --address 0.0.0.0:7233 | grep -q SERVING || exit 1"] # Explicitly set the user to the non-root 'temporal' user (already defined in the base image) USER temporal From 44ae932bcab7e02559c1434bab96086ade0fa515 Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 10:35:37 +0200 Subject: [PATCH 09/16] Add Docker volume setup script for CI service testing Add scripts/setup_volumes.sh for creating required volume directories Modify service-check job in code-quality.yml to run the volume setup script before testing --- .github/workflows/code-quality.yml | 2 ++ scripts/setup_volumes.sh | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100755 scripts/setup_volumes.sh diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 53b9be0..9660f01 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -47,6 +47,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - name: Create volume directories + run: bash scripts/setup_volumes.sh - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build services with no cache diff --git a/scripts/setup_volumes.sh b/scripts/setup_volumes.sh new file mode 100755 index 0000000..f38ee37 --- /dev/null +++ b/scripts/setup_volumes.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Create volume directories for Docker Compose +echo "Setting up volume directories..." +mkdir -p volumes/elasticsearch-data +mkdir -p volumes/postgresql-data +mkdir -p volumes/n8n_data + +echo "Volume directories created successfully." \ No newline at end of file From b64c3456d606c0bf1474f70874db220e03613bb0 Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Fri, 18 Apr 2025 10:47:11 +0200 Subject: [PATCH 10/16] Improve CI pipeline with timeout and cleanup enhancements - Add 10-minute timeout for service-check job - Ensure service cleanup runs even if previous steps fail with "if: always()" - Add "-v" flag to docker compose down to remove volumes after tests - Fix whitespace in SonarQube job --- .github/workflows/code-quality.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 9660f01..50bb6da 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -29,7 +29,7 @@ jobs: uses: SonarSource/sonarqube-scan-action@v5 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - + hadolint: name: Dockerfile Linting runs-on: ubuntu-latest @@ -43,6 +43,7 @@ jobs: service-check: name: Service Availability Check + timeout-minutes: 10 runs-on: ubuntu-latest steps: - name: Checkout code @@ -58,5 +59,5 @@ jobs: - name: Verify services run: bash scripts/check_services.sh - name: Stop services - run: docker compose down if: always() + run: docker compose down -v From c80b677a62be79be29b8f263b8bf51e680f5363e Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Sun, 20 Apr 2025 17:58:45 +0200 Subject: [PATCH 11/16] Update Temporal and n8n configurations with latest versions and environment variables - Update n8n from 1.22.0 to 1.89.2 and change working directory - Update Temporal from 1.20 to 1.20.5 and configure with environment variables - Replace Elasticsearch with OpenSearch for Temporal visibility - Add environment variables for n8n and database configurations - Improve container restart policies with unless-stopped - Update documentation with volume setup instructions and troubleshooting - Add .gitignore entries for mcp executable, config files and .cursor - Fix volume paths and opensearch port mapping --- .gitignore | 5 +++++ Dockerfile.n8n | 6 +++--- Dockerfile.temporal | 16 ++++++++-------- README.md | 34 ++++++++++++++++++++++++++-------- docker-compose.yml | 38 +++++++++++++++++++++++--------------- scripts/check_services.sh | 6 +++--- scripts/setup_volumes.sh | 2 +- 7 files changed, 69 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index 0d658f6..66b3b1b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,11 @@ yarn-error.log* lerna-debug.log* .pnpm-debug.log* +# mcp executable +mcp +mcp-config.json +.cursor/ + # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/Dockerfile.n8n b/Dockerfile.n8n index eea4d7a..032d17f 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -1,4 +1,4 @@ -FROM n8nio/n8n:1.22.0 +FROM n8nio/n8n:1.89.2 # Add custom environment variables ENV N8N_PORT=5678 \ @@ -7,7 +7,7 @@ ENV N8N_PORT=5678 \ N8N_HEALTH_CHECK_ENDPOINT=true # Create app directory -WORKDIR /home/node/.n8n +WORKDIR /home/node # Add custom healthcheck using exec form HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ @@ -17,4 +17,4 @@ HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ USER node # The entrypoint script is already defined in the base image -# Don't override the CMD \ No newline at end of file +# Don't override the CMD diff --git a/Dockerfile.temporal b/Dockerfile.temporal index 4526a10..aa29bb2 100644 --- a/Dockerfile.temporal +++ b/Dockerfile.temporal @@ -1,17 +1,17 @@ -FROM temporalio/auto-setup:1.20 +FROM temporalio/auto-setup:1.20.5 -# Set up environment variables for PostgreSQL and Elasticsearch +# Set up environment variables for PostgreSQL and OpenSearch ENV DB=postgresql \ DB_PORT=5432 \ - POSTGRES_USER=temporal \ - POSTGRES_PWD=temporal \ + POSTGRES_USER=${POSTGRES_USER} \ + POSTGRES_PWD=${POSTGRES_PASSWORD} \ POSTGRES_SEEDS=postgresql \ ENABLE_ES=true \ - ES_SEEDS=elasticsearch \ - ES_VERSION=v7 + ES_SEEDS=opensearch \ + ES_VERSION=v2 # Add custom healthcheck using exec form -HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ +HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ CMD ["/bin/sh", "-c", "temporal operator cluster health --address 0.0.0.0:7233 | grep -q SERVING || exit 1"] # Explicitly set the user to the non-root 'temporal' user (already defined in the base image) @@ -20,4 +20,4 @@ USER temporal # Expose the gRPC port EXPOSE 7233 -# The entrypoint script is already defined in the base image \ No newline at end of file +# The entrypoint script is already defined in the base image diff --git a/README.md b/README.md index f29a577..b4b7a46 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The setup includes: - Temporal server - Temporal UI - PostgreSQL (database) - - Elasticsearch (for visibility features) + - OpenSearch (for visibility features) ## Custom Docker Images @@ -22,6 +22,17 @@ This project uses custom Docker images built from the following Dockerfiles: ## Usage +### Prepare volume directories + +Before starting the services, run the setup script to create the necessary volume directories: + +```bash +chmod +x scripts/setup_volumes.sh +./scripts/setup_volumes.sh +``` + +This prevents volume mount errors that may occur if the directories don't exist. + ### Starting the services ```bash @@ -57,7 +68,7 @@ You should see containers for: - temporal - temporal-ui - temporal-postgresql -- temporal-elasticsearch +- opensearch ### Checking Service Health @@ -70,7 +81,7 @@ Use the provided script to verify that all services are accessible: This will check: - n8n health endpoint - Temporal UI web interface -- Elasticsearch API +- OpenSearch API - Temporal server gRPC port - PostgreSQL database connection @@ -79,14 +90,14 @@ Example output: Checking service availability... Checking n8n at http://localhost:5678/healthz... ACCESSIBLE ✅ (HTTP 200) Checking temporal-ui at http://localhost:8080... ACCESSIBLE ✅ (HTTP 200) -Checking elasticsearch at http://localhost:9200... ACCESSIBLE ✅ (HTTP 200) +Checking opensearch at http://localhost:9200... ACCESSIBLE ✅ (HTTP 200) Checking temporal at localhost:7233... ACCESSIBLE ✅ Checking postgresql at localhost:5432... ACCESSIBLE ✅ Service URLs: - n8n: http://localhost:5678 - Temporal UI: http://localhost:8080 -- Elasticsearch: http://localhost:9200 +- OpenSearch: http://localhost:9200 ``` ### Accessing the services @@ -121,7 +132,7 @@ docker compose down -v All data is stored in local volumes under the `./volumes/` directory: - `./volumes/n8n_data` - n8n data and workflows -- `./volumes/elasticsearch-data` - Elasticsearch data for Temporal +- `./volumes/opensearch-data` - OpenSearch data for Temporal - `./volumes/postgresql-data` - PostgreSQL database for Temporal ## Service Ports @@ -130,7 +141,7 @@ All data is stored in local volumes under the `./volumes/` directory: - Temporal server: 7233 (gRPC API, not HTTP) - Temporal UI: 8080 - PostgreSQL: 5432 -- Elasticsearch: 9200 +- OpenSearch: 9200 ## Troubleshooting @@ -143,4 +154,11 @@ If you encounter any issues: ``` 2. Ensure all required ports are available on your system -3. Make sure Docker has sufficient resources allocated \ No newline at end of file + +3. Make sure Docker has sufficient resources allocated + +4. If you encounter volume mount errors (e.g., "failed to mount local volume ... no such file or directory"), run the setup script: + ```bash + ./scripts/setup_volumes.sh + ``` + This creates the necessary volume directories in the `./volumes/` folder. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 8ad0cc1..575e70b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,10 +4,12 @@ services: build: context: . dockerfile: Dockerfile.n8n + restart: unless-stopped ports: - "5678:5678" environment: - - WEBHOOK_URL=http://localhost:5678/ + - WEBHOOK_URL=$N8N_WEBHOOK_URL + - N8N_ENCRYPTION_KEY=$N8N_ENCRYPTION_KEY volumes: - n8n_data:/home/node/.n8n networks: @@ -15,17 +17,18 @@ services: user: node # Temporal services - elasticsearch: - container_name: temporal-elasticsearch + opensearch: + container_name: opensearch image: opensearchproject/opensearch:2.5.0 + restart: unless-stopped environment: - discovery.type=single-node - bootstrap.memory_lock=true - "OPENSEARCH_JAVA_OPTS=-Xms256m -Xmx256m" - - "DISABLE_SECURITY_PLUGIN=true" + - "DISABLE_SECURITY_PLUGIN=${DISABLE_SECURITY_PLUGIN}" - "DISABLE_INSTALL_DEMO_CONFIG=true" ports: - - 9200:9200 + - 9201:9200 cap_add: - IPC_LOCK ulimits: @@ -33,7 +36,7 @@ services: soft: -1 hard: -1 volumes: - - elasticsearch-data:/usr/share/opensearch/data + - opensearch-data:/usr/share/opensearch/data networks: - app-network healthcheck: @@ -45,10 +48,11 @@ services: postgresql: container_name: temporal-postgresql image: postgres:14 + restart: unless-stopped environment: - POSTGRES_USER: temporal - POSTGRES_PASSWORD: temporal - POSTGRES_DB: temporal + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} ports: - 5432:5432 volumes: @@ -57,7 +61,7 @@ services: - app-network user: postgres healthcheck: - test: ["CMD-SHELL", "pg_isready -U temporal"] + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 5s timeout: 5s retries: 5 @@ -68,11 +72,14 @@ services: build: context: . dockerfile: Dockerfile.temporal + restart: unless-stopped depends_on: postgresql: condition: service_healthy - elasticsearch: + opensearch: condition: service_healthy + environment: + - ES_SEEDS=opensearch ports: - 7233:7233 networks: @@ -82,9 +89,10 @@ services: temporal-ui: container_name: temporal-ui image: temporalio/ui:2.10.3 + restart: unless-stopped depends_on: temporal: - condition: service_started + condition: service_healthy environment: - TEMPORAL_ADDRESS=temporal:7233 - TEMPORAL_PERMIT_WRITE_API=true @@ -100,12 +108,12 @@ volumes: type: none o: bind device: ${PWD}/volumes/n8n_data - elasticsearch-data: + opensearch-data: driver: local driver_opts: type: none o: bind - device: ${PWD}/volumes/elasticsearch-data + device: ${PWD}/volumes/opensearch-data postgresql-data: driver: local driver_opts: @@ -115,4 +123,4 @@ volumes: networks: app-network: - driver: bridge \ No newline at end of file + driver: bridge diff --git a/scripts/check_services.sh b/scripts/check_services.sh index e73ebc2..a67caa8 100755 --- a/scripts/check_services.sh +++ b/scripts/check_services.sh @@ -28,8 +28,8 @@ check_http_service "n8n" "http://localhost:5678/healthz" # Check temporal-ui check_http_service "temporal-ui" "http://localhost:8080" -# Check elasticsearch -check_http_service "elasticsearch" "http://localhost:9200" +# Check opensearch +check_http_service "opensearch" "http://localhost:9200" # Check temporal service echo -n "Checking temporal at localhost:7233... " @@ -50,4 +50,4 @@ fi echo -e "\nService URLs:" echo "- n8n: http://localhost:5678" echo "- Temporal UI: http://localhost:8080" -echo "- Elasticsearch: http://localhost:9200" \ No newline at end of file +echo "- OpenSearch: http://localhost:9200" \ No newline at end of file diff --git a/scripts/setup_volumes.sh b/scripts/setup_volumes.sh index f38ee37..01cbdd1 100755 --- a/scripts/setup_volumes.sh +++ b/scripts/setup_volumes.sh @@ -2,7 +2,7 @@ # Create volume directories for Docker Compose echo "Setting up volume directories..." -mkdir -p volumes/elasticsearch-data +mkdir -p volumes/opensearch-data mkdir -p volumes/postgresql-data mkdir -p volumes/n8n_data From 88e1414e54dc3ed50d23eb236adb36d59574407b Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Sun, 20 Apr 2025 20:02:53 +0200 Subject: [PATCH 12/16] Improve Docker configuration with parameterized builds and better healthchecks - Added .env.example file with configuration variables - Enhanced Dockerfiles with ARG variables for better customization - Updated healthchecks with improved parameters and container naming - Fixed OpenSearch port mapping to match documentation - Added missing healthcheck for temporal-ui service - Improved volume permissions in setup_volumes.sh script - Fixed README path reference to check_services.sh --- .env.example | 21 +++++++++++++++++++++ Dockerfile.n8n | 12 ++++++++---- Dockerfile.temporal | 19 ++++++++++++++----- README.md | 2 +- docker-compose.yml | 25 +++++++++++++++++++++---- scripts/setup_volumes.sh | 8 +++++++- 6 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d9aab8b --- /dev/null +++ b/.env.example @@ -0,0 +1,21 @@ +# PostgreSQL Configuration +POSTGRES_USER=temporal +POSTGRES_PASSWORD=temporal +POSTGRES_DB=temporal +POSTGRES_PORT=5432 + +# n8n Configuration +N8N_WEBHOOK_URL=http://localhost:5678/ +N8N_ENCRYPTION_KEY=a_random_string_for_encryption +N8N_PORT=5678 + +# OpenSearch Configuration +DISABLE_SECURITY_PLUGIN=true +OPENSEARCH_PORT=9200 + +# Temporal Configuration +TEMPORAL_PORT=7233 +TEMPORAL_UI_PORT=8080 + +# Volumes path (you can customize if needed) +PWD=. diff --git a/Dockerfile.n8n b/Dockerfile.n8n index 032d17f..9d4f126 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -1,8 +1,12 @@ FROM n8nio/n8n:1.89.2 +# Define build arguments +ARG N8N_PORT=5678 +ARG NODE_ENV=production + # Add custom environment variables -ENV N8N_PORT=5678 \ - NODE_ENV=production \ +ENV N8N_PORT=${N8N_PORT} \ + NODE_ENV=${NODE_ENV} \ N8N_METRICS=true \ N8N_HEALTH_CHECK_ENDPOINT=true @@ -10,8 +14,8 @@ ENV N8N_PORT=5678 \ WORKDIR /home/node # Add custom healthcheck using exec form -HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ - CMD ["/bin/sh", "-c", "curl -s http://localhost:${N8N_PORT}/healthz || exit 1"] +HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=30s \ + CMD ["/bin/sh", "-c", "wget -q --spider http://n8n:${N8N_PORT}/healthz || exit 1"] # Explicitly set the user to the non-root 'node' user (which is already set up in the base image) USER node diff --git a/Dockerfile.temporal b/Dockerfile.temporal index aa29bb2..cdf0c21 100644 --- a/Dockerfile.temporal +++ b/Dockerfile.temporal @@ -1,18 +1,27 @@ FROM temporalio/auto-setup:1.20.5 +# Define build arguments with defaults matching the .env file +ARG POSTGRES_USER=temporal +ARG POSTGRES_PASSWORD=temporal +ARG POSTGRES_DB=temporal +ARG DB_PORT=5432 +ARG POSTGRES_SEEDS=postgresql +ARG ES_SEEDS=opensearch +ARG ES_VERSION=v7 + # Set up environment variables for PostgreSQL and OpenSearch ENV DB=postgresql \ - DB_PORT=5432 \ + DB_PORT=${DB_PORT} \ POSTGRES_USER=${POSTGRES_USER} \ POSTGRES_PWD=${POSTGRES_PASSWORD} \ - POSTGRES_SEEDS=postgresql \ + POSTGRES_SEEDS=${POSTGRES_SEEDS} \ ENABLE_ES=true \ - ES_SEEDS=opensearch \ - ES_VERSION=v2 + ES_SEEDS=${ES_SEEDS} \ + ES_VERSION=${ES_VERSION} # Add custom healthcheck using exec form HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ - CMD ["/bin/sh", "-c", "temporal operator cluster health --address 0.0.0.0:7233 | grep -q SERVING || exit 1"] + CMD ["/bin/sh", "-c", "temporal operator cluster health --address temporal:7233 | grep -q SERVING || exit 1"] # Explicitly set the user to the non-root 'temporal' user (already defined in the base image) USER temporal diff --git a/README.md b/README.md index b4b7a46..4c3a61b 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ You should see containers for: Use the provided script to verify that all services are accessible: ```bash -./check_services.sh +scripts/check_services.sh ``` This will check: diff --git a/docker-compose.yml b/docker-compose.yml index 575e70b..149d76c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,18 @@ services: # n8n service n8n: + container_name: n8n build: context: . dockerfile: Dockerfile.n8n + args: + - N8N_PORT=5678 restart: unless-stopped ports: - "5678:5678" environment: - - WEBHOOK_URL=$N8N_WEBHOOK_URL - - N8N_ENCRYPTION_KEY=$N8N_ENCRYPTION_KEY + - WEBHOOK_URL=${N8N_WEBHOOK_URL} + - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} volumes: - n8n_data:/home/node/.n8n networks: @@ -28,7 +31,7 @@ services: - "DISABLE_SECURITY_PLUGIN=${DISABLE_SECURITY_PLUGIN}" - "DISABLE_INSTALL_DEMO_CONFIG=true" ports: - - 9201:9200 + - 9200:9200 cap_add: - IPC_LOCK ulimits: @@ -44,6 +47,7 @@ services: interval: 30s timeout: 10s retries: 5 + start_period: 30s postgresql: container_name: temporal-postgresql @@ -65,13 +69,19 @@ services: interval: 5s timeout: 5s retries: 5 - start_period: 10s + start_period: 30s temporal: container_name: temporal build: context: . dockerfile: Dockerfile.temporal + args: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + - ES_SEEDS=opensearch + - ES_VERSION=v7 restart: unless-stopped depends_on: postgresql: @@ -80,6 +90,7 @@ services: condition: service_healthy environment: - ES_SEEDS=opensearch + - ES_VERSION=v7 ports: - 7233:7233 networks: @@ -100,6 +111,12 @@ services: - 8080:8080 networks: - app-network + healthcheck: + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://localhost:8080"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s volumes: n8n_data: diff --git a/scripts/setup_volumes.sh b/scripts/setup_volumes.sh index 01cbdd1..c5c2c84 100755 --- a/scripts/setup_volumes.sh +++ b/scripts/setup_volumes.sh @@ -6,4 +6,10 @@ mkdir -p volumes/opensearch-data mkdir -p volumes/postgresql-data mkdir -p volumes/n8n_data -echo "Volume directories created successfully." \ No newline at end of file +# Set broader permissions to ensure Docker can access these directories +echo "Setting permissions for Docker access..." +chmod -R 777 volumes/opensearch-data +chmod -R 777 volumes/postgresql-data +chmod -R 777 volumes/n8n_data + +echo "Volume directories created successfully with Docker-accessible permissions." \ No newline at end of file From 4d2dbc81c81a6825d09b75b53fb5da0d462b50e0 Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Mon, 21 Apr 2025 14:57:45 +0200 Subject: [PATCH 13/16] Refactor Docker configuration to use environment variables from .env file - Modified dockerfiles to reduce hardcoded values and use environment variables - Updated docker-compose.yml to source ports and credentials from environment file - Enhanced check_services.sh to read from .env instead of using hardcoded values - Improved README.md with instructions for environment file setup - Fixed container health checks to use the correct service addresses --- Dockerfile.n8n | 11 +++-------- Dockerfile.temporal | 26 +++++++------------------- README.md | 11 ++++++++++- docker-compose.yml | 39 ++++++++++++++++++++++++--------------- scripts/check_services.sh | 28 ++++++++++++++++++---------- 5 files changed, 62 insertions(+), 53 deletions(-) diff --git a/Dockerfile.n8n b/Dockerfile.n8n index 9d4f126..d612090 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -1,24 +1,19 @@ FROM n8nio/n8n:1.89.2 # Define build arguments -ARG N8N_PORT=5678 ARG NODE_ENV=production - -# Add custom environment variables -ENV N8N_PORT=${N8N_PORT} \ - NODE_ENV=${NODE_ENV} \ - N8N_METRICS=true \ - N8N_HEALTH_CHECK_ENDPOINT=true +# Environment variables are now defined in docker-compose.yml # Create app directory WORKDIR /home/node # Add custom healthcheck using exec form HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=30s \ - CMD ["/bin/sh", "-c", "wget -q --spider http://n8n:${N8N_PORT}/healthz || exit 1"] + CMD ["/bin/sh", "-c", "wget -q --spider http://0.0.0.0:${N8N_PORT}/healthz || exit 1"] # Explicitly set the user to the non-root 'node' user (which is already set up in the base image) USER node +EXPOSE ${N8N_PORT} # The entrypoint script is already defined in the base image # Don't override the CMD diff --git a/Dockerfile.temporal b/Dockerfile.temporal index cdf0c21..0b87324 100644 --- a/Dockerfile.temporal +++ b/Dockerfile.temporal @@ -1,32 +1,20 @@ FROM temporalio/auto-setup:1.20.5 -# Define build arguments with defaults matching the .env file -ARG POSTGRES_USER=temporal -ARG POSTGRES_PASSWORD=temporal -ARG POSTGRES_DB=temporal -ARG DB_PORT=5432 -ARG POSTGRES_SEEDS=postgresql -ARG ES_SEEDS=opensearch -ARG ES_VERSION=v7 +# Build arguments are still needed for the temporal container setup +# Keeping only those used in the HEALTHCHECK or other commands +ARG HOST=temporal +ARG TEMPORAL_PORT=7233 -# Set up environment variables for PostgreSQL and OpenSearch -ENV DB=postgresql \ - DB_PORT=${DB_PORT} \ - POSTGRES_USER=${POSTGRES_USER} \ - POSTGRES_PWD=${POSTGRES_PASSWORD} \ - POSTGRES_SEEDS=${POSTGRES_SEEDS} \ - ENABLE_ES=true \ - ES_SEEDS=${ES_SEEDS} \ - ES_VERSION=${ES_VERSION} +# Environment variables are now defined in docker-compose.yml # Add custom healthcheck using exec form HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ - CMD ["/bin/sh", "-c", "temporal operator cluster health --address temporal:7233 | grep -q SERVING || exit 1"] + CMD ["/bin/sh", "-c", "temporal operator cluster health --address ${HOST}:${TEMPORAL_PORT} | grep -q SERVING || exit 1"] # Explicitly set the user to the non-root 'temporal' user (already defined in the base image) USER temporal # Expose the gRPC port -EXPOSE 7233 +EXPOSE ${TEMPORAL_PORT} # The entrypoint script is already defined in the base image diff --git a/README.md b/README.md index 4c3a61b..67b0ceb 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,21 @@ This project uses custom Docker images built from the following Dockerfiles: Before starting the services, run the setup script to create the necessary volume directories: ```bash -chmod +x scripts/setup_volumes.sh ./scripts/setup_volumes.sh ``` This prevents volume mount errors that may occur if the directories don't exist. +### Create environment file + +Create a `.env` file in the root directory of the project with your environment variables: + +```bash +cp .env.example .env +``` + +Then edit the `.env` file to set your specific configuration values. + ### Starting the services ```bash diff --git a/docker-compose.yml b/docker-compose.yml index 149d76c..d3e1cdb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,14 +5,18 @@ services: build: context: . dockerfile: Dockerfile.n8n - args: - - N8N_PORT=5678 restart: unless-stopped ports: - - "5678:5678" + - "${N8N_PORT}:5678" environment: - WEBHOOK_URL=${N8N_WEBHOOK_URL} - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} + - "N8N_RUNNERS_ENABLED=true" + - "N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true" + - "N8N_PORT=5678" + - "NODE_ENV=production" + - "N8N_METRICS=true" + - "N8N_HEALTH_CHECK_ENDPOINT=true" volumes: - n8n_data:/home/node/.n8n networks: @@ -31,7 +35,7 @@ services: - "DISABLE_SECURITY_PLUGIN=${DISABLE_SECURITY_PLUGIN}" - "DISABLE_INSTALL_DEMO_CONFIG=true" ports: - - 9200:9200 + - ${OPENSEARCH_PORT}:9200 cap_add: - IPC_LOCK ulimits: @@ -43,7 +47,7 @@ services: networks: - app-network healthcheck: - test: ["CMD-SHELL", "curl -sSf http://localhost:9200/ || exit 1"] + test: ["CMD-SHELL", "curl -sSf http://localhost:${OPENSEARCH_PORT}/ || exit 1"] interval: 30s timeout: 10s retries: 5 @@ -58,7 +62,7 @@ services: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} ports: - - 5432:5432 + - ${POSTGRES_PORT}:5432 volumes: - postgresql-data:/var/lib/postgresql/data networks: @@ -77,11 +81,8 @@ services: context: . dockerfile: Dockerfile.temporal args: - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_DB=${POSTGRES_DB} - - ES_SEEDS=opensearch - - ES_VERSION=v7 + - HOST=temporal + - TEMPORAL_PORT=${TEMPORAL_PORT} restart: unless-stopped depends_on: postgresql: @@ -91,8 +92,16 @@ services: environment: - 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=7233 ports: - - 7233:7233 + - ${TEMPORAL_PORT}:7233 networks: - app-network user: temporal @@ -105,14 +114,14 @@ services: temporal: condition: service_healthy environment: - - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_ADDRESS=temporal:${TEMPORAL_PORT} - TEMPORAL_PERMIT_WRITE_API=true ports: - - 8080:8080 + - ${TEMPORAL_UI_PORT}:8080 networks: - app-network healthcheck: - test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://localhost:8080"] + test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://temporal-ui:${TEMPORAL_UI_PORT}"] interval: 10s timeout: 5s retries: 5 diff --git a/scripts/check_services.sh b/scripts/check_services.sh index a67caa8..69e95e2 100755 --- a/scripts/check_services.sh +++ b/scripts/check_services.sh @@ -1,5 +1,13 @@ #!/bin/bash +# Source environment variables from .env file +if [ -f .env ]; then + source .env +else + echo "Error: .env file not found. Please make sure it exists in the root directory." + exit 1 +fi + echo "Checking service availability..." # Check if docker-compose is running @@ -23,31 +31,31 @@ check_http_service() { } # Check n8n -check_http_service "n8n" "http://localhost:5678/healthz" +check_http_service "n8n" "http://localhost:${N8N_PORT}/healthz" # Check temporal-ui -check_http_service "temporal-ui" "http://localhost:8080" +check_http_service "temporal-ui" "http://localhost:${TEMPORAL_UI_PORT}" # Check opensearch -check_http_service "opensearch" "http://localhost:9200" +check_http_service "opensearch" "http://localhost:${OPENSEARCH_PORT}" # Check temporal service -echo -n "Checking temporal at localhost:7233... " -if nc -z localhost 7233 >/dev/null 2>&1; then +echo -n "Checking temporal at localhost:${TEMPORAL_PORT}... " +if nc -z localhost ${TEMPORAL_PORT} >/dev/null 2>&1; then echo "ACCESSIBLE ✅" else echo "NOT ACCESSIBLE ❌" fi # Check PostgreSQL -echo -n "Checking postgresql at localhost:5432... " -if docker compose exec postgresql pg_isready -h localhost -p 5432 -U temporal >/dev/null 2>&1; then +echo -n "Checking postgresql at localhost:${POSTGRES_PORT}... " +if docker compose exec postgresql pg_isready -h localhost -p ${POSTGRES_PORT} -U ${POSTGRES_USER} >/dev/null 2>&1; then echo "ACCESSIBLE ✅" else echo "NOT ACCESSIBLE ❌" fi echo -e "\nService URLs:" -echo "- n8n: http://localhost:5678" -echo "- Temporal UI: http://localhost:8080" -echo "- OpenSearch: http://localhost:9200" \ No newline at end of file +echo "- n8n: http://localhost:${N8N_PORT}" +echo "- Temporal UI: http://localhost:${TEMPORAL_UI_PORT}" +echo "- OpenSearch: http://localhost:${OPENSEARCH_PORT}" \ No newline at end of file From 02169cbb930c95de1691c6b3c0793e4fac407ef9 Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Mon, 21 Apr 2025 15:12:05 +0200 Subject: [PATCH 14/16] Add environment file copy step to GitHub workflow - Add step to copy .env.example to .env in code-quality workflow - Ensure environment configuration is available for Docker build process --- .github/workflows/code-quality.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 50bb6da..58d8f92 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -50,6 +50,8 @@ jobs: uses: actions/checkout@v4 - name: Create volume directories run: bash scripts/setup_volumes.sh + - name: Copy .env file + run: cp .env.example .env - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build services with no cache From 737eb62a345279b3dea9d09071ac94f2ef81d52f Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Mon, 21 Apr 2025 16:11:42 +0200 Subject: [PATCH 15/16] Add N8N_PORT build argument to Dockerfile - Add ARG N8N_PORT=5678 to properly define the port used in healthcheck and EXPOSE --- Dockerfile.n8n | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile.n8n b/Dockerfile.n8n index d612090..08eddb2 100644 --- a/Dockerfile.n8n +++ b/Dockerfile.n8n @@ -2,6 +2,7 @@ FROM n8nio/n8n:1.89.2 # Define build arguments ARG NODE_ENV=production +ARG N8N_PORT=5678 # Environment variables are now defined in docker-compose.yml # Create app directory From ce49d6ed82d01bcb8f6cf02a56c93941d88a285d Mon Sep 17 00:00:00 2001 From: Peter Ovchyn Date: Mon, 21 Apr 2025 17:31:54 +0200 Subject: [PATCH 16/16] Update README.md with improved documentation formatting - Simplify Docker rebuild instructions for better readability - Fix code block formatting by specifying text language - Format service URLs as proper markdown links with angle brackets --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 67b0ceb..c243a71 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ This will start all services in detached mode. ### Building custom images -If you've made changes to the Dockerfiles, you'll need to rebuild the images: +Rebuild images after modifying the Dockerfiles: ```bash docker compose build @@ -95,7 +95,7 @@ This will check: - PostgreSQL database connection Example output: -``` +```text Checking service availability... Checking n8n at http://localhost:5678/healthz... ACCESSIBLE ✅ (HTTP 200) Checking temporal-ui at http://localhost:8080... ACCESSIBLE ✅ (HTTP 200) @@ -111,8 +111,8 @@ Service URLs: ### Accessing the services -- **n8n**: http://localhost:5678 -- **Temporal UI**: http://localhost:8080 +- **n8n**: +- **Temporal UI**: You can verify the services are responding with: