Docker — Dockerfile, .dockerignore, image yaratish, container
Muammodan boshlaylik
Lokal kompyuteringizda API mukammal ishlaydi. Serverga qo'yasiz:
- Serverda .NET 8, sizda .NET 9 — ilova ishga tushmaydi
- Kerakli kutubxona (ICU,
libgdiplus) o'rnatilmagan - Muhit o'zgaruvchilari boshqacha
- Ikkinchi serverga o'rnatishda hammasini qo'lda qaytadan sozlash
"Mening kompyuterimda ishlaydi" — eng mashhur dasturchi bahonasi.
Docker nima?
Konteyner — ilova va uning barcha bog'liqliklari (runtime, kutubxonalar, sozlamalar) bitta paketda. U istalgan Docker o'rnatilgan mashinada bir xil ishlaydi.
- Image — o'zgarmas shablon (retsept + ingredientlar)
- Container — image dan ishga tushirilgan jarayon
- Dockerfile — image qanday quriladi, ko'rsatmalar
Hayotiy o'xshatma
Yuk konteynerlari. Ilgari kemaga yuk yuklash — qop, quti, bochkalarni birma-bir joylash; har bir portda boshqacha. Standart konteyner ixtiro qilingach — ichida nima bo'lishidan qat'i nazar, u istalgan kema, poyezd va yuk mashinasiga bir xil kran bilan yuklanadi. Docker image — dasturiy ta'minot uchun standart konteyner.
Dockerfile — multi-stage
# 1-bosqich: build — to'liq SDK bilan
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
# avval faqat loyiha fayllari — restore qatlami keshlanadi
COPY ["Dokon.Api/Dokon.Api.csproj", "Dokon.Api/"]
RUN dotnet restore "Dokon.Api/Dokon.Api.csproj"
# keyin butun kod
COPY . .
RUN dotnet publish "Dokon.Api/Dokon.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false
# 2-bosqich: runtime — faqat ishga tushirish uchun kerakli
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS final
WORKDIR /app
COPY --from=build /app/publish .
USER $APP_UID
EXPOSE 8080
ENTRYPOINT ["dotnet", "Dokon.Api.dll"]
| Bosqich | Image | Hajmi (taxminan) |
|---|---|---|
| build | sdk — kompilyator, NuGet, vositalar |
~800 MB |
| final | aspnet — faqat runtime |
~220 MB |
Yakuniy image da faqat final bosqichi qoladi — SDK va manba kodi yo'q.
[!INFO] .NET 8+ image lari sukut bo'yicha 8080 portda tinglaydi (avval 80 edi) va ichida oddiy
appfoydalanuvchisi bor —USER $APP_UIDilovani root huquqisiz ishga tushiradi. Bu xavfsizlik uchun muhim: konteyner buzilsa ham, hujumchi root bo'lmaydi.
.dockerignore
**/bin/
**/obj/
**/.vs/
**/.vscode/
**/*.user
**/node_modules/
**/appsettings.Development.json
.git/
Dockerfile
docker-compose*.yml
*.md
Keraksiz fayllar build kontekstiga tushmaydi — tezroq build, maxfiy fayllar image ga kirmaydi.
Build va ishga tushirish
docker build -t dokon-api:1.0 .
docker images
docker run -d \
--name dokon-api \
-p 5000:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e ConnectionStrings__Dokon="Host=db.server;Database=dokon;Username=app;Password=..." \
dokon-api:1.0
-p 5000:8080— kompyuterning 5000 porti konteynerning 8080 portiga-e— muhit o'zgaruvchisi;__(ikki pastki chiziq) — konfiguratsiyadagi:(ichma-ich kalit)
docker logs -f dokon-api # konsol log lari (66-dars)
docker ps # ishlayotgan konteynerlar
docker exec -it dokon-api sh # konteyner ichiga kirish
docker stop dokon-api && docker rm dokon-api
SDK bilan Dockerfile siz (.NET 8+)
dotnet publish --os linux --arch x64 -c Release /t:PublishContainer
.csproj da:
<PropertyGroup>
<ContainerRepository>dokon-api</ContainerRepository>
<ContainerImageTag>1.0</ContainerImageTag>
</PropertyGroup>
.NET SDK o'zi optimallashtirilgan image yaratadi. Oddiy loyihalar uchun qulay; murakkab build qadamlari kerak bo'lsa — Dockerfile.
Health check
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:8080/health/live || exit 1
aspnet image ida curl va wget bo'lmasligi mumkin — kerak bo'lsa o'rnating yoki orkestrator (Kubernetes) darajasidagi probe lardan foydalaning (74-dars).
Kichikroq image lar
| Image | Xususiyati |
|---|---|
aspnet:9.0 |
Debian asosida, standart |
aspnet:9.0-alpine |
Kichikroq (~110 MB) |
aspnet:9.0-noble-chiseled |
Ubuntu "chiseled" — shell va paket menejerisiz, minimal hujum yuzasi |
[!TIP] Production uchun chiseled image lar — ularda shell ham, paket menejeri ham yo'q: hujumchi konteynerga kirsa ham, deyarli hech narsa qila olmaydi. Native AOT bilan esa
runtime-depsimage ida o'nlab MB gacha kichraytirish mumkin.
Tez-tez uchraydigan xatolar
Port mos emas — ilova 8080 da tinglaydi, -p 5000:80 — ulanib bo'lmaydi.
Konteyner ichida localhost ga ulanish — konteyner uchun localhost — o'zi; bazaga host nomi yoki docker-compose servis nomi bilan (81-dars).
Maxfiy ma'lumot image da (COPY appsettings.Production.json parollar bilan, ENV Password=...) — image ni olgan har kim o'qiydi; muhit o'zgaruvchilari yoki secrets (82-dars).
COPY . . restore dan oldin — har bir kod o'zgarishida paketlar qayta yuklanadi.
Xulosa
Docker — ilova va barcha bog'liqliklarni image ga joylash: istalgan joyda bir xil ishlaydi. Multi-stage Dockerfile: sdk da restore va publish, aspnet da faqat natija — kichik va xavfsiz image. Avval .csproj va restore — qatlam keshlanadi.
.dockerignore; docker build -t, docker run -p 5000:8080 -e ...; __ — ichma-ich konfiguratsiya kaliti. .NET 8+: port 8080, USER $APP_UID. Muqobil — dotnet publish /t:PublishContainer. Chiseled image lar; maxfiy ma'lumot image ga kirmasin.
Keyingi dars
81-dars: docker-compose — API + PostgreSQL + Redis bir yerda