Docker-Compose kullanırken Django veritabanı geçişlerini nasıl gerçekleştirirsiniz?


112

Docker sitesindeki Django Hızlı Başlangıç ​​talimatlarını yakından takip ederek bir Docker Django / PostgreSQL uygulaması kurdum .

Django'nun manage.py migrate komutunu kullanarak ilk çalıştırdığımda sudo docker-compose run web python manage.py migratebeklendiği gibi çalışıyor. Veritabanı, Docker PostgreSQL kapsayıcısının içinde oluşturulmuştur.

Django uygulamasının kendisinde yapılan değişiklikler, onları kaydettiğim anda Docker Django konteynerine de aynı şekilde yansıtılıyor. Bu harika!

Ancak daha sonra Django'da bir modeli değiştirirsem ve Postgres veritabanını modelle eşleşecek şekilde güncellemeye çalışırsam, hiçbir değişiklik algılanmaz, bu nedenle kaç kez çalıştırsam makemigrationsveya migratetekrar çalıştırsam da geçiş olmaz .

Temel olarak, Django modelini her değiştirdiğimde, Docker konteynerlerini silmem (kullanarak sudo docker-compose rm) ve yeni bir geçişle yeniden başlamam gerekiyor.

Hâlâ Docker'ın etrafından dolaşmaya çalışıyorum ve nasıl çalıştığına dair anlamadığım çok şey var, ama bu beni deli ediyor. Neden değişikliklerimi taşıma işlemi görmüyor? Neyi yanlış yapıyorum?


Neden olduğunu anladın mı? Aşağıdaki cevabı aldım ve işe yarıyor: You just have to log into your running docker container and run your commands.ama bu şekilde davranmasının nedeni nedir? @LouisBarranqueiro
lukik

Yanıtlar:


119

Çalışan docker konteynerinizde oturum açmanız ve komutlarınızı çalıştırmanız yeterlidir.

  1. Yığınınızı oluşturun: docker-compose build -f path/to/docker-compose.yml
  2. Yığınınızı başlatın: docker-compose up -f path/to/docker-compose.yml
  3. Docker çalışan kapsayıcıları görüntüleyin: 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 uygulamanızın KONTEYNER KIMLIĞINI alın ve şurada oturum açın:
docker exec -t -i 66175bfd6ae6 bash
  1. Şimdi giriş yaptınız, ardından doğru klasöre gidin: cd path/to/django_app

  2. Ve şimdi, modellerinizi her düzenlediğinizde, kapsayıcınızda çalıştırın: python manage.py makemigrationsvepython manage.py migrate

Ayrıca django docker konteyner dosyanızın otomatik olarak çalışması için bir docker-inputpoint kullanmanızı tavsiye ederim:

  • Kolleksiyon
  • göç
  • runserver veya gunicorn veya uWSGI ile başlatın

İşte bir örnek ( 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

17
Ayrıca django docker konteyner dosyanızın otomatik olarak çalışması için bir docker-entrypoint kullanmanızı tavsiye ederim - bu tür işlemler asla otomatik olarak çalıştırılmamalıdır - özellikle migrate demek istiyorum .
Opal

7
Hangi ortamda olduğunuz önemli değil - dağıtım her zaman aynı görünmelidir. Taşıma işlemleri otomatik ise, eşzamanlı olarak çalıştırılabilir ve bu kesinlikle önerilmez. Örneğin, heroku'da - taşımalar asla dağıtımın bir parçası olarak çalıştırılmaz.
Opal

5
aynı anda mı? İşte bir dev ortamındayız. Ben koşarım makemigrations. yığınımı bir dahaki sefere başlattığımda, migrategeri alınan son geçişler ile veritabanını güncelleyeceğim, aksi takdirde django uygulaması düzgün çalışmayacak ... Mevcut uygulamayla doğru veritabanı şemasına sahip olduğunuzdan emin olmak için sadece dev env içinde bir kısayol
Louis Barranqueiro

2
@LouisBarranqueiro, birden çok örneği kastetmiştim, tek DB.
Opal

1
4. adım için şunu tavsiye ederim: docker exec -ti $ CONTAINER_ID / bin / sh
Santiago Magariños

52

Bu yöntemi kullanıyorum:

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

dockerYaptığımız hiyerarşiyi kullanarak , servis geçişi, veritabanı kurulduktan sonra ve ana servisi çalıştırmadan önce çalışır. Artık çalıştırdığınızda, hizmetiniz dockersunucuyu çalıştırmadan önce geçişleri çalıştıracaktır; migrationsunucunun web sunucusuyla aynı görüntü üzerine uygulandığına bakın , bu, tüm geçişlerin projenizden alınacağı ve sorunlardan kaçınıldığı anlamına gelir.

Bu şekilde giriş noktası veya başka bir şey yapmaktan kaçınırsınız.


3
Yok nasıl build: .birlikte çalışma image: I göç adında görüntüyü çekemez o hatayı alıyorum
Aaron McMillin

2
Ben koyarak çözüldü build:üzerinde migrationönce çalışacağını beriweb
Aaron McMillin

5
Bu, uzman imajının sürekli çalışmasını ve RAM'i sonsuza kadar tüketmesini sağlamaz mı? Ayrıca, hangi olduğu uzman görüntü?
mlissner

Bu benim özel docker imajım, RAM'i henüz test etmedim.
SalahAdDin

35

Yığınınızın çalışmasını sağlayın ve ardından tek seferlik bir docker-compose run komutunu çalıştırın. Örneğin

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

Bu, yerleşik (varsayılan) SQLite veritabanı için ve ayrıca bağımlılık olarak listelenen harici bir dockerize veritabanı için harika çalışır. İşte örnek bir docker-compose.yaml dosyası

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/


13

docker execKomutu kullanabilirsiniz

docker exec -it container_id python manage.py migrate

1
Cevap bu olmalı.
tolga

Bahsedilen kapsayıcı kimliği elde etmek için, yapın docker psve sonra django sunucusu için COMMAND sütununu arayın.
Jai Sharma

6

Eğer içinde böyle bir şey varsa 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

O zaman basitçe koşabilirsiniz ...

~$ docker-compose exec app python manage.py makemigrations
~$ docker-compose exec app python manage.py migrate

3

Bunun eski olduğunu biliyorum ve belki burada bir şeyi kaçırıyorum (eğer öyleyse, lütfen beni aydınlatın!), Ama neden komutlarınızı start.shkomut dosyanıza eklemiyorsunuz, örneğinizi çalıştırmak için Docker tarafından çalıştırılsın? Yalnızca birkaç saniye daha sürecektir.

NotDJANGO_SETTINGS_MODULE Geliştirme ve üretim için farklı veritabanları kullandığım için (bunun 'en iyi uygulama' olmadığını bilmeme rağmen) doğru veritabanının kullanıldığından emin olmak için değişkeni ayarlıyorum .

Bu benim için çözdü:

#!/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 kullanarak şu hatayı alıyordum:

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

Bunun yerine şu komutu kullandım:

docker-compose -f local.yml run django python manage.py makemigrations
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.