Dockerfilelar yozish bo'yicha qo'llanma
Docker samaradorligining markazida Dockerfile yotadi - Docker imagelarini yaratish uchun ishlatiladigan asosiy skript. Ushbu fayllar takrorlanadigan va portativ konteynerli muhitni yaratish uchun zarur bo'lgan ko'rsatmalar va bog'liqliklarni qamrab oladi. O'rnatish jarayonini soddalashtirish va turli muhitlarda izchillikni ta'minlashga intilayotgan dasturchilar va DevOps muhandislari uchun samarali Dockerfilelarni qanday yaratishni tushunish juda muhimdir.
Ushbu qo'llanma Dockerfilelar qanday yozishni uni elementlarini ko'rib chiqamiz.
FROM
Dockerfiledagi FROM
instructioni sizning imagengiz asosida quriladigan asosiy imageni belgilash uchun ishlatiladi. Bu yangi konteyner imegaseni yaratish uchun boshlang'ich nuqtadir. Docker imageni yaratishni boshlaganingizda, odatda uni ma'lum muhit yoki funksiyalar to'plamini ta'minlaydigan mavjud imagega asoslashni xohlaysiz. FROM
instructioni ushbu asosiy imageni belgilaydi.
FROM <image>[:<tag>] [@<digest>]
#Node.js namunalar
FROM node
FROM node:18
FROM node@sha256:XXXXXX
image - bu yangi imagengizga asoslanmoqchi bo'lgan imagening nomi.
tag (ixtiyoriy) imagening muayyan versiyasi yoki variantini bildiradi. Agar belgilanmagan bo'lsa, u default bo'yicha latest
bo'ladi.
@digest (ixtiyoriy) sizga imageni uning content hashi (digest) bo'yicha belgilash imkonini beradi va bu imagega aniq mos kelishini ta'minlaydi.
MAINTAINER, LABEL
Dockerfile-dagi MAINTAINER
instructioni qurilayotgan imagening muallifi yoki maintainerini ko'rsatish uchun ishlatilgan. Biroq, bu instruction iamge haqidagi metamaʼlumotlar, jumladan, texnik maʼlumotlar bilan taʼminlash uchun LABEL
dan foydalanish foydasiga eskirgan.
Maintainerni ko'rsatish uchun LABEL
dan qanday foydalanish mumkinligiga misol:
FROM node:18
MAINTAINER Otabek Ismoilov
# LABEL bilan
LABEL maintainer="Otabek Ismoilov ismoilovdev@gmail.com"
RUN
Docker faylidagi RUN
buyrug'i Docker imagedagi buyruqlarni bajarish uchun ishlatiladi. Ushbu buyruqlar odatda paketlarni o'rnatish, tizimni yangilash, fayllarni yuklab olish yoki konteyner ichidagi muhitni tayyorlash uchun zarur bo'lgan boshqa vazifalar uchun ishlatiladi.
RUN
qanday ishlatilishiga misol:
FROM ubuntu:latest
# Konteynerni yangilash va konteynerga zip, git, unzip o'rnatish
RUN apt-get update && apt-get install -y \
zip \
git \
unzip
Javascript applicationlar uchun misol
FROM node:18
RUN npm install
RUN npm build
WORKDIR
Dockerfiledagi WORKDIR
ko'rsatmasi(instructioni) Dockerfiledagi har qanday keyingi ko'rsatmalar uchun ishchi jildni o'rnatish uchun ishlatiladi. Bu buyruqlar bajariladigan konteyner ichidagi joriy jildni o'zgartiradi.
WORKDIR
ga misol:
FROM python:3.9-slim
WORKDIR /usr/src/app
WORKDIR /usr/src/app
Bu qator konteyner ichidagi ishchi jildni /usr/src/app
ga o'rnatadi. Dockerfile-dagi keyingi buyruqlar, agar bekor qilinmasa, ushbu ko'rsatilgan jildda bajariladi.
Ishchi jildi o'rnatish, ayniqsa, fayllarda ishlaydigan yoki yo'llarga(path) murojaat qilish kerak bo'lgan buyruqlar har safar to'liq yo'lni ko'rsatmasdan doimiy ishlashini ta'minlash uchun foydalidir. Shuni ta'kidlash kerakki, WORKDIR
-dan foydalanish, agar asosiy imageda mavjud bo'lmasa, jild yaratmaydi. Agar ko'rsatilgan jildg imageda mavjud bo'lmasa, Docker uni buyruq talab qilganda yoki COPY
instructioni yordamida ushbu jildga fayllar ko'chirilganda yaratadi.
COPY
Dockerfiledagi COPY
buyrug'i fayllar yoki jildlarni host mashinasidan qurilayotgan Docker imagesiga nusxalash uchun ishlatiladi.
COPY
qanday ishlatilishiga misol:
FROM ubuntu:latest
RUN mkdir /myapp
COPY app-files /myapp
app-files jildidagi fayllarni host mashinasidan image ichidagi /myapp
jildiga ko'chiradi.
Python applicationlari uchun real namuna
FROM python:3.9-slim
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN pip install --no-cache-dir -r requirements.txt
WORKDIR
konteyner ichidagi ishni jildni /usr/src/app
ga o'rnatadi. COPY
Joriy jilddagi barcha fayllarni Docker imagedagi /usr/src/app
jildiga ko'chiradi.
ENV
Dockerfiledagi ENV
buyrug'i konteyner ichidagi muhit o'zgaruvchilarini(environment variable) o'rnatish uchun ishlatiladi. Ushbu o'zgaruvchilar key-value juftliklari bo'lib, ularga konteyner ichida ishlaydigan har qanday jarayon orqali kirish mumkin.
ENV
insturctionlaridan foydalanishni ko'rsatadigan oddiy Dockerfile misoli:
FROM node:14
ENV NODE_ENV=production
ENV PORT=3000
Real mysql database uchun ENV
ishlatilishi
FROM mysql:latest
ENV MYSQL_ROOT_PASSWORD=my-secret-pw
ENV MYSQL_DATABASE=mydb
ENV MYSQL_USER=user
ENV MYSQL_PASSWORD=password
ADD
Dockerfile-dagi ADD
insturctioni fayllarni, jildlarni yoki masofaviy URL-larni yaratish kontekstidan yaratilayotgan Docker imagening fayl tizimiga nusxalash uchun ishlatiladi. Bu sizga Docker build kontekstidan (Dockerfile joylashgan jild) local fayllar yoki jildlarni imagega qo'shish imkonini beradi.
ADD
insturctioni sintaksisi quyidagicha:
FROM node:14
ADD myapp /usr/src/app
Bu yerda Docker build kontekstidan myapp
nomli local jildni image ichidagi /usr/src/app
jildiga qo'shiladi.
Masofaviy fayl qo'shsih quyidagicha
FROM python:3.9
ADD https://example.com/file.txt /app/file.txt
ADD
insturctioni, shuningdek, masofaviy(remote) URL-manzillardan fayllarni olib, ularni imagega qo'shishi mumkin. Ushbu misolda fayl (file.txt) https://example.com/file.txt
dan yuklab olinadi va imagening /app
jildiga joylashtiriladi.
CMD
CMD
insturctioni ushbu Docker imagega asoslangan konteyner ishga tushirilganda bajarilishi kerak bo'lgan buyruqni belgilash uchun ishlatiladi. U konteyner ishga tushganda ishga tushirish uchun standart buyruqni belgilaydi, garchi uni konteynerni ishga tushirishda buyruq berish orqali bekor qilish mumkin.
CMD insturctioni sintaksisi quyidagicha:
FROM python:3.9
CMD ["python", "app.py"]
Ushbu misolda, ushbu imagega asoslangan konteyner ishga tushirilganda, u standart buyruq sifatida Python skripti app.py
ni ishga tushiradi.
Web Serverni ishga tushirishga misol
FROM nginx:latest
CMD ["nginx", "-g", "daemon off;"]
Bu yerda CMD instructioni Nginx veb-serverini konteyner ichida ishga tushirish buyrug'ini belgilaydi.
ENTRYPOINT
ENTRYPOINT
instructioni Docker imagedan konteyner ishga tushirilganda bajariladigan asosiy buyruqni o'rnatadi. Runtimeda buyruq berish orqali bekor qilinishi mumkin bo'lgan CMD
instructionidan farqli o'laroq, ENTRYPOINT
konteynerning bajarilishi(execute) uchun belgilangan boshlanish nuqtasini ta'minlaydi, ammo konteyner ishga tushirilganda u hali ham qo'shimcha argumentlar yoki buyruqlar bilan to'ldirilishi mumkin.
ENTRYPOINT
instructioni sintaksisi CMD
ga o'xshaydi:
FROM python:3.9
ENTRYPOINT ["python", "app.py"]
Bunday holda, ENTRYPOINT
instructioni konteyner ishga tushirilganda Python skripti app.py
ni asosiy buyruq sifatida bajarishi(execute) kerakligini bildiradi.
CMD
bilan birga ishlatilishi
FROM nginx:latest
ENTRYPOINT ["nginx", "-g", "daemon off;"]
CMD ["-c", "/etc/nginx/nginx.conf"]
Ushbu Dockerfile Nginx serverini standart sozlamalar bilan ishga tushirish uchun ENTRYPOINT
-dan foydalanadi va foydalaniladigan konfiguratsiya faylini belgilash uchun CMD
-dan foydalanadi (nginx.conf). Konteyner ishga tushganda, ENTRYPOINT standart sozlamalar bilan Nginx-ni ishga tushiradi va CMD konfiguratsiya fayli argumentini taqdim etish orqali uni to'ldiradi.
ENTRYPOINT
konteynerning asosiy ishlashini aniqlash va izchil bajarilish muhitini ta'minlash uchun foydalidir. U ko'pincha ma'lum bir boshlang'ich nuqtasi yoki ishga tushirish jarayonini talab qiladigan uzoq muddatli servicelar yoki ilovalar uchun qo'llaniladi. Bundan tashqari, u foydalanuvchilarga runtimeda qo'shimcha argumentlar yoki buyruqlar taqdim etish imkonini beradi va uning funksiyalarini kengaytiradi.
EXPOSE
EXPOSE
insturctioni Dockerga konteyner runtimeda ma'lum tarmoq portlarini tinglashi(listen) haqida xabar berish uchun ishlatiladi. Biroq, u portlarni publish qilmaydi yoki ochmaydi. U foydalanuvchilar uchun konteyner qaysi portlarni tinglamoqchi(listen) ekanligini tushunish uchun documentatsiya sifatida xizmat qiladi.
EXPOSE
insturctionining sintaksisi oddiy:
FROM nginx:latest
# HTTP trafigi uchun 80 portini ochadi(expose)
EXPOSE 80
Bunday holda, EXPOSE
insturctioni Dockerga konteyner kiruvchi trafik uchun 80
-portni tinglashini(listen) aytadi. Biroq, bu insturctionning o'zi portni host machinega publish qilmaydi yoki uni mapda ko'rsatmaydi. Portlarni konteynerdan hostga map qilish yoki publish qilish uchun konteynerni docker run -p
buyru'gidan foydalanishingiz kerak.
Masalan, konteynerning 80
-portini host-mashinadagi 8080
-portga map qilish uchun siz konteynerni quyidagicha ishga tushirasiz:
docker run -p 8080:80 my_image
Bu buyruq Docker-ga 80
-portni konteynerdan hostdagi 8080
-portga publish qilishni aytadi, bu esa konteyner ichida ishlaydigan servicelarga tashqi kirish imkonini beradi.
EXPOSE
konteyner qaysi portlardan foydalanishni kutayotganini bildirish uchun ko'proq qo'llanma xususiyatidir. Bu foydalanuvchilarga runtimeda konteynerning tarmoq harakatiga bevosita ta'sir qilmasdan mo'ljallangan tarmoq aloqa portlarini tushunishga yordam beradi. Haqiqiy port ulanishi va tarmoq konfiguratsiyasi konteyner tegishli port mapping bilan docker run
buyrug'i yordamida ishga tushirilganda amalga oshiriladi.
Misol uchun Node.js dasturiga namuna Dockerfile
FROM node:14
WORKDIR /usr/src/app
# package.json va package-lock.json fayllaridan nusxa oladi
COPY package*.json ./
# Dependencilarniu o'rnatadi
RUN npm install
# Ilova fayllarini nusxalaydi
COPY . .
# Node.js ilovasi uchun 3000 portini ochadi
EXPOSE 3000
# Node.js ilovasini ishga tushirish buyrug'i
CMD ["npm", "start"]
Ushbu Node.js misolida EXPOSE
insturctioni konteyner ichidagi Node.js ilovasi 3000
-portda tinglashini(listen) bildiradi. Bu ko'plab Node.js ilovalari uchun umumiy senariy bo'lishi mumkin, chunki ular odatda ushbu portdan default bo'yicha foydalanadilar.
VOLUME
VOLUME
instructioni Docker konteynerida mount point yaratish uchun ishlatiladi va konteyner tomonidan yaratilgan ma'lumotlarni doimiy ravishda saqlash yoki konteyner va host mashinasi o'rtasida ma'lumotlarni almashish uchun ishlatiladi.
VOLUME
instructioni sintaksisiga misol:
# Use a base image
FROM ubuntu:latest
# Ma'lumotlarni saqlash uchun volume yaratish
VOLUME /app/data
Ushbu misolda VOLUME
insturctioni konteyner ichidagi /app/data
da moint pointni yaratadi. Konteynerni ishga tushirish paytida ushbu jildga yozilgan har qanday ma'lumotlar konteynerning yoziladigan qatlamidan(writable layer) tashqarida saqlanadi, bu esa konteyner to'xtatilgandan yoki o'chirilgandan keyin ham doimiy(persistent) va mavjud bo'ladi.
VOLUME
dan foydalanish bo'yicha bir nechta asosiy fikrlarga e'tibor qaratish muhim:
-
Persisting Data(Doimiy ma'lumotlar): Belgilangan volume mountga yozilgan har qanday ma'lumotlar, hatto konteyner o'chirib tashlangan bo'lsa ham saqlanib qoladi. Bu ma'lumotlarni konteyner instancelarida almashish va qayta ishlatish imkonini beradi.
-
Runtimeda Volume Mount: Konteynerni ishga tushirganda, Docker'dagi
-v
yoki--volume
flagi yoki--mount
flagi local jild yoki nomlangan jildni Dockerfile'daVOLUME
yordamida yaratilgan jildga yo'naltirish uchun ishlatiladi.
Masalan:
docker run -v /host/path:/app/data my_image
Bu buyruq host mashinasidagi /host/path
jildini konteyner ichidagi /app/data
jildiga moslashtiradi.
- Specialized Data Containers(Ixtisoslashgan ma'lumotlar konteynerlari): volumelarni konteynerlar o'rtasida ham taqsimlash(share) mumkin. Nomlangan volumeni yaratish bir nechta konteynerlarga bir xil ma'lumotlarni almashish imkonini beradi.
Misol uchun:
docker run --name container1 -v shared_data:/app/data my_image
docker run --name container2 --volumes-from container1 another_image
Bu yerda container2
container1
volumidan foydalanadi.
Dockerfiledagi VOLUME
birinchi navbatda Docker uchun ko'rsatma bo'lib xizmat qiladi, bu konteyner ichidagi ma'lum bir jild doimiy ma'lumotlarni(persistent data) saqlash yoki konteynerlar yoki host mashinasi bilan ma'lumotlarni almashish uchun mo'ljallanganligini ko'rsatadi. Bu Docker konteynerlarida stateful datalarni boshqarishning asosiy jihati.
USER
USER
insturctioni Docker faylida keyingi buyruqlarni bajarayotganda Docker konteyneri qaysi foydalanuvchiga(user) ishlashi kerakligini belgilash uchun ishlatiladi. U foydalanuvchini username nomi yoki UID (Foydalanuvchi identifikatori) bo'yicha sozlash imkonini beradi.
USER
instructioni sintaksisi quyidagicha:
USER <username yoki UID>
<username yoki UID>
asosiy imagedagi mavjud foydalanuvchining yoki Dockerfile-da yaratilgan foydalanuvchining usernamesi yoki UID bo'lishi mumkin.
Docker faylida USER instructionian foydalanishni ko'rsatadigan bir nechta misollar:
FROM ubuntu:latest
# Yangi foydalanuvchi "appuser" yaratadi va o'sha foydalanuvchiga o'tadi
RUN useradd -ms /bin/bash appuser
USER appuser
WORKDIR /home/appuser
COPY . .
CMD ["./start.sh"]
Ushbu misolda, useradd
yordamida appuser
nomli yangi foydalanuvchi yaratilgan va USER
insturctioni Dockerfile faylidagi keyingi buyruqlar uchun appuser
ni standart foydalanuvchi sifatida belgilaydi. Bu cheklangan imtiyozlar bilan dasturni ishga tushirish uchun foydalidir.
UID dan foyalanishga misol
FROM node:14
WORKDIR /usr/src/app
COPY . .
RUN chown -R node:node /usr/src/app
USER node
CMD ["npm", "start"]
USER
instructioni Node.js asosiy imagesida mavjud bo'lmagan root
foydalanuvchisi bo'lgan node foydalanuvchisiga o'tadi. Foydalanuvchilarni almashtirishdan oldin, dastur ishlayotgan vaqtda o'z fayllariga kirishini ta'minlash uchun dastur jildining egaligi node foydalanuvchisiga o'zgartiriladi.
USER
instructionidan foydalanish xavfsizlik maqsadlari uchun juda muhim, chunki root
bo'lmagan foydalanuvchilar bilan konteynerlarni ishga tushirish konteynerlashtirilgan ilova ichidagi xavfsizlik zaifliklarining potentsial ta'sirini kamaytiradi. Ammo shuni yodda tutingki, Dockerfile'dagi ba'zi operatsiyalar root
huquqlarini talab qilishi mumkin, shuning uchun Dockerfile'da foydalanuvchini belgilashda xavfsizlikning eng yaxshi amaliyotlari bilan operatsion talablarni muvozanatlash juda muhimdir.
Namunalar
Quyida bir nechta dasturlar uchun yozilgan Dockerfilelar
JavaScript (Node.js)
FROM node:18
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Python
FROM python:3.9
WORKDIR /usr/src/app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
Rust
FROM rust:latest
WORKDIR /usr/src/app
COPY . .
CMD ["cargo", "run"]
.NET(C#)
# Use a base image
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
WORKDIR /app
COPY --from=build /app/out .
ENV ASPNETCORE_ENVIRONMENT=Development
ENV TZ="Asia/Tashkent"
ENTRYPOINT ["dotnet", "YourApp.dll", "--urls=http://0.0.0.0:4040"]
Go
FROM golang:latest
WORKDIR /go/src/app
COPY . .
RUN go build -o main .
EXPOSE 8080
CMD ["./main"]
Qo'shimcha Dockerfilelar va yaxshiroq loyiha va fremworkga moslab yozilgan Dockerfile namunlarini devops-tools (opens in a new tab) github repositoriyasidan topsishingiz mumkin