Instruksiyalar — WORKDIR, ENV, ARG, EXPOSE, USER, ENTRYPOINT
Muammodan boshlaylik
O'tgan darsdagi Dockerfile ishlaydi. Lekin savollar:
- Ilova
rootsifatida ishlayapti — xavfsizmi? - Build paytida versiya raqamini qanday uzatish kerak?
CMDvaENTRYPOINT— farqi nima?- Konteyner "tirik", lekin ilova qotib qolgan — Docker buni qanday biladi?
Bu darsda Dockerfile ning qolgan muhim instruksiyalarini ko'ramiz.
ENV — muhit o'zgaruvchilari
ENV NODE_ENV=production \
PORT=3000
Build paytida ham (RUN larda), konteyner ishlaganda ham mavjud. Standart qiymat sifatida — docker run -e PORT=8080 uni almashtiradi (10-dars).
[!WARNING] Maxfiy qiymatlar (parol, kalit) —
ENVda hech qachon. Ular image qatlamida qoladi vadocker inspect/docker historyda ko'rinadi.
ARG — build vaqtidagi o'zgaruvchilar
ARG NODE_VERSION=22
FROM node:${NODE_VERSION}-alpine
ARG APP_VERSION=dev
ENV APP_VERSION=${APP_VERSION}
docker build --build-arg NODE_VERSION=20 --build-arg APP_VERSION=1.4.2 -t ilova:1.4.2 .
ARG |
ENV |
|
|---|---|---|
| Qachon mavjud | Faqat build paytida | Build va ishlash paytida |
| Qanday beriladi | --build-arg |
-e (run) yoki Dockerfile |
| Konteynerda ko'rinadimi | Yo'q (agar ENV ga ko'chirilmasa) | Ha |
ARG ham maxfiy ma'lumot uchun emas — u docker history da ko'rinadi. Build paytidagi maxfiy ma'lumot (masalan, xususiy npm token) — RUN --mount=type=secret (39-dars).
EXPOSE — qaysi port
EXPOSE 3000
Faqat hujjat (9-dars): "bu image 3000-portni tinglaydi". Portni ochmaydi — -p kerak. Lekin yozing: Dockerfile ni o'qigan odam darhol tushunadi.
USER — root siz ishlash
Standart holatda konteyner ichidagi jarayon — root. Ilovada zaiflik topilsa — hujumchi konteyner ichida root bo'ladi, va konteynerdan qochish zaifligi bilan birga — butun server.
FROM node:22-alpine
WORKDIR /app
COPY --chown=node:node package*.json ./
RUN npm ci --omit=dev
COPY --chown=node:node . .
USER node
CMD ["node", "src/index.js"]
- Rasmiy
nodeimage larida tayyornodefoydalanuvchisi bor USER node— undan keyingi barcha buyruqlar va konteyner jarayoni —nodesifatidaCOPY --chown=node:node— fayllarnodega tegishli bo'lsin (yozish kerak bo'lsa)
Boshqa image larda foydalanuvchi yaratish:
RUN addgroup -S ilova && adduser -S ilova -G ilova # Alpine
# RUN groupadd -r ilova && useradd -r -g ilova ilova # Debian
USER ilova
[!INFO] Root bo'lmagan foydalanuvchi 1024 dan kichik portlarni (80, 443) tinglay olmaydi. Ilovani 3000 yoki 8080 da ishga tushiring; tashqarida
-p 80:8080.
CMD va ENTRYPOINT
Ikkalasi ham "konteyner ishga tushganda nima bajarilsin". Farqi — docker run dagi argumentlar bilan munosabatda.
# Faqat CMD
CMD ["node", "server.js"]
docker run ilova # node server.js
docker run ilova sh # sh — CMD to'liq almashtirildi
# ENTRYPOINT + CMD
ENTRYPOINT ["node"]
CMD ["server.js"]
docker run ilova # node server.js
docker run ilova seed.js # node seed.js — faqat CMD qismi almashtirildi
ENTRYPOINT— doim bajariladigan dasturCMD— unga standart argumentlar
Image "bitta asbob" bo'lsa (CLI vosita) — ENTRYPOINT. Oddiy ilova — faqat CMD yetarli.
Exec va shell shakli
CMD ["node", "server.js"] # ✅ exec shakli — JSON massiv
CMD node server.js # ⚠️ shell shakli — /bin/sh -c "node server.js"
Shell shaklida asosiy jarayon — sh, Node emas. docker stop yuborgan SIGTERM signali Node ga yetib bormaydi — ilova to'g'ri yopilmaydi, Docker 10 soniya kutib, uni majburan o'ldiradi. Doim exec shakli (JSON massiv) ishlating.
Entrypoint skript
Ishga tushishdan oldin tayyorgarlik kerak bo'lsa (migratsiyalar, bazani kutish):
#!/bin/sh
# docker-entrypoint.sh
set -e
echo "Migratsiyalar..."
npx prisma migrate deploy
exec "$@" # ← CMD ni bajarish; exec — jarayon PID 1 bo'lib qolsin
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["node", "dist/main.js"]
exec "$@" — muhim: skript o'rniga ilova asosiy jarayon bo'ladi va signallarni oladi. Rasmiy mysql, postgres image lari aynan shu naqsh bilan ishlaydi.
HEALTHCHECK — ilova haqiqatan sog'lommi
Konteyner Up — lekin ilova qotib qolgan yoki baza ulanishini yo'qotgan bo'lishi mumkin. Docker buni bilmaydi.
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
Ilovada:
app.get('/health', (req, res) => res.json({ holat: 'ok' }));
docker ps
# STATUS: Up 2 minutes (healthy)
# STATUS: Up 5 minutes (unhealthy)
Compose (28-dars) va orkestratorlar unhealthy konteynerni qayta ishga tushiradi yoki unga trafik yubormaydi.
Alpine da curl yo'q — wget bor. Yoki Node ning o'zi bilan: CMD node -e "fetch('http://localhost:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))".
Boshqalari
LABEL org.opencontainers.image.source="https://github.com/kompaniya/ilova" \
org.opencontainers.image.version="1.4.2"
VOLUME /app/data # ma'lumot papkasi (19-dars; odatda Compose da beriladi)
SHELL ["/bin/bash", "-c"] # RUN uchun shell ni almashtirish
STOPSIGNAL SIGINT # stop paytida qaysi signal
ADD — COPY ga o'xshash, lekin URL dan yuklaydi va arxivlarni avtomatik ochadi. Kutilmagan xatti-harakat tufayli — oddiy nusxalash uchun doim COPY.
To'liq misol
FROM node:22-alpine
ARG APP_VERSION=dev
ENV NODE_ENV=production \
PORT=3000 \
APP_VERSION=${APP_VERSION}
WORKDIR /app
COPY --chown=node:node package.json package-lock.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --chown=node:node src/ ./src/
USER node
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "src/index.js"]
Nima uchun shunday?
Nima uchun exec shaklidagi CMD signallar uchun muhim?
Linux da konteynerning asosiy jarayoni — PID 1. docker stop faqat PID 1 ga SIGTERM yuboradi. Shell shaklida PID 1 — sh, va sh odatda signalni bolasiga (Node ga) uzatmaydi. Natijada ilova "ishni tugat" xabarini olmaydi: ochiq so'rovlar uziladi, bazaga yozilayotgan ma'lumot yarim qoladi, va har bir stop 10 soniya davom etadi. Exec shaklida Node — o'zi PID 1, signalni to'g'ridan-to'g'ri oladi va to'g'ri yopiladi (graceful shutdown).
Xulosa
Eslab qoling:
ENV— build va ishlash paytida;ARG— faqat build paytida (--build-arg)- Maxfiy ma'lumot —
ENVda ham,ARGda ham emas EXPOSE— hujjatUSER— root siz;COPY --chown; 1024 dan katta portlarENTRYPOINT— dastur,CMD— standart argumentlar- Doim exec shakli:
CMD ["node", "app.js"]; entrypoint skriptdaexec "$@" HEALTHCHECK— ilova haqiqatan ishlayaptimiCOPY,ADDemas
Keyingi dars
14-dars: Qatlamlar va kesh — tez build uchun tartib