Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to NGINX Reverse Proxy outside of Docker to proxy_pass to docker containers

I have an NGINX running on a CentOS server and would like to proxy_pass to running docker containers running on the same host.

When using proxy_pass with the IP of container it works, however if machine gets rebooted sometimes the IP changes of the container and have to manually edit the nginx.conf to re-point to new ip of Container. I know that NGINX can be setup inside of its own docker container and linked to other running containers but that would take a long time to setup and test.

Is there a way to use somehow container name or another identifier that does not change directly on the host's NGINX?

like image 398
Val Avatar asked Oct 15 '18 19:10

Val


2 Answers

I know that NGINX can be setup inside of its own docker container and linked to other running containers but that would take a long time to setup and test.

Short answer

If you don't want to run nginx in it's own container, you can create a docker network with a fixed IP range:

docker network create --driver=bridge --subnet=192.168.100.0/24 nginx.docker

And start your container with a fixed IP

docker run --net nginx.docker --ip 192.168.100.1 ...

See docker network create and Assign static IP to Docker container

Long answer

But I would still suggest to run nginx in a container as well, then docker will take care of the DNS resolution and routing. It's actually quickly done and pretty straight forward. You can either define all services in one docker-compose.yml and make sure they all share the same network or:

  1. Create a docker network with docker network create nginx.docker
  2. Add the network to the docker-compose.yml files of your services
  3. Adjust your nginx.conf

For example:

nginx

The docker-compose.yml of nginx

services:
nginx:
  image: nginx:alpine
  container_name: nginx
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - type: bind
      source: ./nginx.conf
      target: /etc/nginx/nginx.conf
  networks:
    - nginx.docker

networks:
  nginx.docker:
    name: nginx.docker
    external: true

Note that "80:80" will bind to all interfaces, use the IP of an interface, e.g. "192.168.0.1:80:80" to bind to one specific interface only.

Your service container

docker-compose.yml

services:
my_service:
  image: image_name
  container_name: myservice
  networks:
    - nginx.docker

networks:
  nginx.docker:
    name: nginx.docker
    external: true

nginx config

An in the server section of your nginx.conf:

server {
listen 443 ssl;
server_name your.server.name;

# Docker DNS
resolver 127.0.0.11;
set $upstream_server http://myservice:8080;          # or myservice.nginx.docker

  location  / {
     proxy_pass $upstream_server;

     # further proxy config ...
  }
}

Note the resolver 127.0.0.11 explicitly telling nginx to use the docker DNS. Not sure if it is still needed, but I had problems before, when not using it.

like image 65
hjsimpson Avatar answered Nov 01 '22 11:11

hjsimpson


There is no need to create a network. It is possible to use default one. Default bridge network has gateway on 172.17.0.1. You can use this IP address in your nginx.conf

server {
    listen 80;
    server_name example.com;

    location /{
        proxy_pass  http://172.17.0.1:81;
    }
}

You can check your bridge gateway IP address by running command docker network inspect bridge

like image 34
Black Avatar answered Nov 01 '22 13:11

Black