Docker-Compose का उपयोग करते समय आप Django डेटाबेस माइग्रेशन कैसे करते हैं?


98

मैंने Docker साइट पर Django क्विक स्टार्ट निर्देशों का बारीकी से पालन करते हुए एक डॉकर Django / PostgreSQL ऐप की स्थापना की है ।

पहली बार जब मैं Django का मैनेजमेन्ट माइग्रेट करता हूं, तो कमांड का उपयोग करते हुए sudo docker-compose run web python manage.py migrate, यह अपेक्षित रूप से काम करता है। डेटाबेस डॉक PostgreSQL कंटेनर के अंदर ठीक बनाया गया है।

Django ऐप में किए गए बदलाव उसी तरह से हैं जो डॉकेर Django कंटेनर में दिखाई देते हैं, जिस पल मैं उन्हें बचाता हूं। यह बहुत अच्छा है!

लेकिन अगर मैं फिर Django में एक मॉडल को बदल देता हूं, और मॉडल से मिलान करने के लिए Postgres डेटाबेस को अपडेट करने का प्रयास करता हूं, तो कोई भी परिवर्तन नहीं पाया जाता है इसलिए कोई माइग्रेशन नहीं होता है कि कितनी बार मैं चलाऊंगा makemigrationsया migrateफिर से।

मूल रूप से, हर बार जब मैं Django मॉडल को बदलता हूं, तो मुझे डॉकर कंटेनर (उपयोग sudo docker-compose rm) को हटाना होगा और एक नए प्रवास के साथ नए सिरे से शुरू करना होगा।

मैं अभी भी डॉकटर के चारों ओर अपना सिर पाने की कोशिश कर रहा हूं, और एक भयानक बहुत कुछ है जो मुझे समझ नहीं आता है कि यह कैसे काम करता है, लेकिन यह एक पागल हो रहा है। माइग्रेट मेरे परिवर्तन क्यों नहीं देखता है? मैं क्या गलत कर रहा हूं?


क्या आपने पता लगाया कि क्यों? मुझे नीचे उत्तर मिलता है और यह काम करता है: You just have to log into your running docker container and run your commands.लेकिन क्या कारण है कि यह उस तरह से व्यवहार करता है? @LouisBarranqueiro
lukik

जवाबों:


102

आपको बस अपने रनिंग डॉकटर कंटेनर में लॉग इन करना होगा और अपने कमांड्स चलाने होंगे।

  1. अपना स्टैक बनाएँ: docker-compose build -f path/to/docker-compose.yml
  2. अपना स्टैक लॉन्च करें: docker-compose up -f path/to/docker-compose.yml
  3. प्रदर्शित डॉकिंग कंटेनर: 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 ...
  1. आप के django एप्लिकेशन के कंटेनर आईडी प्राप्त करें और लॉग इन करें:
docker exec -t -i 66175bfd6ae6 bash
  1. अब आप लॉग इन हैं, फिर राइट फोल्डर में जाएं: cd path/to/django_app

  2. और अब, हर बार जब आप अपने मॉडल को संपादित करते हैं, तो अपने कंटेनर में चलाएं: python manage.py makemigrationsऔरpython manage.py migrate

मैं आपको स्वचालित रूप से चलाने के लिए अपने django docker कंटेनर फ़ाइल के लिए डॉक-एंट्री पॉइंट का उपयोग करने की सलाह देता हूं:

  • collecstatic
  • विस्थापित
  • धावक या इसे gunicorn या uWSGI से शुरू करें

यहाँ एक उदाहरण है ( 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

16
मैं आपको स्वचालित रूप से चलाने के लिए अपने django docker कंटेनर फ़ाइल के लिए docker-entrypoint का उपयोग करने की सलाह देता हूं - इस तरह के संचालन को कभी भी स्वचालित रूप से नहीं चलाया जाना चाहिए - मेरा मतलब है कि विशेष रूप से माइग्रेट करें
ओपल

7
इससे कोई फर्क नहीं पड़ता कि आप किस वातावरण में हैं - परिनियोजन हमेशा एक जैसा दिखना चाहिए। यदि माइग्रेशन स्वचालित हैं तो समवर्ती रूप से चलाया जा सकता है जो अत्यधिक हतोत्साहित है। जैसे कि हॉकू - माइग्रेशन कभी भी तैनाती के एक भाग के रूप में नहीं चलाया जाता है।
ओपल

5
concurently? यहाँ हम एक देव दूत हैं। मैं दौड़ता हूं makemigrations। अगली बार जब मैं अपना स्टैक लॉन्च करूंगा, migrateतो पिछले माइग्रेशन पूर्ववत के साथ डेटाबेस को अपडेट कर दूंगा, अन्यथा django ऐप सही तरीके से काम नहीं करेगा ... यह देव एनवी में सिर्फ एक शॉर्टकट है ताकि आप वर्तमान ऐप के साथ सही डेटाबेस स्कीमा प्राप्त कर सकें
लुई बैरैंकेरो 10

2
@LouisBarranqueiro, मेरा मतलब था कई उदाहरण, एकल DB।
ओपल

1
चरण 4 के लिए, मैं सुझाऊंगा: docker exec -ti $ CONTAINER_ID / bin / sh
Santiago Magariños

52

मैं इन विधि का उपयोग करता हूं:

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सर्वर उसी छवि पर लागू होता है जो वेब सर्वर है, इसका मतलब है कि समस्याओं से बचने के लिए, सभी माइग्रेशन आपके प्रोजेक्ट से लिए जाएंगे।

आप इस तरह से प्रवेश बिंदु या अन्य किसी भी चीज से बचें।


1
मैं किस तरह से build: .काम करता image: हूं मुझे यह त्रुटि मिलती है कि माइग्रेशन नामांकित छवि को खींच नहीं सकता है
हारून मैकमिलिन

2
मैं डाल कर इसका समाधान नहीं होता build:पर migrationके बाद से यह चलने से पहलेweb
हारून McMillin

4
क्या यह उज़मन इमेज को चालू नहीं रखता है और रैम को हमेशा के लिए खपत करता है? इसके अलावा, uzman छवि क्या है ?
मिलीलीटर

यह मेरी कस्टम डॉक इमेज है। मैंने अभी तक रैम का परीक्षण नहीं किया है।
सलाअहदीन

32

अपने स्टैक को चलाएं और फिर एक शॉट डॉकटर-कंपोज़ रन कमांड से फायर करें। उदाहरण के लिए

#assume django in container named web
docker-compose run web python3 manage.py migrate

यह बिल्ट-इन (डिफ़ॉल्ट) SQLite डेटाबेस के लिए बहुत अच्छा काम करता है, लेकिन बाहरी डॉकटराइज़्ड डेटाबेस के लिए भी जो निर्भरता के रूप में सूचीबद्ध है। यहाँ एक उदाहरण 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

https://docs.docker.com/compose/reference/run/


12

आप docker execकमांड का उपयोग कर सकते हैं

docker exec -it container_id python manage.py migrate

1
इसका उत्तर होना चाहिए।
Tolga

कंटेनर_ड का उल्लेख करने के लिए, करें docker psऔर फिर django सर्वर के लिए स्तंभ COMMAND देखें।
जय शर्मा

5

अगर आपके अंदर भी कुछ ऐसा है 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

2

मुझे पता है कि यह पुराना है, और शायद मैं यहां कुछ याद कर रहा हूं (यदि ऐसा है, तो कृपया मुझे बताएं!), लेकिन क्यों न केवल अपने start.shस्क्रिप्ट में कमांड्स जोड़ दें , डॉक द्वारा आपके उदाहरण को आग लगाने के लिए चलाएं। इसमें कुछ अतिरिक्त सेकंड ही लगेंगे।

NB मैंने 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

1

Docker exec का प्रयोग करने पर, मुझे निम्नलिखित त्रुटि मिल रही थी:

AppRegistryNotReady("Models aren't loaded yet.")

इसलिए मैंने इस आदेश का उपयोग किया:

docker-compose -f local.yml run django python manage.py makemigrations
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.