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

发布于 2021-02-01 12:50:17

所以我正在通过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 run运行迁移实际上并没有迁移任何东西。我希望有人可以为此指出正确的方向。

另外,我不知道这是否是一个相关问题,但是当我运行那些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 migration,将需要手动停止。

我的码头工人组成

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/
关注者
0
被浏览
178
1 个回答
  • 面试哥
    面试哥 2021-02-01
    为面试而生,有面试问题,就找面试哥。

    docker-compose运行创建新容器

    您已经注意到了问题。使用时docker-compose run,将创建一个新容器。

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

    当您运行第二个命令(迁移)时,将创建另一个新容器。迁移进行了,但是没有任何关系。那是因为迁移文件不可用-它们是用不同于此新文件的容器编写的。

    您可以通过两种方法解决此问题。

    使用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: /entrypoint.sh
    

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

    新的容器永远循环

    如您所见,新容器保持运行状态。这通常是意外的,因为您用应该退出(而不是保持运行)的命令覆盖了该命令。但是,在docker-
    compose.yml中,您指定了restart: always。因此,他们将一遍又一遍地运行迁移命令,并在每次退出时重新启动。



推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看