为什么我无法通过“docker-compose run web"命令运行 django 迁移? [英] Why am I unable to run django migrations via the 'docker-compose run web' command?

查看:12
本文介绍了为什么我无法通过“docker-compose run web"命令运行 django 迁移?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在通过 docker-compose 部署 django、postgress 和 nginx 容器,但我遇到了一个我似乎无法解决的问题.

So I am deploying django, postgress and nginx containers via docker-compose and I have an issue that I can't seem to figure out.

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

In order to resolve the following error in my Django app, I knew I just had to run a Django migration.

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

为了尝试运行迁移,我尝试了:

In an attempt to run migrations, I tried:

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 容器中成功迁移,例如:

I was only able to successfully migrate from within the Django container, example:

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

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

Although I have resolved the issue, I still don't understand why running the migrate via docker-compose run does not actually migrate anything. I'm hoping someone can maybe point me in the right direction on this.

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

Also, I don't know if this is a related issue or not, but when I run those docker-compose run web commands, they seem to be creating new containers that won't shutdown unless I manually stop them, docker-compose stop doesn't remove them.

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 run web python manage.py migrate 创建的其他容器需要手动停止.

Note: Docker-compose stop will properly stop the container at the bottom (as it should), but the other container that were created by docker-compose run web python manage.py migrate, will need to be manually stopped.

我的 docker-compose

my docker-compose

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 run 创建新容器

你已经注意到了这个问题.当您使用 docker-compose run 时,会创建一个新容器.

docker-compose run creates new containers

You have already noticed the problem. When you use docker-compose run, a new container is created.

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

When you ran the first command (makemigrations), a new container was created, makemigrations ran, and the migration files were written to the (new) container's filesystem.

当您运行第二个命令(迁移)时,会创建另一个新容器.迁移运行了,但没有任何关系.这是因为迁移文件不可用 - 它们是在与这个新容器不同的容器中编写的.

When you ran the second command (migrate), another new container was created. The migration ran, but it had nothing to do. That's because the migration files were not available - they were written in a different container than this new one.

您可以通过多种方式解决此问题.

You can solve this in a couple of ways.

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

First, you can do what you already did, but use docker-compose exec instead of run.

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

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

exec will use the already-running container, rather than creating new containers.

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

Another option is to use an entrypoint script and run the migration there, before the server is started. This is the way to go if you'd prefer things to be more automatic.

Dockerfile:

Dockerfile:

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

入口点.sh:

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

docker-compose.yml(在网络"下):

docker-compose.yml (under 'web'):

entrypoint: /entrypoint.sh

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

In this scenario, when the container starts, the entrypoint script will run, handle your migration, then hand off to the command (which in this case is Django runserver).

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

As you noticed, the new containers stay running. That is normally unexpected, because you overrode the command with one that should exit (rather than stay running). However, in docker-compose.yml, you specified restart: always. So they will run the migration commands over and over, restarting each time the command exits.

这篇关于为什么我无法通过“docker-compose run web"命令运行 django 迁移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆