为什么我无法通过“docker-compose run web”命令运行django迁移?

所以我通过docker-compose来部署django,postgress和nginx容器,我有一个问题,我似乎无法弄清楚。

为了解决我的Django应用程序中的以下错误,我知道我只需要运行Django迁移。

docker@postgres ERROR: relation "accounts_myprofile" does not exist 

为了运行迁移,我试着:

 docker-compose run web python manage.py makemigrations docker-compose run web python manage.py migrate 

其中返回了以下内容:

 Migrations for 'accounts': accounts/migrations/0001_initial.py: - Create model Entry - Create model MyProfile Running migrations: No migrations to apply. 

我只能从Django容器内成功迁移,例如:

 docker exec -i -t 6dc97c6a305c /bin/bash python manage.py makemigrations python manage.py migrate 

虽然我已经解决了这个问题,但是我仍然不明白为什么通过docker-compose运行迁移并不实际迁移任何东西。 我希望有人可以指出我在这个正确的方向。

此外,我不知道这是否是一个相关的问题,但是当我运行这些docker-compose运行web命令,他们似乎创build新的容器,将不会closures,除非我手动停止它们,docker-compose停止不会删除它们。

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a7bb3c7106d1 accounts_web "python manage.py che" 4 hours ago Restarting (0) 41 minutes ago 8000/tcp accounts_web_run_62 ee19ca6cdf49 accounts_web "python manage.py mig" 4 hours ago Restarting (0) 43 minutes ago 8000/tcp accounts_web_run_60 2d87ee35de3a accounts_web "python manage.py mak" 4 hours ago Restarting (0) 43 minutes ago 8000/tcp accounts_web_run_59 1c6143c13097 accounts_web "python manage.py mig" 4 hours ago Restarting (1) 44 minutes ago 8000/tcp accounts_web_run_58 6dc97c6a305c b1cb7debb103 "python manage.py run" 3 days ago Up 4 hours 8000/tcp accounts_web_1 

注意:Docker-compose stop将正确地停止底部的容器(因为它应该),但由docker-compose创build的其他容器运行web python manage.py migrate,则需要手动停止。

我的docker – 撰写

 web: restart: always build: ./web expose: - "8000" links: - postgres:postgres volumes: - /usr/src/app - /usr/src/app/static env_file: .env environment: DEBUG: 'true' command: python manage.py runserver 0.0.0.0:8000 postgres: restart: always image: kartoza/postgis:9.4-2.1 ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data/ 

docker-compose运行创build新的容器

你已经注意到了这个问题。 当你使用docker-compose run ,会创build一个新的容器。

运行第一个命令(makemigrations)时,会创build一个新的容器,运行makeMigrations,并将迁移文件写入(新)容器的文件系统。

运行第二个命令(迁移)时,会创build另一个新的容器。 迁移运行,但没有任何关系。 这是因为迁移文件不可用 – 它们被写入与这个新的不同的容器中。

你可以用几种方法来解决这个问题。

使用docker-compose exec

首先,你可以做你已经做的事情,但是使用docker-compose exec而不是run

 docker-compose exec web python manage.py makemigrations docker-compose exec web python manage.py migrate 

exec将使用已经运行的容器,而不是创build新的容器。

使用入口点脚本

另一个select是在启动服务器之前使用入口点脚本并在那里运行迁移。 如果你希望事情更自动化,这就是要走的路。

Dockerfile:

 COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh 

entrypoint.sh:

 #!/bin/sh python manage.py makemigrations python manage.py migrate exec "$@" 

docker-compose.yml(在“networking”下):

 entrypoint: /entrypoint.sh 

在这种情况下,当容器启动时,入口点脚本将运行,处理你的迁移,然后交给command (在本例中是Django runserver )。

新的容器永远循环

你注意到,新的容器保持运行。 这通常是意想不到的,因为你用一个应该退出的命令覆盖命令(而不是保持运行)。 但是,在docker-compose.yml中,您指定了restart: always 。 所以他们会反复运行迁移命令,每次命令退出时重新启动。