docker-compose — API + PostgreSQL + Redis bir yerda
Muammodan boshlaylik
API ishlashi uchun kerak: PostgreSQL, Redis va API ning o'zi. Har birini alohida docker run bilan:
docker network create dokon-net
docker run -d --name db --network dokon-net -e POSTGRES_PASSWORD=... -v pgdata:/var/lib/postgresql/data postgres:17
docker run -d --name redis --network dokon-net redis:7
docker run -d --name api --network dokon-net -p 5000:8080 -e ConnectionStrings__Dokon=... dokon-api
Uzun buyruqlar, tartibni eslab qolish, yangi dasturchi uchun yarim kunlik sozlash. Bittasida xato — hech narsa ishlamaydi.
Hayotiy o'xshatma
Orkestr dirijyori va partitura. Har bir musiqachini alohida chaqirib "sen skripka chal, sen keyin baraban" deb tushuntirish o'rniga — bitta partitura: kim, qachon, qaysi asbobda. Dirijyor bitta ishora bilan butun orkestrni boshlaydi va to'xtatadi. docker-compose.yml — sizning partiturangiz.
compose.yaml
services:
api:
build:
context: .
dockerfile: Dokon.Api/Dockerfile
ports:
- "5000:8080"
environment:
ASPNETCORE_ENVIRONMENT: Development
ConnectionStrings__Dokon: "Host=db;Port=5432;Database=dokon;Username=dokon;Password=${DB_PAROL}"
ConnectionStrings__Redis: "redis:6379"
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
restart: unless-stopped
db:
image: postgres:17
environment:
POSTGRES_DB: dokon
POSTGRES_USER: dokon
POSTGRES_PASSWORD: ${DB_PAROL}
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432" # lokal vositalar (DBeaver) uchun; production da olib tashlang
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dokon -d dokon"]
interval: 5s
timeout: 3s
retries: 10
redis:
image: redis:7
volumes:
- redisdata:/data
volumes:
pgdata:
redisdata:
# .env — compose bilan bir papkada, git ga QO'SHILMAYDI
DB_PAROL=lokal-uchun-parol-123
Asosiy tushunchalar
Tarmoq — compose barcha servislarni bitta tarmoqqa qo'yadi; ular bir-birini servis nomi bilan topadi: Host=db, redis:6379. localhost emas!
Volume — pgdata konteyner o'chirilsa ham ma'lumot saqlanadi. Volume siz docker compose down — butun baza yo'qoladi.
depends_on + service_healthy — API faqat PostgreSQL tayyor bo'lgandan keyin ishga tushadi (faqat konteyner boshlangani emas).
${DB_PAROL} — .env faylidan yoki muhitdan olinadi.
Buyruqlar
docker compose up -d # hammasini ishga tushirish (fon rejimida)
docker compose up -d --build # API image ini qayta qurib
docker compose ps # holat
docker compose logs -f api # API log lari
docker compose exec db psql -U dokon -d dokon
docker compose restart api
docker compose down # to'xtatish va konteynerlarni o'chirish (volume lar qoladi)
docker compose down -v # volume lar bilan — BAZA O'CHADI
Migratsiyalar
API ishga tushganda bazani yangilash usullari:
// 1) ishga tushishda (kichik loyihalar, bitta nusxa)
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<DokonDbContext>();
await db.Database.MigrateAsync();
}
# 2) alohida qadam — SQL skript yoki migration bundle (tavsiya)
dotnet ef migrations bundle -o efbundle
./efbundle --connection "Host=...;..."
[!WARNING] Bir nechta API nusxasi bir vaqtda
MigrateAsyncchaqirsa — migratsiyalar to'qnashishi mumkin. Production da migratsiyani deploy jarayonining alohida qadami sifatida, bitta marta bajaring (bundle yoki idempotent SQL skript:dotnet ef migrations script --idempotent).
Development va production fayllari
compose.yaml asosiy
compose.override.yaml lokal — avtomatik qo'shiladi (portlar, debug)
compose.prod.yaml production farqlari
docker compose up -d # compose.yaml + override
docker compose -f compose.yaml -f compose.prod.yaml up -d # production
# compose.prod.yaml
services:
api:
environment:
ASPNETCORE_ENVIRONMENT: Production
deploy:
resources:
limits:
memory: 512M
db:
ports: !reset [] # bazani tashqariga ochmaslik
Qo'shimcha servislar
seq:
image: datalust/seq
environment:
ACCEPT_EULA: "Y"
ports:
- "5341:80"
Markaziy log (66-dars), pgAdmin, mail sinovchi (Mailpit) — har biri bir necha qator.
[!TIP] Faqat bog'liqliklarni (
db,redis) compose da ishga tushirib, API ni IDE dan debug bilan ishlatish — lokal ishlab chiqish uchun eng qulay variant:docker compose up -d db redis. Connection string da u holdaHost=localhost.
[!INFO] .NET Aspire — xuddi shu vazifani C# kodi bilan bajaruvchi yangi vosita: AppHost loyihasida
builder.AddPostgres("db"),builder.AddRedis("cache")— konteynerlarni ishga tushiradi, connection string larni avtomatik uzatadi va boshqaruv paneli (log, trace, metrikalar) beradi.
Tez-tez uchraydigan xatolar
Host=localhost konteyner ichida — API o'zini qidiradi; servis nomi db.
depends_on sharti yo'q — API baza tayyor bo'lmasdan ishga tushib yiqiladi.
.env git da — parollar oshkor; .gitignore ga va .env.example (qiymatlarsiz) ni git ga.
down -v tasodifan — lokal baza ma'lumotlari yo'qoladi.
Xulosa
docker-compose — bir nechta konteynerni bitta faylda tavsiflash va bitta buyruq bilan boshqarish. services: build yoki image, ports, environment, volumes, depends_on (service_healthy + healthcheck). Servislar bir-birini nomi bilan topadi (Host=db), volume — ma'lumotni saqlaydi, .env — maxfiy qiymatlar.
up -d, logs -f, exec, down (-v — ehtiyot). Migratsiya — production da alohida qadam (bundle, idempotent skript). Override fayllar — muhitlar farqi. Muqobil — .NET Aspire.
Keyingi dars
82-dars: Environment va Secrets — production sozlamalar, secret management