Vic
Vic

Reputation: 2055

Docker Compose with NGINX proxy pass thru not working

Following is my Docker Compose file & NGINX conf file.

The application seems to work and NGINX is also up, but the proxy_pass setting doesn't seem to work properly.

File docker-compose.yaml


networks:
  webapp:

services:
 
  web:
    image: nginx
    volumes:
      - ./data/ntemplates:/etc/nginx/templates
      - ./webapp.conf:/etc/nginx/conf.d/webapp.conf
    ports:
      - "8080:80"
    networks:
      - webapp

  pyweb:
    build: .
    ports:
      - "5000:5000"
    networks:
      - webapp

  redis:
    image: "redis:alpine"
    networks:
      - webapp

File webapp.conf

server { 
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
       proxy_pass "http://pyweb_1:5000/";
    }

    #error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;

}

Service pyweb is working if properly if directly accessed by http://pyweb_1:5000

I created this app based on docker getting started page For completeness below are other files and seems to be working just fine.

File Dockerfile

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

File requirement.txt

flask
redis

File app.py

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

Upvotes: 2

Views: 2183

Answers (1)

Stefano
Stefano

Reputation: 5076

EDIT:

You're currently not using the nginx configuration. I didn't read carefully your docker-compose file. You can fix it by mapping the webapp.conf on /etc/nginx/conf.d/default.conf. e.g.

services:
 
  web:
    image: nginx
    volumes:
      - ./data/ntemplates:/etc/nginx/templates
      - ./webapp.conf:/etc/nginx/conf.d/default.conf
    ports:
      - "8080:80"
    depends_on:
      - pyweb
    networks:
      - webapp

There are 2 issues:

  • you don't know what container name will be used by docker-compose
  • you don't know the order used to start the containers

docker-compose allows you to solve the first issue in 2 ways:

  • define a container_name subsection
  • use the service name

This means that you can simply use proxy_pass "http://pyweb:5000/"; in your nginx setup

The second issue can be fixed by adding a depends_on subsection in the nginx service. e.g.

services:
 
  web:
    image: nginx
    volumes:
      - ./data/ntemplates:/etc/nginx/templates
      - ./webapp.conf:/etc/nginx/conf.d/webapp.conf
    depends_on:
      - pyweb
    ports:
      - "8080:80"
    networks:
      - webapp

Nevertheless, the depends_on might not be enough since it does not check the service status but it only make sure that the docker service is started (as stated in the documentation).

You'll need to find another way to monitor if the service is actually started.

Upvotes: 4

Related Questions