简体   繁体   English

带有 wsgi 的 gunicorn 问题的烧瓶

[英]Flask with gunicorn problems with wsgi

I am trying to set up dockerized production environment for Flask application with gunicorn.我正在尝试使用 gunicorn 为 Flask 应用程序设置 dockerized 生产环境。 I follow this Digital Ocean's instructions together with testdriven's one for dockerizing.我按照这个Digital Ocean 的说明和testdriven 的说明一起进行 dockerizing。

Project structure is following:项目结构如下:

tree -L 2
.
├── Docker
│   ├── Dockerfile
│   ├── Dockerfile-nginx
│   └── nginx.conf
├── dev-requirements.txt
├── docker-compose.prod.yml
├── docker-compose.yml
├── gunicorn_conf.py
├── requirements.txt
├── setup.cfg
├── src
│   ├── __pycache__
│   ├── config.py
│   ├── main.py
│   ├── models.py
│   ├── tests.py
│   ├── views.py
│   └── wsgi.py
└── venv
    ├── bin
    ├── include
    ├── lib
    └── pip-selfcheck.json

7 directories, 16 files

The config resides in docker-compose.prod.yml :配置驻留在docker-compose.prod.yml

version: "3.7"

services:
  web:
    build:
      context: .
      dockerfile: Docker/Dockerfile
    env_file:
      - .web.env
    ports:
      - "5000:5000"
    depends_on:
      - db
    command: gunicorn wsgi:app -c ../gunicorn_conf.py
    working_dir: /app/src
  db:
    image: "postgres:11"
    volumes:
      - simple_app_data:/var/lib/postgresql/data
    env_file:
      - .db.env
volumes:
  simple_app_data:

Contents of gunicorn_conf.py : gunicorn_conf.py内容:

bind = "0.0.0.0:5000"
workers = 2

And wsgi.py :wsgi.py

from main import app

print('*'*10)
print(__name__)
print('*'*10+'\n')

if __name__ == '__main__':
    app.run()

When I try to run this configuration with docker-compose -f docker-compose.prod.yml build --force-rm --no-cache web && docker-compose -f docker-compose.prod.yml run web I get following logs:当我尝试使用docker-compose -f docker-compose.prod.yml build --force-rm --no-cache web && docker-compose -f docker-compose.prod.yml run web运行此配置时,我得到以下信息日志:

Starting simple_app_db_1 ... done
[2019-12-18 12:15:45 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2019-12-18 12:15:45 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2019-12-18 12:15:45 +0000] [1] [INFO] Using worker: sync
[2019-12-18 12:15:45 +0000] [9] [INFO] Booting worker with pid: 9
[2019-12-18 12:15:45 +0000] [10] [INFO] Booting worker with pid: 10
/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py:835: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True or False to suppress this warning.
  'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
**********
wsgi
**********

/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py:835: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True or False to suppress this warning.
  'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
**********
wsgi
**********

So the wsgi.py file is not the __main__ .所以wsgi.py文件不是__main__ However, when I try to get rid of this if :但是,当我尝试摆脱这种if

from main import app

print('*'*10)
print(__name__)
print('*'*10+'\n')

app.run()

I get:我得到:

OSError: [Errno 98] Address already in use

How can I correct this config to use gunicorn?如何更正此配置以使用 gunicorn?

Use gunicorn in the command used to run the docker, ie:在用于运行 docker 的命令中使用 gunicorn,即:

# Dockerfile
...
CMD [ "gunicorn", "-w3", "--bind=0.0.0.0:9999", "wsgi" ]

If you use an entrypoint, just add this command at the end of the entrypoint script.如果您使用入口点,只需在入口点脚本的末尾添加此命令。

You might need to experiment a bit to find the right command.您可能需要进行一些试验才能找到正确的命令。 The syntax is as follow:语法如下:

<folder>.<filename>:<python_object>

Your wsgi.py file might then look like this:您的wsgi.py文件可能如下所示:

# wsgi.py

from main import app as application  # what gunicorn expects
# or
from main import app  # then use gunicorn wsgi:app 

Feel free to check my repo here to have a working example随意在这里检查我的回购以获得一个有效的例子

It turned out that docker did not expose ports for some reason.事实证明,由于某种原因,docker 没有公开端口。

 → docker-compose ps
             Name                            Command               State    Ports
-----------------------------------------------------------------------------------
simple_app_db_1                   docker-entrypoint.sh postgres    Up      5432/tcp
simple_app_web_run_a7165f8215b2   gunicorn wsgi:app -c ../gu ...   Up
 → docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
6c0f5f884135        simple_app_web      "gunicorn wsgi:app -…"   59 seconds ago      Up 57 seconds                           simple_app_web_run_a7165f8215b2
e2948b152b36        postgres:11         "docker-entrypoint.s…"   38 minutes ago      Up 38 minutes       5432/tcp            simple_app_db_1

When I changed the command I used to run the application everything was OK:当我更改用于运行应用程序的命令时,一切正常:

docker-compose -f docker-compose.prod.yml run --publish 5000:5000 web

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM