Gunicorn не работает в док-контейнере при использовании ENTRYPOINT или CMD - PullRequest
0 голосов
/ 21 октября 2018

У меня есть следующий скрипт Dockerfile и entrypoint.sh.Я делаю так, как показано ниже, но когда я запускаю контейнер, похоже, что gunicorn никогда не запускается, потому что ничего не записывается в файлы журнала.Контейнер продолжает работать, потому что я набираю «docker ps» и вижу его.

Затем я запускаю процесс bash, выполнив «docker exec -it / bin / bash», и я могу запустить процесс gunicorn оттудаи затем это работает.

Таким образом, в основном, это работает, если я запускаю контейнер и затем вхожу в сеанс bash и вставляю команду gunicorn, но это не работает иначе.

Dockerfile:

FROM ubuntu:18.04
MAINTAINER peter griffin "some@email.com"
RUN apt-get update -y && apt-get install -y python-pip python-dev

WORKDIR /deploy

COPY ./requirements.txt ./
RUN pip install -r requirements.txt
RUN pip install gunicorn

COPY ./app ./app

COPY [\
    "run.py", \
    "app.db", \
    "entrypoint.sh", \
    "config.py", \
    "gunicorn.conf.py", \
    "./"]

#RUN mkdir ./logs
RUN chmod +x ./entrypoint.sh

ENTRYPOINT ["sh", "entrypoint.sh"]

entrypoint.sh:

#!/bin/bash

mkdir -p /deploy/logs
touch /deploy/logs/error.log
touch /deploy/logs/access.log
tail -n 0 -f /deploy/logs/*.log

exec gunicorn run:app \
    --name greg_docker \
    --bind 0.0.0.0:8080 \
    --workers 2 \
    --log-level=info \
    --log-file=/deploy/logs/error.log \
    --access-logfile=/deploy/logs/access.log \

Для сборки:

docker build -t greg:latest .

Для запуска:

docker run -d -p 8080:8080 greg:latest

Если явнутри контейнера в сеансе / bin / bash я могу вставить:

exec gunicorn run:app \
    --name greg_docker \
    --bind 0.0.0.0:8080 \
    --workers 2 \
    --log-level=info \
    --log-file=/deploy/logs/error.log \
    --access-logfile=/deploy/logs/access.log

И тогда это сработает, когда я перейду к http://0.0.0.0:8080 на хосте докера.

В чем разница?Почему gunicorn не работает на entrypoint.sh?

update Я создал новый файл, entrypoint2.sh:

#!/bin/bash
mkdir -p /deploy/logs
touch /deploy/logs/error.log
exec gunicorn run:app \
    --name greg_docker \
    --bind 0.0.0.0:8080 \
    --log-level=debug \
    --log-file=/deploy/logs/error.log \
    --workers 2
"$@"

И я обновил свойDockerfile со строкой:

ENTRYPOINT ["sh","-x","entrypoint2.sh"]

Когда я запускаю контейнер, я получаю это:

+ mkdir -p /deploy/logs
+ touch /deploy/logs/error.log
+ exec gunicorn run:app --name greg_docker --bind 0.0.0.0:8080 --log-level=debug --log-file=/deploy/logs/error.log --workers 2

Но тогда контейнер ничего не делает, он не работает.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Оказывается при запуске gunicorn, вам абсолютно необходимо указать файл конфигурации.

entrypoint2.sh:

#!/bin/bash
mkdir -p /deploy/logs
touch /deploy/logs/error.log
touch /deploy/logs/access.log
cd /deploy
exec gunicorn --bind 0.0.0.0:8080 -c docker-gunicorn.conf.py run:app

docker-gunicorn.conf.py:

accesslog = "/deploy/logs/access.log"
errorlog = "/deploy/logs/error.log"
0 голосов
/ 21 октября 2018

Когда вы docker run контейнер, он запускает ENTRYPOINT (если есть), передавая CMD в качестве аргументов командной строки.Когда эта программа или сценарий завершается, контейнер завершается.

На первой итерации ваша ENTRYPOINT сказала:

#!/bin/bash

# Read all of the log files, blocking forever, printing out new
# content as it appears
tail -n 0 -f /deploy/logs/*.log

# Only then, once that "blocking forever" has finished...
exec gunicorn run:app

Таким образом, команда tail препятствовала фактическому запуску gunicorn,Вы должны были увидеть это, используя опцию оболочки -x (как при редактировании, или добавив строку set -x в скрипт): она поднимется до tail, а затем просто остановится.

В комментарии вы говорите, что установили опцию daemon = True * gun5orn в файле конфигурации.Если Gunicorn обнаружит это, то он превратится в фон и выйдет.С точки зрения Докера, он видит процесс, который он запустил, как выход из точки входа контейнера, поэтому контейнер завершен, и он завершает работу.Я не совсем уверен, что вызывает или не вызывает чтение этого конфигурационного файла, но это может привести к досрочному завершению работы.

Вам необходимо убедиться, что вы используете сервер какпроцесс переднего плана .Если вы docker exec получите оболочку в работающем контейнере, запустите сервер и получите командную строку обратно, то вы вызываете ее таким образом, чтобы контейнер не оставался в живых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...