Использование gunicorn с ubuntu: последнее изображение Docker - PullRequest
2 голосов
/ 01 августа 2020

Я пытаюсь настроить сервер Gunicorn внутри Ubuntu: последний образ Docker.

При запуске на Docker я получаю следующий результат:

[2020-08-01 14:12:38 +0000] [6] [INFO] Starting gunicorn 20.0.4
[2020-08-01 14:12:38 +0000] [6] [DEBUG] Arbiter booted
[2020-08-01 14:12:38 +0000] [6] [INFO] Listening at: http://0.0.0.0:5000 (6)
[2020-08-01 14:12:38 +0000] [6] [INFO] Using worker: sync
[2020-08-01 14:12:38 +0000] [8] [INFO] Booting worker with pid: 8
[2020-08-01 14:12:38 +0000] [6] [DEBUG] 1 workers

После что, я не вижу вывода на терминал. Я проверил порты, используя sudo netstat -tunlp, открытый на моем компьютере, и Gunicorn не работает.

Он отлично работает, если я использую ту же настройку, используя gunicorn --bind 0.0.0.0:5000 app:app --log-level debug внутри virtualenv ... Что-то мне не хватает вверх?

# ------------------------------------------------------------------------------
# Production image based on ubuntu:latest with nginx & python3
# ------------------------------------------------------------------------------
FROM ubuntu:latest as prod-react

WORKDIR /usr/src/app

# update, upgrade and install packages
RUN apt-get update && apt-get install -y --no-install-recommends apt-utils
RUN apt-get upgrade -y
RUN apt-get install -y nginx curl python3 python3-distutils python3-apt

# install pip
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
RUN python3 get-pip.py

# copy flask-api requirements file and install modules
COPY ./flask-api/requirements.txt ./
RUN pip install -r requirements.txt
RUN pip install gunicorn

# copy flask code
COPY ./flask-api/app.py .

# ------------------------------------------------------------------------------
# Serve flask-api with gunicorn
# ------------------------------------------------------------------------------
EXPOSE 5000
CMD gunicorn --bind 0.0.0.0:5000 app:app --log-level debug

Flask python код

from flask import Flask, request
from flask_cors import CORS
from flask_restful import Api, Resource
import time

# ------------------------------------------------------------------------------
# Flask app config + CORS
# ------------------------------------------------------------------------------
app = Flask(__name__)
app.config.from_object(__name__)
app.config['DEBUG'] = True

# accept CORS from frontend app
CORS(app, origins=['*'], supports_credentials=True)

# ------------------------------------------------------------------------------
# RESTFUL API
# ------------------------------------------------------------------------------
API_PREFIX = '/api'
api = Api(prefix=API_PREFIX)


class AuthenticationAPI(Resource):
    def get(self):
        print('auth get', flush=True)
        return {'res': 'get'}, 200

    def post(self):
        print('auth post', flush=True)
        print(request.get_json())
        return {'res': 'post'}, 200


class TimeAPI(Resource):
    def get(self):
        print('time get', flush=True)
        return {'res': time.time()}, 200


api.add_resource(AuthenticationAPI, '/auth')
api.add_resource(TimeAPI, '/time')

api.init_app(app)

Ответы [ 2 ]

1 голос
/ 01 августа 2020

Из документации docker для директивы EXPOSE :

Инструкция EXPOSE фактически не публикует sh порт. Он функционирует как тип документации между человеком, создающим образ, и человеком, который запускает контейнер, о том, какие порты предназначены для публикации. Чтобы фактически опубликовать sh порт при запуске контейнера, используйте флаг -p для docker run в publi sh и сопоставьте один или несколько портов или флаг -P для publi sh всех открытых портов и сопоставления их на порты высокого порядка.

Итак, поскольку Gunicorn прослушивает порт 500, вы захотите запустить свой контейнер следующим образом:

docker run -p 5000:5000 your_image

передавая любые другие параметры вы уже переходите при запуске вашего контейнера.

0 голосов
/ 02 августа 2020

Мне удалось заставить его работать на локальном dev. Следующий файл Dockerfile содержит все изменения, я прокомментировал команды, чтобы он работал правильно.

# ------------------------------------------------------------------------------
# Temporary image for react.js app using a multi-stage build
# ref : https://docs.docker.com/develop/develop-images/multistage-build/
# ------------------------------------------------------------------------------
FROM node:latest as build-react

# create a shared folder and define it as current dir
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH

# copy the files required for node packages installation
COPY ./react-client/package.json ./
COPY ./react-client/yarn.lock ./

# install dependencies, copy code and build bundles
RUN yarn install
COPY ./react-client .
RUN yarn build

# ------------------------------------------------------------------------------
# Production image based on ubuntu:latest with nginx & python3
# ------------------------------------------------------------------------------
FROM ubuntu:latest as prod-react

WORKDIR /usr/src/app

# update, upgrade and install packages
RUN apt-get update && apt-get install -y --no-install-recommends apt-utils
RUN apt-get upgrade -y
RUN apt-get install -y nginx curl python3 python3-distutils python3-apt

# install pip
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
RUN python3 get-pip.py

# copy flask-api requirements file and install modules
COPY ./flask-api/requirements.txt ./
RUN pip install -r requirements.txt
RUN pip install gunicorn

# copy flask code
COPY ./flask-api/app.py .

# copy built image and config onto nginx directory
COPY --from=build-react /usr/src/app/build /usr/share/nginx/html
COPY ./conf.nginx /etc/nginx/conf.d/default.conf

# ------------------------------------------------------------------------------
# Serve flask-api with gunicorn and react-client with nginx
# Ports :
#   - 5000 is used for flask-api
#   - 8080 is used by nginx to serve react-client
# You can change them but you'll have to change :
#   - for flask-api    : conf.nginx, axios calls (5000 -> @newApiPort)
#   - for react-client : CORS origins (8080 -> @newClientPort)
#
# To build and run this :
#   docker build -t @imageName .
#   docker run -d --name @containerName -e "PORT=8080" -p 8080:8080 -p 5000:5000 @imageName
# ------------------------------------------------------------------------------
CMD gunicorn --bind 0.0.0.0:5000 app:app --daemon && \
sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && \
nginx -g 'daemon off;'
...