使用ENTRYPOINT或CMD

时间:2018-10-21 07:12:31

标签: docker flask gunicorn

我有以下Dockerfile和entrypoint.sh脚本。我按照下面的方法进行操作,但是当我运行容器时,它看起来像是gunicorn永远不会启动,因为没有任何内容写入日志文件。该容器保持运行状态,因为我键入“ docker ps”,并且可以看到它。

然后我通过执行“ docker exec -it / bin / bash”启动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

然后当我在docker主机上转到http://0.0.0.0:8080时,它确实起作用。

有什么区别?为什么gunicorn在entrypoint.sh上不起作用?

更新 我已经创建了一个新文件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 :(得分:1)

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的实际启动。您应该能够通过使用shell -x选项(如在您的编辑中,或者在脚本中添加set -x行)来看到此内容:它将自动切换到tail ,然后停下来。

在注释中,您说您在配置文件中设置了daemon = True gunicorn option。如果gunicorn找到了它,它将自动将其插入后台并退出。从Docker的角度来看,它看到它作为容器入口点出口启动的过程,因此容器完成了,并关闭了。我不确定是什么导致或不引起该配置文件被读取,但这会导致提前退出。

您需要确保正在将服务器作为前台进程运行。如果您docker exec在运行中的容器中获取外壳程序,启动服务器并返回命令提示符,则您将以无法使容器保持活动状态的方式对其进行调用。

答案 1 :(得分:1)

在运行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"