【问题标题】:Docker-compose service exited with code 0Docker-compose 服务以代码 0 退出
【发布时间】:2019-10-17 08:53:08
【问题描述】:

我对 Docker 很陌生。我正在尝试在 Docker 上运行 Django。以下是我的 docker-compose 文件。

version: '2'
services:
    django:
        build:
          context: .
          dockerfile: ./deploy/dev/Dockerfile
        tty: true
        command: python manage.py runserver 0.0.0.0:8000
        ports:
              - "8000:8000"
        volumes:
            - ./app:/src/app
        depends_on:
            - "workflow_db"
            - "rabbitmq"
        env_file:
            - ./deploy/dev/envvar.env
    workflow_db:
        image: postgres:9.6
        volumes:
            - postgres_data:/var/lib/postgresql/data/
        environment:
            - POSTGRES_USER=hello_django
            - POSTGRES_PASSWORD=hello_django
            - POSTGRES_DB=hello_django
    rabbitmq:
        image: "rabbitmq:3-management"
        hostname: "rabbitmq"
        environment:
            RABBITMQ_ERLANG_COOKIE: "SWQOKODSQALRPCLNMEQG"
            RABBITMQ_DEFAULT_USER: "rabbitmq"
            RABBITMQ_DEFAULT_PASS: "rabbitmq"
            RABBITMQ_DEFAULT_VHOST: "/"
        ports:
            - "15672:15672"
            - "5672:5672"
volumes:
  postgres_data:

DockerFile

FROM python:3.7-alpine

RUN apk update && apk add --no-cache gcc libffi-dev g++ python-dev build-base linux-headers postgresql-dev postgresql postgresql-contrib pcre-dev bash alpine-sdk \
  && pip install wheel

#Copy over application files
COPY ./app /src/app

#Copy over, and grant executable permission to the startup script
COPY ./deploy/dev/entrypoint.sh /
RUN chmod +x /entrypoint.sh

WORKDIR /src/app

#Install requirements pre-startup to reduce entrypoint time
RUN pip install -r requirements.txt

ENTRYPOINT [ "/entrypoint.sh" ]

最后是我的 entrypoint.sh

#! /bin/bash

cd /src/app || exit

echo "PIP INSTALLATION" && pip install -r requirements.txt

echo "UPGRADE" && python manage.py migrate

# echo "uwsgi" && uwsgi "uwsgi.ini"

我做django-compose build,它构建了图像。但是当我做docker-compose updjango_1 exited with code 0.

但是,如果我取消注释 entrypoint.sh 的最后一行,它运行得非常好。

有人可以帮我理解背后的原因吗?

【问题讨论】:

  • 如果您在 docker 映像中复制文件,最好删除卷。删除这个 `volumes: - ./app:/src/app` ,因为它会覆盖图像中的所有内容。或者可能在撰写容器内的路径将成为某些东西 /src/app/app/... 。由于应用程序以代码 0 退出所以意味着没有错误,通过添加 django: command: tail -f /dev/null 然后验证 django 容器内的文件和文件夹来帮助您调试的一件事。路径似乎有问题
  • 还有其他消息还是django_1 exited with code 0?您能否将您的uwsgi.ini 包含在问题中?

标签: django docker uwsgi


【解决方案1】:

当您同时拥有命令和入口点时,Docker只运行入口点,并将命令作为参数传递给它。请参阅 Dockerfile 文档中的 Understand how CMD and ENTRYPOINT interact。入口点一退出,容器就结束了;它可以对命令部分做任何它喜欢的事情,包括完全忽略它。

典型的做法是用

结束入口点脚本
exec "$@"

这导致它只接受其命令行参数并将它们作为命令运行,将入口点脚本替换为主容器进程。

没有这个,你会到达入口点脚本的末尾,并且容器已经完成了它被告知要做的所有事情,所以它成功退出(状态代码 0)。

【讨论】:

  • 是的。玩了很多,我自己弄清楚了数学。但是,您的回答起到了解释的作用。非常感谢。
【解决方案2】:

如果你想让容器继续运行,你需要:

  1. 运行前台进程
  2. 通过 --ti 连接到它的终端

你需要连接终端来查看在uwsgi没有执行时python命令是否失败,从而停止容器

【讨论】:

    【解决方案3】:

    AFAIU,当您取消注释入口点中的最后一行时,容器不再有可以保持其启动和运行的前台进程,因此它以状态 0 退出。入口点必须有一个前台进程来保持容器正常运行 &跑步。此外,您正在多次执行“pip install”。这一步应该只是在 Dockerfile 中。

    尝试将python manage.py runserver 0.0.0.0:8000 移动到entrypoint.sh 本身。

    更新 -

    在端口冲突的情况下,容器将不会以状态 0 退出,并且端口冲突错误会在 STDOUT 中出现。此外,当他取消连接时,不会发生端口冲突。所以,前台进程似乎根本没有被执行。

    【讨论】:

    • 我认为它确实有一个前台进程,在撰写文件上python manage.py runserver 0.0.0.0:8000
    • 知道了。但我怀疑这是否会被执行。您可以尝试将该命令放在入口点中吗?
    • 我不知道,让提问者说吧:D。你认为这是因为 uwsgi 在同一个端口 8000 上运行,所以当 docker compose 执行 python manage.py runserver 0.0.0.0:8000 时,它会停止前台进程。也许?
    • 是的,有道理,很可能是原因。我从来没有这样尝试过。理想情况下,它应该都在入口点或入口点应该支持 CMD 传递的参数。
    • 更正,如果端口冲突,容器将不会以状态0退出并且端口冲突错误并在STDOUT中出现。此外,当他取消连接时,不会发生端口冲突。所以,前台进程似乎根本没有被执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 2018-12-09
    • 2023-02-25
    • 1970-01-01
    • 2017-04-07
    相关资源
    最近更新 更多