[PYTHON] Nginx setting summary (Flask + Docker + Gunicorn edition)

I used Nginx for web app development in Flask + docker-compose. I have extracted and summarized the points of Nginx at that time, especially the configuration file: thumbs up_tone3:

The parent's article is here. ■ I made a game WebApp with Flask + Docker + Vue.js + AWS ...

■ The source code is available on Github

Good compatibility with Gunicorn

Gunicorn ** recommends using Nginx on its official page **. https://docs.gunicorn.org/en/stable/deploy.html

Since Nginx is buffered by default, it is not easily affected by slow clients and seems to be able to handle Gunicorn workers efficiently. Especially effective when the number of workers (number of sessions) is limited. By the way, the Apache server doesn't buffer requests. Unless you have a specific reason, Nginx is a good choice if you choose Gunicorn for WSGI.

Precautions when running with Docker

Let's start with foreground. The following is the command part of the Dockerfile.


CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]

docker will stop the container if you don't run the command in the foreground. Since nginx runs as a daemon, it needs to be set with deamon off to work in the foreground.

Quickly review the configuration file

A quick review of the configuration file.

Write processing for each module There are four modules

--core: Modules related to process control, configuration files, etc. --event: Module related to event processing --http: Module related to http --mail Module related to mail

Describe each setting in a fixed context. Write the core module in the main context. In other words, write it at the top of the configuration file.

core module settings

events {
event module settings
}

http {
http module settings
}

mail {
mail module settings
}

Configuration file (nginx.conf)

It is a configuration file of Nginx built in Flask + Gunicon + docker-compose environment.


user  nginx;
worker_processes  auto;

#events context: required
events {
    worker_connections 512; #Limiting the number of connections
}

#http context: Required
http {
    keepalive_timeout 60;
    server_tokens off;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    server {
            listen 80;
            server_name nginx_container;
            charset UTF-8;
            proxy_read_timeout  60s;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_redirect off;
            #Necessary, an appropriate port number will be given when redirecting within the app
            port_in_redirect on;

            # docker-Can be specified by container name because it is networks with compose
            location / {
                proxy_pass http://flask:5000;
            }

    }
}

From now on, I will touch on each point in detail: arrow_down:

core module

worker_processes You can specify the number of execution processes. Set according to the number of cores. If you set it to auto, it will set the optimum number of cores. The default is 1.

events module

worker_connections Limits the number of connections a worker can handle at the same time. If there are two processes and 512 connections, it is a calculation that can process up to 1024 connections at the same time. The default is 512.

It is the same value as the default, but I intentionally left it because I was considering another value.

http module

keepalive_timeout It is the number of seconds for the timeout on the server side. The default is 75.

server_tokens Set whether to display the Nginx version in the footer of the error page. It is unnecessary and should be removed for security reasons. ʻOff`.

proxy_set_header Redefine the header to send to the backend server.

proxy_redirect Location header when redirecting the backend server. If on, proxy_pass is used as the host name, and if off, redirect as instructed by the server. Since it is not necessary to expose the host name that is the container configuration in the location header, set it to ʻoff`.

port_in_redirect An appropriate port number will be assigned. When redirecting within the app, if this is not set, the PORT of the App container will be used. The redirect fails every time because the Nginx port (80) and the App container port (5000) are different. If you want to use ridirect with Flask, this setting is indispensable.

location It is connected to the App container running Flask as follows. proxy_pass http://flask:5000;

This is because the flask container of the connection source has the following settings in the docker-compose settings.

#Excerpt

flask:
    build: .
    container_name: flask

    #abridgement

    networks:
      - front
    expose:
      - 5000

I am connecting to nginx via the front network. Therefore, you can connect with flask of container_name. Also, since PORT is opened in the connection container with ʻexpose 5000, connect the port number with 5000`.

in conclusion

It was the minimum content, but I still haven't studied enough. : scream: If you study Nginx, you will learn how to handle traffic and distribute the load, so it seems to be cost-effective. Thank you for reading until the end. : raised_hands_tone3:

Recommended Posts

Nginx setting summary (Flask + Docker + Gunicorn edition)
[With image diagram] Nginx + gunicorn + Flask converted to Docker [Part 2]
[With image diagram] Nginx + gunicorn + Flask converted to Docker [Part 1]
Flask + Gunicorn + Nginx + Supervisor Until it works
Make Django's environment Docker (Docker + Django + Gunicorn + nginx) Part 2
Run Flask on CentOS with python3.4, Gunicorn + Nginx.
Docker command summary
Using Flask with Nginx + gunicorn configuration [Local environment]
Make Django's environment Docker (Docker + Django + Gunicorn + nginx) Part 3
Output log to console with Flask + Nginx on Docker
Launch a Python web application with Nginx + Gunicorn with Docker
Flask article summary page
Jupyter Docker image summary