Django 为什么我无法通过';docker compose run web';指挥部?

Django 为什么我无法通过';docker compose run web';指挥部?,django,docker,migration,docker-compose,Django,Docker,Migration,Docker Compose,因此,我正在通过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-c

因此,我正在通过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运行migrate实际上并不迁移任何东西。我希望有人能给我指出正确的方向

另外,我不知道这是否是一个相关问题,但当我运行那些docker compose run web命令时,它们似乎正在创建新的容器,除非我手动停止它们,否则不会关闭它们,docker compose stop不会删除它们

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运行web python manage.py migrate创建的另一个容器将需要手动停止

我的码头工人

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运行创建新容器 你已经注意到了这个问题。使用
docker compose run
时,将创建一个新容器

当您运行第一个命令(makemigrations)时,将创建一个新容器,并运行makemigrations,迁移文件将写入(新)容器的文件系统

当您运行第二个命令(migrate)时,另一个新容器被创建。迁移正在运行,但与此无关。这是因为迁移文件不可用-它们是在与此新文件不同的容器中编写的

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

使用docker compose exec 首先,您可以执行已经执行的操作,但是使用
docker compose exec
而不是
run

docker-compose exec web python manage.py makemigrations 
docker-compose exec web python manage.py migrate
exec
将使用已经运行的容器,而不是创建新的容器

使用入口点脚本 另一个选项是在服务器启动之前,使用入口点脚本并在那里运行迁移。如果你想让事情变得更自动化,这是一个好办法

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(在“web”下):

在这种情况下,当容器启动时,entrypoint脚本将运行,处理迁移,然后切换到
命令(在本例中是Django
runserver

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

Dan Lowe给出了一个非常好的回答,但是entrypoint脚本对我不起作用。问题是一些“makemigration”需要您的输入,例如“yes”/“no”

您可以用以下内容补充Dan Lowe的回答:

python manage.py makemigrations --noinput
而不是

python manage.py makemigrations

(这至少适用于简单的“是”/“否”问题)

此awnser是对Dan Lowe和Rexcirus回答的补充

为了在de CodeBuild e Fargate期间工作良好,我做了一些更改:

文件:

COPY ./docker/entrypoint.sh /usr/local/bin/
COPY ./docker/entrypoint.sh /${projectName}/
# backwards compat
RUN ln -s usr/local/bin/entrypoint.sh /

ENTRYPOINT ["entrypoint.sh"]
CMD ["entrypoint.sh"]
/docker/entrypoint.sh

#!/bin/sh
python manage.py makemigrations --noinput
python manage.py migrate
python manage.py runserver 0.0.0.0:8000

现在一切都正常运行。

也会有所帮助,但我认为自动运行迁移不是一个好主意(例如,有时Django会询问您是否重命名了模型,这可能会破坏自动化),但是如果您使用entrypoint.sh文件,您如何做python manage.py createsuperuser之类的事情,这些命令是ignored@JesusAlmaral您也可以在entrypoint脚本中执行此操作。但在这种情况下,您必须执行与正常不同的操作,因为该命令需要输入。查看哪一项可能有助于完成该任务。通过编写数据迁移,您可以将超级用户的创建作为迁移的一部分,请参阅@JesusAlmaralAre 2019年有什么变化吗?我希望做同样的事情,我很好奇答案是否会改变。
python manage.py makemigrations

python manage.py migrate

#Crear usuario root

DJANGO_SUPERUSER_PASSWORD=*your-passwd* python manage.py createsuperuser --username *root* --email *youremail@gamil.com* --noinput
python manage.py makemigrations

python manage.py migrate

#Crear usuario root

DJANGO_SUPERUSER_PASSWORD=*your-passwd* python manage.py createsuperuser --username *root* --email *youremail@gamil.com* --noinput