Mehmet Yerli

Mehmet Yerli

Maden Mühendisi & Yazılım Geliştirme Uzmanı

PostgreSQL'i Docker ile Kurma ve Django'ya Entegre Etme

PostgreSQL'i Docker'da çalıştırırken verinin nerede kalacağını ve portun nereye açılacağını önce belirliyorum. Ardından Django'nun gerçekten bağlandığını bir migration ve küçük bir okuma/yazma işlemiyle kontrol ediyorum. Konteynerin çalışması tek başına bu adımları doğrulamıyor.

Bu dizin sitenin uygulamasından bağımsız, yalnız sentetik example_local verisini kullanan küçük bir Django projesidir. Üretim .env, ayarlar veya veri kullanılmaz. Bir önceki denemeye ait aynı adlı Docker projesi/volume varsa bu temiz kurulum sayılmaz; önce onun sahipliğini ve verisini inceleyin. Port 5433 boş olmalı.

Dosyaları edinme ve hazırlık

Bu dizindeki bütün dosyaları birlikte yeni bir dizine kopyalayın. Yalnız Markdown içindeki kod parçalarını kopyalamak migration dosyasını sağlamaz. Tam örnek paketini indirin ve postgresql-django dizinini kullanın.

Gerekenler: Python 3.13, Docker Desktop veya Docker Engine + Compose. Kurulumda Python paketleri ve resmi container imajları indirilir. Rehber 7 Ekim 2026'da macOS/arm64 üzerinde Docker Desktop 4.92.0, Engine 29.8.0 ve Compose 5.5.1 ile sınandı. Host Python 3.13.3, container Python 3.13.16, Django 5.2.16, psycopg2-binary 2.9.12, python-dotenv 1.1.1 ve PostgreSQL 17.11 kullanıldı. Geçişli bağımlılıklar da requirements.txt içinde sabitlendi. İmaj digest'leri compose.yaml/Dockerfile içindedir.

Yeni örnek dizininin içinde:

python3.13 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python init_env.py

Son komut Created .env.local (0600); values are not printed. döndürür. Parola ve Django secret her deneme için üretilir; mevcut dosyanın üzerine yazılmaz. .env.local.example yalnız değişken adlarını gösterir, kullanılabilir parola içermez. Ortam dosyasını paylaşmayın. Bu dizindeki manage.py, sitenin manage.py dosyası değildir.

Django bağlantı ayarı

Tam settings.py dosyası kendi dizinindeki .env.local dosyasını okur. required yardımcı fonksiyonu boş/placeholder değeri reddeder. Bağlantı ayarının özü:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "example_local",
        "USER": "example_local",
        "PASSWORD": required("LOCAL_POSTGRES_PASSWORD"),
        "HOST": required("LOCAL_DB_HOST"),
        "PORT": required("LOCAL_DB_PORT"),
        "OPTIONS": {"connect_timeout": 3},
    }
}

Host üzerinde değerler 127.0.0.1 ve 5433; aynı Compose ağı içindeki Django için db ve 5432. Container içindeki localhost host'taki veritabanı değildir.

Host üzerinde Django

DB servisinin temel düzeni:

services:
  db:
    image: postgres:17@sha256:ae69c452f483507a6b99fb654cf93aad7fe156ffd2c56247707eef4e36d3c12b
    environment:
      POSTGRES_DB: example_local
      POSTGRES_USER: example_local
      POSTGRES_PASSWORD: ${LOCAL_POSTGRES_PASSWORD:?python init_env.py ile yerel parola olusturun}
    ports:
      - "127.0.0.1:5433:5432"
    volumes:
      - postgres_local:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U example_local -d example_local"]
      interval: 2s
      timeout: 3s
      retries: 15
volumes:
  postgres_local:

postgres:17 major etiketi tek başına değişebilir; burada gerçek sınanan build digest ile sabit. Host portu yazılmazsa Docker varsayılan olarak bütün arayüzlerde yayımlar; loopback ve eski Engine istisnası için aşağıdaki port belgesine bakın.

docker compose --project-name example-postgresql-django-local --env-file .env.local up -d --wait --wait-timeout 45 db
.venv/bin/python manage.py migrate --noinput
.venv/bin/python manage.py smoke

DB healthcheck'in geçmesi beklenir; migration Applying notes.0001_initial... OK yazar. Boş volume'de ilk smoke sonucu:

{"count": 1, "created": true, "postgresql": "17.11 (Debian 17.11-1.pgdg13+2)", "text": "yerel-deneme"}

smoke, Django ORM ile bir satır yazar, DB'den yeniden okur ve SHOW server_version çalıştırır. Tekrar çalıştırıldığında created: false, count: 1 beklenir. Başka sentetik satır eklediyseniz count değişebilir.

settings.py yalnız bu dizinin .env.local dosyasını okur; shell'de aynı adlı değişken varsa shell değeri önceliklidir. Başka projeye ait değişkenleri bu terminale taşımayın. DB adı/kullanıcı example_local olarak sabit; adres yalnız 127.0.0.1:5433 veya db:5432 olabilir. Yanlış veya eksik yerel değer açık hata verir.

Compose içinde Django

docker compose --project-name example-postgresql-django-local --env-file .env.local build app
docker compose --project-name example-postgresql-django-local --env-file .env.local run --rm app python manage.py migrate --noinput
docker compose --project-name example-postgresql-django-local --env-file .env.local run --rm app python manage.py smoke

Host adımları tamamlandıysa migration No migrations to apply. yazar; smoke aynı satırı created: false ile okur. Compose app servisi host varsayılanlarını LOCAL_DB_HOST=db, LOCAL_DB_PORT=5432 ile değiştirir. Aynı volume'ü kullanır; ikinci bir veritabanı oluşturmaz.

Sınırlar ve teşhis

Belirti Kontrol ve sonraki adım
Connection refused Docker hizmetini, docker compose --project-name example-postgresql-django-local --env-file .env.local ps ve DB loglarını kontrol edin. up -d --wait --wait-timeout 45 db ile hazır olmasını bekleyin. Host için 127.0.0.1:5433, container için db:5432 gerekir.
LOCAL_POSTGRES_PASSWORD is missing a value --env-file .env.local yolunu ve init_env.py adımını kontrol edin. Compose, eksik parola ile DB oluşturmayı reddeder.
Missing local value: ... Django'nun bu dizindeki ortam dosyasını okuduğunu kontrol edin. Shell'de boş aynı adlı değişken dosyadaki değeri bastırır. Placeholder kullanmayın.
password authentication failed Mevcut volume ilk kurulumdaki rol parolasını taşır. Ortam dosyasını değiştirmek rol parolasını değiştirmez. Önce doğru yerel parolayı bulup kullanın; veriye ihtiyacınız varsa volume'ü silmeyin.
port is already allocated 5433 başka servis tarafından kullanılıyor. Bu örnek sabit adres çiftiyle sınırlı; başka servisi gelişigüzel durdurmayın.

POSTGRES_USER ile oluşturulan ilk kullanıcı yüksek yetkilidir; üretim için uygulama rolü tasarımı değildir. PostgreSQL 17 için volume yolu /var/lib/postgresql/data; 18+ resmi imajında düzen değişir. Bu digest'i major yükseltme planı olmadan değiştirmeyin. Başlatma değişkenleri yalnız boş veri dizininde etkili olur. Healthcheck'teki pg_isready bağlantıya hazır olmayı gösterir; Django okuma/yazma doğrulaması ayrı adımdır.

docker compose --project-name example-postgresql-django-local --env-file .env.local down

Bu komut yalnız örnek projesinin container/ağını kaldırır, volume'ü korur. Aynı ortam dosyasıyla yeniden up -d --wait --wait-timeout 45 db ve smoke çalıştırınca satır kalır. Volume yedek değildir; bu rehber veri silme/reset komutu içermez.

Test edilen sonuç ve kaynaklar

Temiz kopya ve yeni volume üzerinde host migration + ilk yazma, Compose migration + aynı satırı okuma geçti. down sonrası volume korunarak tekrar başlatma sınandı. Bağlantı reddi, eksik Django/Compose parola değeri ve mevcut volume'e yanlış parola teşhisleri gerçek hata çıktısıyla sınandı. Windows, Linux host ve amd64 container çalıştırılmadı; bu sonuçlar o ortamlar için doğrulama değildir.