Search code examples
dockernginxdocker-composeload-balancing

Nginx Not Redirecting to Local Instances


When I access localhost:8080/, it displays the nginx default page; it should redirect to my instances. I want any request to localhost:8080/ to redirect to my instances.

My configurations:

docker-compose.yml:

version: '3'
services:
  golang-instance:
    image: "myapi"
    ports:
      - "5000:5000"
    networks:
      - nginx_net
    restart: on-failure

  golang-instance-2:
    image: "myapi"
    ports:
      - "5001:5000"
    networks:
      - nginx_net
    restart: on-failure

  nginx:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/nginx.conf
    networks:
      - nginx_net
    restart: on-failure

networks:
  nginx_net:

nginx.conf:

upstream backend {
    least_conn;
    server golang-instance:5000;
    server golang-instance-2:5000;
}

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://backend;
    }
}

When I access localhost:8080/hello, it should display "Hello World" because that's what my instances return. In fact, if I access localhost:5000/hello or localhost:5001/hello, both correct display "Hello World". However, what I'm getting in the browser is the nginx 404 page with the message "404 Not Found." The log in the container:

2023-09-30T18:32:28.873946632Z 172.20.0.1 - - [30/Sep/2023:18:32:28 +0000] "GET /hello HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" "-"

I tried removing least_conn, i tried setting port 8080 in the listen directive, and port 5001 in golang-instance-2 from my nginx.conf file, as these are the ports running on my machine. However, it didn't change the result.

I also changed the configuration of my network to the following:

networks:
  nginx_net:
    driver: bridge

And it didn't change anything; all these attempts didn't yield any different results.

I tried changing the volumes in my docker-compose:

#option-1
volumes:
  - ./nginx.conf:/etc/nginx/nginx.conf

#option-2
volumes:
  - ./nginx.conf:/etc/nginx/conf.d/nginx.conf

#option-3
volumes:
  - ./nginx.conf:/etc/nginx/http.d/nginx.conf

With option-3, the container doesn't start; it gives an error:

2023/09/30 18:14:48 [emerg] 1#1: "upstream" directive is not allowed here in /etc/nginx/nginx.conf:1 2023-09-30T18:14:48.131910502Z nginx: [emerg] "upstream" directive is not allowed here in /etc/nginx/nginx.conf:1

But with option-1 and option-2, the container starts normally with the following log:

o log /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration 2023-09-30T17:40:27.718888715Z /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ 2023-09-30T17:40:27.720393590Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 2023-09-30T17:40:27.724760049Z 10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled 2023-09-30T17:40:27.724773299Z /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh 2023-09-30T17:40:27.725033174Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh 2023-09-30T17:40:27.731775465Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh 2023-09-30T17:40:27.736814424Z /docker-entrypoint.sh: Configuration complete; ready for start up 2023-09-30T17:40:27.759872299Z 2023/09/30 17:40:27 [warn] 1#1: conflicting server name "localhost" on 0.0.0.0:80, ignored 2023-09-30T17:40:27.759900590Z nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored 2023-09-30T17:40:27.760202507Z 2023/09/30 17:40:27 [notice] 1#1: using the "epoll" event method 2023-09-30T17:40:27.760207549Z 2023/09/30 17:40:27 [notice] 1#1: nginx/1.25.2 2023-09-30T17:40:27.760209590Z 2023/09/30 17:40:27 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2023-09-30T17:40:27.760211382Z 2023/09/30 17:40:27 [notice] 1#1: OS: Linux 5.15.49-linuxkit 2023-09-30T17:40:27.760213090Z 2023/09/30 17:40:27 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2023-09-30T17:40:27.761007132Z 2023/09/30 17:40:27 [notice] 1#1: start worker processes 2023-09-30T17:40:27.761015632Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 22 2023-09-30T17:40:27.764749424Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 23 2023-09-30T17:40:27.764774007Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 24 2023-09-30T17:40:27.764776340Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 25

Nevertheless, even with option-1 and option-2, Nginx still doesn't redirect to the instances. I even made sure that these volumes were correctly mapped. I entered the container, navigated to the directory, and confirmed that the nginx.conf file was as I specified.

I'm quite stuck at the moment and not sure what else to try. Any insights or suggestions on how to troubleshoot this issue further would be greatly appreciated.


Solution

  • I managed to make it work; I needed to make the following changes to get it working:

    In the docker-compose.yml, the change I made was in the volumes section.

    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    

    And the nginx.conf has changed completely; it now looks like this:

    events {
    }
    
    http {
        upstream instances {
            least_conn;
            server golang-instance:5000;
            server golang-instance-2:5000;
        }
        server {
            listen 80;
            location / {
                proxy_pass http://instances;
            }
        }
    }