1

I have a MarkLogic cluster set up in docker and I wanted to add nginx as a load balancer so I can access all hosts on the same ports. The basic configuration doesn't work, when I try to access http://localhost:8001 for example, nginx logs an error

172.19.0.1 - - [09/Sep/2025:08:30:17 +0000] "GET / HTTP/1.1" 502 559 "http://localhost:8001/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" 2025/09/09 08:30:17 [error] 62#62: *6 no resolver defined to resolve cluster_m, client: 172.19.0.1, server: , request: "GET / HTTP/1.1", host: "localhost:8001", referrer: "http://localhost:8001/" 

What am I missing here? Attached the nginx.conf and a docker-compose.yaml. Any help greately appreciated.

nginx version: nginx/1.29.1

events {} http { upstream cluster_m { resolver 127.0.0.11; server bootstrap_3n; server node2; server node3; } server { listen 7997-8074; location / { proxy_set_header Host $host; proxy_pass http://cluster_m:$server_port; } } } 
name: marklogic-cluster services: nginx: image: nginx container_name: nginx volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro ports: - 7197:7997 - 8000-8010:8000-8010 - 8020-8074:8020-8074 depends_on: - bootstrap_3n networks: - external_net bootstrap_3n: image: progressofficial/marklogic-db:latest-11 container_name: bootstrap_3n hostname: bootstrap_3n dns_search: "" environment: - MARKLOGIC_INIT=true - MARKLOGIC_ADMIN_USERNAME_FILE=mldb_admin_username - MARKLOGIC_ADMIN_PASSWORD_FILE=mldb_admin_password - TZ=Europe/Prague volumes: - MarkLogic_3n_vol1:/var/opt/MarkLogic secrets: - mldb_admin_password - mldb_admin_username networks: - external_net node2: image: progressofficial/marklogic-db:latest-11 container_name: node2 hostname: node2 dns_search: "" environment: - MARKLOGIC_INIT=true - MARKLOGIC_ADMIN_USERNAME_FILE=mldb_admin_username - MARKLOGIC_ADMIN_PASSWORD_FILE=mldb_admin_password - MARKLOGIC_JOIN_CLUSTER=true - MARKLOGIC_BOOTSTRAP_HOST=bootstrap_3n - TZ=Europe/Prague volumes: - MarkLogic_3n_vol2:/var/opt/MarkLogic secrets: - mldb_admin_password - mldb_admin_username depends_on: - bootstrap_3n networks: - external_net node3: image: progressofficial/marklogic-db:latest-11 container_name: node3 hostname: node3 dns_search: "" environment: - MARKLOGIC_INIT=true - MARKLOGIC_ADMIN_USERNAME_FILE=mldb_admin_username - MARKLOGIC_ADMIN_PASSWORD_FILE=mldb_admin_password - MARKLOGIC_JOIN_CLUSTER=true - MARKLOGIC_BOOTSTRAP_HOST=bootstrap_3n - TZ=Europe/Prague volumes: - MarkLogic_3n_vol3:/var/opt/MarkLogic secrets: - mldb_admin_password - mldb_admin_username depends_on: - bootstrap_3n networks: - external_net secrets: mldb_admin_password: file: ./mldb_admin_password.txt mldb_admin_username: file: ./mldb_admin_username.txt networks: external_net: {} volumes: MarkLogic_3n_vol1: MarkLogic_3n_vol2: MarkLogic_3n_vol3: 

I tried adding the resolver in server and location blocks set to 127.0.0.1 and 127.0.0.11 but it didn't work.

3
  • Port is a part of upstream's servers (server node2 in your config is actually server node2:80). You cannot use upstream + port in proxy_pass. Commented Sep 9 at 10:08
  • Docs say that port is optional for proxy pass nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass I changed upstrea/server entires like so server bootstrap_3n:8000;server bootstrap_3n:8001; server bootstrap_3n:8002; but it still can't find the upstream name. Commented Sep 9 at 11:45
  • nginx.org/en/docs/http/ngx_http_upstream_module.html#server If a port is not specified, the port 80 is used Commented Sep 9 at 12:05

1 Answer 1

0

Looks like it's not possible to do it the way I wanted. So I came up with a solution. I defined an upstream for each port and luckily the $server_port variable can be used in the proxy_pass instruction like that proxy_pass http://cluster_$server_port;. With envsubst I generated the upstream configs for each port from a range and then included them with include nginx-config/config_*.conf; in the nginx.conf.

Final compose and config files look like that:

 nginx: image: nginx container_name: nginx volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx-config:/etc/nginx/nginx-config:ro ports: - 8000-8074:8000-8074 depends_on: - bootstrap_3n networks: - external_net 
events { worker_connections 1024; } http { proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-NginX-Proxy true; include nginx-config/config_*.conf; server { listen 8000-8074; location / { proxy_pass http://cluster_$server_port; } } } 

The template I used and shell script to generate upstream configs:

 upstream cluster_${INT} { resolver 127.0.0.11; server bootstrap_3n:${INT}; server node2:${INT}; server node3:${INT}; } 

script

#!/bin/bash for INT in {8000..8074}; do export INT envsubst < "int.conf.template" > "config_$INT.conf" done 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.