[英]How do you perform Django database migrations when using Docker-Compose?
我已經按照 Docker 站點上的 Django 快速入門說明設置了一個 Docker Django/PostgreSQL 應用程序。
我第一次運行 Django 的 manage.py migrate 時,使用命令sudo docker-compose run web python manage.py migrate
,它按預期工作。 數據庫構建在 Docker PostgreSQL 容器中就好了。
在我保存它們的那一刻,對 Django 應用程序本身所做的更改同樣反映在 Docker Django 容器中。 這很棒!
但是,如果我隨后在 Django 中更改模型,並嘗試更新 Postgres 數據庫以匹配該模型,則不會檢測到任何更改,因此無論我運行makemigrations
或再次migrate
多少次都不會發生migrate
。
基本上,每次更改 Django 模型時,我都必須刪除 Docker 容器(使用sudo docker-compose rm
)並重新開始新的遷移。
我仍在努力了解 Docker,我不明白它是如何工作的,但這個讓我發瘋。 為什么遷移看不到我的更改? 我究竟做錯了什么?
您只需要登錄正在運行的 docker 容器並運行您的命令。
docker-compose build -f path/to/docker-compose.yml
docker-compose up -f path/to/docker-compose.yml
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fcc49196a84 ex_nginx "nginx -g 'daemon off" 3 days ago Up 32 seconds 0.0.0.0:80->80/tcp, 443/tcp ex_nginx_1
66175bfd6ae6 ex_webapp "/docker-entrypoint.s" 3 days ago Up 32 seconds 0.0.0.0:32768->8000/tcp ex_webapp_1
# postgres docker container ...
docker exec -t -i 66175bfd6ae6 bash
現在您已登錄,然后轉到正確的文件夾: cd path/to/django_app
現在,每次編輯模型時,請在容器中運行: python manage.py makemigrations
和python manage.py migrate
我還建議您為 django docker 容器文件使用 docker-entrypoint 以自動運行:
這是一個示例( docker-entrypoint.sh
):
#!/bin/bash
# Collect static files
echo "Collect static files"
python manage.py collectstatic --noinput
# Apply database migrations
echo "Apply database migrations"
python manage.py migrate
# Start server
echo "Starting server"
python manage.py runserver 0.0.0.0:8000
我使用這些方法:
services:
web:
build: .
image: uzman
command: python manage.py runserver 0.0.0.0:8000
ports:
- "3000:3000"
- "8000:8000"
volumes:
- .:/code
depends_on:
- migration
- db
migration:
image: uzman
command: python manage.py migrate --noinput
volumes:
- .:/code
depends_on:
- db
使用我們創建的docker
層次結構,服務遷移在設置數據庫之后運行,並在運行主服務之前運行。 現在,當您運行服務時, docker
將在運行服務器之前運行遷移; 看看migration
服務器應用在與 Web 服務器相同的圖像上,這意味着所有遷移都將從您的項目中獲取,從而避免出現問題。
通過這種方式,您可以避免制作入口點或其他任何東西。
讓你的堆棧運行,然后發出一個一次性的 docker-compose run 命令。 例如
#assume django in container named web
docker-compose run web python3 manage.py migrate
這適用於內置(默認)SQLite 數據庫,但也適用於列為依賴項的外部 dockerized 數據庫。 這是一個示例 docker-compose.yaml 文件
version: '3'
services:
db:
image: postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
您可以使用docker exec
命令
docker exec -it container_id python manage.py migrate
如果你docker-compose.yml
有這樣的東西
version: "3.7"
services:
app:
build:
context: .
dockerfile: docker/app/Dockerfile
ports:
- 8000:8000
volumes:
- ./:/usr/src/app
depends_on:
- db
db:
image: postgres
restart: always
environment:
POSTGRES_USER: docker
POSTGRES_PASSWORD: docker
POSTGRES_DB: docker
然后你可以簡單地運行...
~$ docker-compose exec app python manage.py makemigrations
~$ docker-compose exec app python manage.py migrate
您可以使用docker-entrypoint.sh
或者更新的解決方案將是您docker-compose.yml
多個注釋
version: '3.7'
services:
web:
build: ./
command: >
sh -c "python manage.py collectstatic --noinput &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
volumes:
- ./:/usr/src/app/
ports:
- 8000:8000
env_file:
- ./.env
depends_on:
- postgres
postgres:
image: postgres:13.0-alpine
ports:
- 5432:5432
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
我知道這是舊的,也許我在這里遺漏了一些東西(如果是這樣,請賜教!),但是為什么不將命令添加到您的start.sh
腳本中,由 Docker 運行以啟動您的實例? 它只需要額外的幾秒鍾。
注意,我設置了DJANGO_SETTINGS_MODULE
變量以確保使用正確的數據庫,因為我使用不同的數據庫進行開發和生產(盡管我知道這不是“最佳實踐”)。
這為我解決了:
#!/bin/bash
# Migrate the database first
echo "Migrating the database before starting the server"
export DJANGO_SETTINGS_MODULE="edatool.settings.production"
python manage.py makemigrations
python manage.py migrate
# Start Gunicorn processes
echo "Starting Gunicorn."
exec gunicorn edatool.wsgi:application \
--bind 0.0.0.0:8000 \
--workers 3
使用 docker exec,我收到以下錯誤:
AppRegistryNotReady("Models aren't loaded yet.")
所以我改用這個命令:
docker-compose -f local.yml run django python manage.py makemigrations
如果只想使用 Dockerfile,可以添加 ENTRYPOINT[] 命令。 示例如何運行 .sh 腳本:
FROM python:3.9.4
RUN apt-get update
RUN apt-get install libpq-dev --assume-yes
RUN pip3 install psycopg2
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
RUN pip3 install debugpy
ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.