1

I'm trying to build a multi-container environment, with a client,server,worker & nginx directories and I'm getting this error:

nginx_1     | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
nginx_1     | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx_1     | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx_1     | 2021/01/01 19:48:26 [emerg] 1#1: host not found in upstream "client:3000" in /etc/nginx/conf.d/default.conf:2
nginx_1     | nginx: [emerg] host not found in upstream "client:3000" in /etc/nginx/conf.d/default.conf:2

Why it can't find my react service running on 3000 in my latest check the default port has not been changed

Architecture

  • Client: React project listens on default port 3000
  • Server: The API server listens on port 5000
  • Worker: functions in a js file
  • Nginx: contains the default.conf and Dockerfile.dev (Dockerfile.dev is not omitted in the previous directories)
  • Some more backend services

Nginx

This is my configuration where i try to forward requests from / to client and from /api to the server

default.conf

upstream client {
    server client:3000;
}

upstream api {
    server api:5000;
}

server {
    listen 80;

    location / {
        proxy_pass http://client;
    }

    locatoin /api {
        rewrite /api/(.*) /$1 break;
        proxy_pass http://api;
    }
}

docker-composer.yml

version: '3'
services:
  nginx:
    restart: always
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - '8081:80'

Dockerfile.dev

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf
Phill Alexakis
  • 1,449
  • 1
  • 12
  • 31

1 Answers1

0

I recommend you check this:

How to connect API with React App through docker

A quickly answer to your question:

Why it can't find my react service running on 3000 in my latest check the default port has not been changed

Your nginx configuration is not able to determine the real ip. Instead of this, is using client or api strings:

host not found in upstream client:3000 in /etc/nginx/conf.d/default.conf:2

Quickly and not recommend solution

If you are using docker-compose, all of your apps will run in the same host, so the ip is the same for all of them.

You need to hardcode the ip of this host in your default.conf

upstream client {
    server 10.10.10.50:3000;
}

upstream api {
    server 10.10.10.50:5000;
}

Dynamic nginx

According to these links, Nginx by default don't support variables

In order to avoid the hardcoded ip in default.conf you need to use some tool like ansible or create some script to replace a placeholder in your default.conf

upstream client {
    server #IP:3000;
}

upstream api {
    server #IP:5000;
}

bash script:

sed -i "s/#IP/$MY_IP/g" /etc/nginx/conf.d/default.conf

docker-composer.yml

version: '3'
services:
  nginx:
    restart: always
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - '8081:80'
    environment:
      MY_IP: ${MY_IP}

Here you need to create a custom nginx Dockerfile which is able to execute the script to replace the ip or use this

Finally just run:

export MY_IP=10.10.10.50
docker-compose up -d ...

docker-compose = development

Docker compose in my opinion is jut for development, stagging or testing phase, not for production

In production each app must be in a isolated host:

  • nginx
  • api
  • web

In this case, each app must have a different ip, so your nginx must be able to handled them.

In prod you could use another tools to create dynamic nginx configuration files

  • ansible

Or more advanced loadbalancers

  • AWS Elastic Load Balancing.
  • Traefik
  • LiteSpeed
  • etc
JRichardsz
  • 14,356
  • 6
  • 59
  • 94
  • Thank you for the post, the truth is i'd like to avoid hardcoded IP's. I'm planning to deploy it to AWS Elastic Beanstack in production mode through Travis. I'll look into the script although I already have a `Dockerfle.dev` for `Nginx` – Phill Alexakis Jan 02 '21 at 07:10