使用Docker拉取Django镜像并运行容器。

4

因此,我按照 Docker 的 这个 教程创建了一个 Django 镜像。

仅需在项目的根目录中运行 docker-compose up 命令,即可在我的本地机器上完美运行。

但是,在将镜像推送到 Docker Hub https://hub.docker.com/repository/docker/vivanks/firsttry 后,我在另一台机器上拉取镜像,然后运行:

docker run -p 8020:8020 vivanks/firsttry

但是它没有启动并显示了以下错误:

已退出(0)

有人能帮我解决如何拉取这个镜像并运行它的问题吗?

我的Dockerfile

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

我的docker-compose.yml文件
  version: '3'
    
  services:
    db:
      image: postgres
      environment:
        - POSTGRES_DB=postgres
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
    web:
      build: .
      command: python manage.py runserver 0.0.0.0:8000
      volumes:
        - .:/code
      ports:
        - "8000:8000"
      depends_on:
        - db

2
请编辑您的问题并添加最终版本的Dockerfile。 - mehrdadep
1
顺便提一下,使用 WORKDIR /code 就足够了,你不需要在它之前运行 mkdir /code。请注意,每个 RUN 命令都会向您的 Docker 镜像添加一个额外的层。 - mehrdadep
我已经创建了数据库。使用 docker-compose up 命令,在我的机器上它可以完美地运行,并且有正确的数据库。docker-compose up 命令只会自动创建数据库镜像。 - The Drunken Wiz
我已经按照这个教程 https://docs.docker.com/compose/django/ 进行操作,以便您能够复制该问题。 - The Drunken Wiz
1
@MehrdadEP,在compose文件中,当前目录被挂载到构建时源代码和requirements.txt所复制的目录中...除了没有一个合适的数据库。 - Neo Anderson
显示剩余4条评论
2个回答

1

您的 Dockerfile 没有指定 CMDENTRYPOINT。当您运行时...

docker run -p 8020:8020 vivanks/firsttry

...容器没有任何操作(这意味着它实际上会尝试启动一个Python交互式shell,但由于您没有使用-t分配终端,因此shell会立即退出。成功)。在您的docker-compose.yml中,您正在传递一个明确的命令:

      command: python manage.py runserver 0.0.0.0:8000

因此,相应的docker run命令行应如下所示:

docker run -docker run -p 8020:8020 vivanks/firsttry python manage.py runserver 0.0.0.0:8000

但您可能希望将其嵌入到 Dockerfile 中,如下所示:

CMD python manage.py runserver 0.0.0.0:8000

加入 CMD 后,我该如何运行这个镜像? - The Drunken Wiz
我遇到了一个错误:conn = _connect(dsn, connection_factory=connection_factory, **kwasync) django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known - The Drunken Wiz
有什么帮助吗?@larsks - The Drunken Wiz

1

正如@larsks在他的回答中提到的那样,你的问题是你的命令在Compose文件中,而不是在Dockerfile中。

要在另一台机器上原样运行项目,请使用以下docker-compose.yml

version: '3' 
services:
    db:
      image: postgres
      environment:
        - POSTGRES_DB=postgres
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
    web:
      image: vivanks/firsttry:latest
      command: python manage.py runserver 0.0.0.0:8000
      ports:
        - "8000:8000"
      depends_on:
        - db

如果你已经在Dockerfile中添加了CMD python manage.py runserver 0.0.0.0:8000并重新构建了镜像,那么上述内容可以进一步简化为:
version: '3' 
services:
    db:
      image: postgres
      environment:
        - POSTGRES_DB=postgres
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
    web:
      image: vivanks/firsttry:latest
      ports:
        - "8000:8000"
      depends_on:
        - db

使用docker run将会失败,因为它不会设置数据库。
编辑:
楼主,我欣赏你的坚持,但同时也不理解为什么要使用Docker CLI而不是docker-compose。我建议使用上述任一docker-compose.yml文件来启动您的应用程序。
尽管如此,我接受了不使用docker-compose运行它的挑战。
当您使用docker run命令时,您的应用程序无法启动,因为它尝试连接到名为db的主机上的数据库,但该主机不存在。在您(和我的)的docker-compose.yml中,有一个称为db的服务定义。Docker-compose使用该定义为您设置数据库容器,并使其在主机名db下可用于您的应用程序。
要在不使用docker-compose的情况下启动应用程序,您需要手动执行它自动执行的所有操作(以下命令假定您已将CMD...添加到您的Dockerfile中)。
docker network create --driver bridge django-test-network
docker run --detach --env POSTGRES_DB=postgres --env POSTGRES_USER=postgres --env POSTGRES_PASSWORD=postgres --network django-test-network --name db postgres:latest
docker run -it --rm --network django-test-network --publish 8080:8000 vivanks/firsttry:latest

上述3个命令创建了一个新的桥接网络,创建并启动了一个已配置好数据库连接到该网络的分离(后台)容器,最后创建并启动了一个基于您的镜像的附加(前台)容器,也连接到该新网络。由于两个容器都在相同的非默认桥接网络上,因此您的应用程序将能够将主机名db解析为数据库容器的内部IP地址并正确启动。
一旦您使用Ctrl+C关闭它,您的应用程序容器将删除自身(因为它是使用选项--rm启动的),但您还需要手动清理其余部分。要这样做,请运行以下命令:
docker stop db
docker rm -v db
docker network remove django-test-network

第一个命令停止数据库容器,第二个命令删除它及其匿名卷,第三个命令删除网络。
希望这能解释一切。

如何让它工作?我已经告诉你如何在另一台机器上运行你的项目了。 - Konrad Botor
conn = _connect(dsn, connection_factory=connection_factory, **kwasync) django.db.utils.OperationalError: 无法将主机名“db”翻译为地址:名称或服务未知在运行“docker run vivanks/firsttry”时,我遇到了上述更改的错误。 - The Drunken Wiz
这里需要帮助吗,@Konrad Botor - The Drunken Wiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接