# Norden — Docker yerel prova paketi

Tarih: 13 Eylül 2026

Bu paket G-14'ün tamamlanmış yerel Docker provasıdır. Production kurulumu değildir; tam SQLite-to-PostgreSQL taşıma provası 14 Eylül'de ayrıca tamamlanmış ve [[15-SQLITE-POSTGRESQL-GUVENLI-TASIMA]] içinde kaydedilmiştir.

## 14 Eylül kurulum durumu

- `D:\Docker\Docker Desktop Installer.exe` mevcut; Windows imzası geçerli ve imzalayan `Docker Inc`. SHA-256: `2ECC54255702FFBF2E2779CB35EBECDE535A0B31E4223171BE2195DC318EBD3D`.
- D diskinde ölçüm sırasında yaklaşık 734,4 GB boş alan vardı.
- Docker Desktop 4.90.0, Linux Engine 29.7.2 ve Compose 5.5.1 çalışır durumda doğrulandı. Etkin context `desktop-linux`.
- WSL 2.7.14 ve `docker-desktop` dağıtımı sürüm 2 üzerinde çalışıyor.
- Program dosyalarını `D:\Docker` altına kurmak, Linux container/image diskini otomatik olarak D diskine taşımaz. Kurulum seçeneğinde `--wsl-default-data-root` verilmesi veya kurulumdan sonra Docker Desktop içindeki disk imajı konumunun ayrıca D diskine alınması gerekir.
- Docker veri konumu kullanıcı tarafından `D:\Docker\data` olarak kaydedildi. Doğrulamada ana disk `D:\Docker\data\DockerDesktopWSL\disk\docker_data.vhdx` altında bulundu; eski C diski veri klasöründe dosya kalmadı.
- `.env.docker` bağımsız rastgele prova değerleriyle oluşturuldu, Git tarafından ignore edildi ve değerler çıktıya yazılmadı. Compose yapılandırması gerçek Docker Compose ile temiz doğrulandı.
- Kurulum ve lisans kabulü kullanıcı tarafından yürütülüyor; bu çalışma kurucuyu çalıştırmadı veya sistem bileşeni değiştirmedi.

## 14 Eylül Docker prova sonucu

- `norden-tools:rehearsal` ve `norden-web:rehearsal` Linux imajları başarıyla üretildi; Next.js production build içinde TypeScript ve 46/46 sayfa üretimi geçti.
- PostgreSQL 17 container'ı sağlıklı başladı; `20260907000000_init` migration'ı başarıyla uygulandı.
- Kayıtlı katalog snapshot'ı boş PostgreSQL'e yüklendi: 131 ürün, 272 ürün görseli, 7 seri ve 48 pazar kaydı. Pazarların 40'ı etkin hedef, 8'i pasif eski kayıttır.
- Web ve Nginx çalıştı. TR/EN/RU ana sayfaları, ürün/seri rotaları, katalog PDF'si, katalog kapağı ve iki dünya haritası HTTP 200 döndü.
- `/admin` ve `/api/admin/upload` Nginx sınırında 403 döndü. Proxy üzerinden `/api/health` tasarım gereği 404; container içi healthcheck geçti.
- PostgreSQL hosta yayınlanmadı; yalnız container ağı içindeki `5432/tcp` mevcut. `norden_app` rolünde superuser, veritabanı oluşturma ve rol oluşturma yetkileri false doğrulandı.
- PostgreSQL, web ve proxy yeniden başlatıldı. Sonrasında web tekrar 200 verdi ve 131 ürün / 40 etkin / 8 pasif pazar sayıları korundu.
- Ana Docker sanal diski prova sonunda D sürücüsünde yaklaşık 9,02 GB idi. Hiçbir volume silinmedi.

## 13 Eylül yerel doğrulaması

- Next.js standalone build ve derleme içindeki TypeScript kontrolü geçti; 46/46 sayfa üretildi.
- Üretilen `server.js` 3100 portunda gerçek yerel SQLite ile çalıştı. `/tr`, `/en/collections/nero`, logo ve katalog PDF 200 döndü; oturumsuz admin isteği login'e yönlendi.
- `/api/health` sağlıklı DB'de 200 ve `no-store`; erişilemeyen PostgreSQL adresiyle ayrı sunucuda yalnız `{"status":"unavailable"}` gövdesiyle 503 döndü.
- Yedi seri × üç dil, 12 temsilî ürün rotası ve 272 görsel varlığı kabul kontrolü geçti. Altı rotanın JS/cache performans bütçesi geçti.
- Compose YAML statik kontrolüne ek olarak gerçek `docker compose config --quiet` doğrulaması geçti. Bu henüz imaj build veya çalışan container testi değildir.
- Prova ortam dosyası üreticisi ayrı geçici klasörde test edildi: üç bağımsız rastgele değer üretti; ikinci çağrıda var olan dosyayı değiştirmedi ve değerlere loglarda yer vermedi. Test dosyası temizlendi; gerçek `.env` değiştirilmedi.

Yerel standalone build, Next.js davranışı gereği yerel `.env` dosyasını `.next/standalone` içine kopyalayabilir; bu klasör paylaşılmaz. Docker build ise ayrı Linux ortamında yapılır ve `.dockerignore` tüm `.env` dosyalarını dışarıda tutar. Container kabulünde son imajın secret/DB içermediği ayrıca doğrulanacaktır.

## Hazırlanan yapı

| Parça | İşlev |
|---|---|
| `Dockerfile` | Node 22 / Debian üzerinde Linux bağımlılıkları ve iki Prisma istemcisi üretir. Ayrı araç ve root olmayan standalone web imajı oluşturur. |
| `.dockerignore` | Yalnız gerekli kaynakları kabul eder; yerel `.env`, DB, kaynak görseller ve upload dosyaları build bağlamına girmez. |
| `compose.rehearsal.yml` | İzole PostgreSQL, migration, isteğe bağlı seed, web ve Nginx servislerini tanımlar. Yalnız `127.0.0.1:8080` hosta açılır. |
| `deploy/postgres-init.sql` | Uygulama için superuser olmayan `norden_app` rolünü hazırlar. |
| `app/api/health/route.ts` | DB şema erişimini ölçer; başarılıysa 200, hata/zaman aşımında ayrıntı sızdırmadan 503 döner. R2 veya katalog tamlığı kontrolü değildir. |
| `deploy/nginx.conf` | HTTP akışını web'e taşır; admin yolları bu provada kapalıdır. |
| `scripts/init-docker-rehearsal.mjs` | Mevcut `.env` dosyasına dokunmadan bağımsız rastgele prova parolalarını `.env.docker` içine yazar. Var olan dosyanın üzerine yazmaz. |

Build sırasında `data/catalog.seed.json` yalnızca geçici SQLite build veritabanına yüklenir. Mevcut `dev.db` Docker imajına girmez. Normal prova başlangıç verisi kayıtlı katalog snapshot'ıdır; tam veri aktarımı ayrı, salt okunur bind ve güvenli taşıma aracıyla yalnız boş hedefe uygulanır.

## Uygulanan yerel prova sırası

Komutlar proje kökünde çalıştırılır. Docker Desktop/Linux engine ve Compose v2 gerekir. WSL çalıştırılabilir dosyasının bulunması WSL2 bileşeninin veya Docker motorunun hazır olduğunu kanıtlamaz.

```powershell
docker version
docker compose version
node scripts/init-docker-rehearsal.mjs
docker compose --env-file .env.docker -f compose.rehearsal.yml config --quiet
docker compose --env-file .env.docker -f compose.rehearsal.yml build
docker compose --env-file .env.docker -f compose.rehearsal.yml up -d db
docker compose --env-file .env.docker -f compose.rehearsal.yml run --rm migrate
docker compose --env-file .env.docker -f compose.rehearsal.yml --profile setup run --rm seed
docker compose --env-file .env.docker -f compose.rehearsal.yml up -d web proxy
docker compose --env-file .env.docker -f compose.rehearsal.yml ps
```

İlk seed yalnız boş katalog tablolarında çalışır. Sonraki açılışlarda seed tekrarlanmaz. Dolu hedefteki reddi aşmak için `--replace` eklenmez. `.env.docker` var olan volume kullanılırken yeniden üretilmez; DB ilk kurulum parolası sonraki environment değişikliğiyle kendiliğinden değişmez.

Kontrol adresi: `http://localhost:8080/tr`. TR/EN/RU, katalog PDF, görseller, filtreler ve ürün/seri sayıları kontrol edilir. `/admin` ve `/api/admin/...` için 403 beklenir. DB'nin hostta portu bulunmamalıdır. Healthcheck doğrudan container içinde çalışır; proxy `/api/health` için 404 döner.

```powershell
docker compose --env-file .env.docker -f compose.rehearsal.yml exec web node deploy/healthcheck.mjs
docker compose --env-file .env.docker -f compose.rehearsal.yml exec db psql -U norden_owner -d norden -c 'SELECT rolname, rolsuper, rolcreatedb, rolcreaterole FROM pg_roles;'
```

`norden_app` için üç yetki alanı da false olmalıdır. Beklenen snapshot: 131 ürün ve 272 ürün görseli. Kaynak snapshot değişirse sayılar snapshot manifestinden yeniden alınır. Gerçek PostgreSQL kabulünde tüm kayıt değerleri ve ilişkiler ayrıca karşılaştırılır.

Yalnız servisleri durdurmak için:

```powershell
docker compose --env-file .env.docker -f compose.rehearsal.yml stop
```

`down -v` kullanılmaz: kalıcı verileri siler. Bu belgedeki durdurma komutu volume silmez.

## Production öncesinde kalanlar

- Tam taşıma aracı geçti; production öncesinde son SQLite yedeği üzerinden staging ve production çalıştırması yapılacak. Eski admin oturumları taşınmayacak.
- Container yeniden **oluşturma** testi ve production geri dönüş senaryosu. Bu turda güvenli yeniden başlatma ve volume kalıcılığı doğrulandı; volume silinmedi.
- İmajları doğrulanmış digest ve Git release kimliğine sabitlemek. Prova etiketleri güncellenebilir etiketlerdir.
- Gerçek R2 bağlantısı ve CDN alan adıyla yeniden build. `MEDIA_CDN_URL`, Next image izin listesi için build sırasında da verilmelidir.
- HTTPS, domain, yönetici MFA/VPN/IP sınırı ve login/upload proxy limitleri. Admin bu HTTP prova dosyasında açılmaz.
- Production şifre deposu, yedek/restore ve dış güvenlik kabulü. Prova `.env.docker` production secret kaynağı olarak kullanılmaz.
- Çoklu imaj/build dağıtımında Server Actions anahtar stratejisi. Tek build'in kendi anahtarı bu imajda kullanılır; ayrı release build'leri aynı anahtarı paylaşmış sayılmaz.
- Güvenlik başlıkları ve CSP'nin gerçek CDN/harita/PDF/video akışlarıyla staging kontrolü.

Kaynaklar: [Next.js output](https://nextjs.org/docs/app/api-reference/config/next-config-js/output), [Compose başlangıç sırası](https://docs.docker.com/compose/how-tos/startup-order/), [Docker build secrets](https://docs.docker.com/build/building/secrets/), [PostgreSQL resmi imajı](https://hub.docker.com/_/postgres).
