4

NGINX Doesn't communicate with flask rest API. When I hit localhost/api If i hit localhost i get the message from the index.html but not json response when i hit /api

I want to use NGINX to serve my Angular 5 dist folder.

What is dist?

dist is the folder were I have my index.html, main.css, and all the others files that Angular 5 creates for me after I run ng build --prod

What is my problem?

  • I want to have Angular 5 for the front-end
  • I want my flask to be my rest api
  • And I want nginx to serve all the static files (HTML, CSS, and javascript)

I want the user if is type in the URL (http://localhost) the NGINX to give him all the static files and let my SPA application to desite for the ROUTES Except for the API routes

If the user types (http://localhost/api) I want the FLASK to take the control and give the user JSON response whatever I say the flask to response

My problem is when the user hits ## /api I get 404 page not found WTF I have set inside nginx if is get /api to let the flask to take action look:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
  worker_connections  1024;
}



http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

  access_log  /var/log/nginx/access.log  main;

  sendfile        on;
  #tcp_nopush     on;

  keepalive_timeout  65;

  gzip  on;

  include /etc/nginx/conf.d/*.conf;


  # Configuration for the server
  server {

    listen 80;
    server_name localhost;

    location / {
      root   /usr/share/nginx/html;
      index  index.html;
      expires -1;
      add_header Pragma "no-cache";
      add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
      try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
      proxy_pass  http://localhost:5000/;
    }

    # location /api {
    #   proxy_pass          http://flask_api:5000;
    #   proxy_set_header        Host $host;
    # }

    }



}

I have a docker-compose file that looks like this:

docker-compose.yml

version: '3'

services:

  nginx_demo:
    image: nginx:1.13.7-alpine
    container_name: nginx
    restart: always
    build:
      context: .
      dockerfile: nginx/Dockerfile
    volumes:
     - ./Client/dist:/usr/share/nginx/html
    ports:
      - "80:80"
    depends_on:
      - flask_api

  flask_api:
    # image: flask
    container_name: flask_api
    restart: always
    build: ./Server
    volumes:
      - ./Server:/usr/src/app
    ports:
      - "5000:80"

this is inside Server/api.py

''' Docker + python 3.6.3 '''

from flask import Flask

app = Flask(__name__)

@app.route('/api')
def hello():
    return 'Hello Form Flask'

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

this is my logs after I run docker-compose up

Creating flask_api ...
Creating flask_api ... done
Creating nginx ...
Creating nginx ... done
Attaching to flask_api, nginx
flask_api     |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
flask_api     |  * Restarting with stat
flask_api     |  * Debugger is active!
flask_api     |  * Debugger PIN: 718-970-762
nginx         | 172.20.0.1 - - [10/Dec/2017:14:16:53 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" "-"
nginx         | 172.20.0.1 - - [10/Dec/2017:14:16:55 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" "-"
nginx         | 172.20.0.1 - - [10/Dec/2017:14:16:56 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" "-"
nginx         | 2017/12/10 14:16:59 [error] 5#5: *2 open() "/usr/share/nginx/html/api" failed (2: No such file or directory), client: 172.20.0.1, server: localhost, request: "GET /api HTTP/1.1", host: "localhost"
nginx         | 172.20.0.1 - - [10/Dec/2017:14:16:59 +0000] "GET /api HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" "-"
nginx         | 172.20.0.1 - - [10/Dec/2017:14:17:01 +0000] "GET /api HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" "-"
nginx         | 2017/12/10 14:17:01 [error] 5#5: *2 open() "/usr/share/nginx/html/api" failed (2: No such file or directory), client: 172.20.0.1, server: localhost, request: "GET /api HTTP/1.1", host: "localhost"
nginx         | 2017/12/10 14:17:02 [error] 5#5: *2 open() "/usr/share/nginx/html/api" failed (2: No such file or directory), client: 172.20.0.1, server: localhost, request: "GET /api HTTP/1.1", host: "localhost"
nginx         | 172.20.0.1 - - [10/Dec/2017:14:17:02 +0000] "GET /api HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" "-"
6
  • In the docker-compose.yml you are publishing the the wrong port. Also consider using links to specify the host for nginx. Take a look at it here: docs.docker.com/compose/compose-file/#links Commented Dec 10, 2017 at 14:43
  • Thank you @ Ehsan in the docker documentation they don't say anything about NGINX and Flask .only flask and REDIS. What port should i use Commented Dec 10, 2017 at 14:45
  • You have mapped the ports from both containers to 80 on the host machine. Change the published port for flask_api to "5000:5000", because that's where nginx is expecting to connect. Commented Dec 10, 2017 at 14:48
  • Also proxy_pass http://localhost:5000/; in nginx config is wrong, bacause it is referring to the nginx container itself. You should specify flask_api in a links section for nginx_demo in your docker-compose file and then you can refer to the address of flask app with flask_api. Commented Dec 10, 2017 at 14:53
  • not is not working I gonna post all my code can you please take a look what is my problem give me 5 minutes please Commented Dec 10, 2017 at 14:58

1 Answer 1

3

This should work:

docker-compose.yml

# Run docker-compose up

version: '3'

services:
  nginx_demo:
    image: nginx:1.13.7-alpine
    container_name: nginx
    restart: always
    build:
      context: .
      dockerfile: ./Nginx/Dockerfile
    volumes:
      - ./Client/dist:/usr/share/nginx/html
    ports:
      - "80:80"
    depends_on:
      - flask_api
    links:
      - flask_api

  flask_api:
    container_name: flask_api
    restart: always
    build:
      context: .
      dockerfile: ./Server/Dockerfile
    volumes:
      - ./Server:/usr/src/app

Nginx/Dockerfile

FROM nginx:1.13.7-alpine

# remove the old nginx.conf
RUN rm /etc/nginx/nginx.conf

# Copy custom nginx config
COPY ./Nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./Client/dist /usr/share/nginx/html

EXPOSE 80

Server/Dockerfile

FROM python:3.6-alpine

ADD ./Server /app
WORKDIR /app
RUN pip install -r requirements.txt

EXPOSE 5000
CMD ["python", "api.py"]

Nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
  worker_connections  1024;
}


http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

  access_log  /var/log/nginx/access.log  main;

  sendfile    on;

  keepalive_timeout  65;

  gzip  on;

  # Configuration for the server
  server {

    listen 80;

    location /api {
      proxy_pass http://flask_api:5000;
    }

    location / {
      root   /usr/share/nginx/html;
      index  index.html;
      expires -1;
      add_header Pragma "no-cache";
      add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
      try_files $uri$args $uri$args/ $uri $uri/ =404;
    }

  }

}
Sign up to request clarification or add additional context in comments.

2 Comments

Works perfectly :)
Sir, is there an article that guides you through the proper use of Nginx and docker using Python Flask?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.