Docker / Image build хийх

Image build хийх

docker build командаар Dockerfile-аас image үүсгэнэ. Энэ хичээлд build-ийн бүх сонголтыг судална.

docker build — үндсэн хэрэглээ

bash
docker build -t myapp:1.0 .
  • -t myapp:1.0 — image-д нэр ба tag өгөх
  • . — build context (одоогийн директор)

Build дуусвал:

код
Successfully built 3f2a1b4c5d6e
Successfully tagged myapp:1.0

-t флаг — нэр ба tag

bash
# Нэр ба tag
docker build -t myapp:1.0 .

# Зөвхөн нэр (tag автоматаар "latest" болно)
docker build -t myapp .

# Олон tag нэгэн зэрэг
docker build -t myapp:1.0 -t myapp:latest .

# Docker Hub-д байршуулах форматтай
docker build -t username/myapp:1.0 .

Tag-ийн зөвлөмж:

  • latest — хамгийн сүүлийн хувилбар
  • 1.0, 1.2.3 — semantic versioning
  • git-abc1234 — git commit hash (CI/CD-д хэрэгтэй)

Build context гэж юу вэ?

docker build командын сүүлийн аргумент build context — Docker daemon-д илгээх файлуудын директор.

bash
docker build -t myapp .    # Одоогийн директор build context
docker build -t myapp /home/user/project  # Тодорхой директор

Build context-ийн бүх файл Docker daemon-д дамжуулагдана. Тиймээс context жижиг байх нь build хурдасна.

код
[+] Building 2.3s (10/10) FINISHED
 => [internal] load build context          0.1s
 => => transferring context: 1.23MB        0.1s   ← Context хэмжээ

Context том байвал:

код
 => => transferring context: 890MB         45.3s  ← Маш удаан!

.dockerignore — context-ийг хязгаарлах

.dockerignore файл нь build context-ээс хасах файлуудыг тодорхойлно. .gitignore-тэй ижил синтакс.

Node.js төслийн жишээ:

код
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
.env
.env.local
*.md
dist
coverage
.DS_Store

Python төслийн жишээ:

код
# .dockerignore
__pycache__
*.pyc
*.pyo
.venv
venv
.env
.git
*.md
dist
build
*.egg-info

.dockerignore байгаа эсэхийг шалгах:

bash
ls -la | grep dockerignore

-f флаг — Dockerfile нэр зааx

Анхдагч байдлаар Dockerfile нэртэй файл хайна. Өөр нэр ашиглахад:

bash
# Тодорхой Dockerfile зааx
docker build -f Dockerfile.prod -t myapp:prod .
docker build -f Dockerfile.dev -t myapp:dev .

Олон орчин (development, staging, production) тус бүрт Dockerfile байж болно:

код
myapp/
├── Dockerfile           ← Үндсэн
├── Dockerfile.dev       ← Хөгжүүлэлт
├── Dockerfile.prod      ← Production
└── Dockerfile.test      ← Тест

--build-arg — build-ийн аргумент

Dockerfile-д динамик утга дамжуулахад:

dockerfile
ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine
ARG APP_VERSION=1.0.0
ENV VERSION=${APP_VERSION}
bash
docker build --build-arg NODE_VERSION=18 --build-arg APP_VERSION=2.1.0 -t myapp .

ARG зөвхөн build явцад байна. ENV болгосны дараа container-д ч байна.

--no-cache — cache ашиглахгүй build

bash
docker build --no-cache -t myapp:fresh .

Package-ийн шинэ хувилбар татахад хэрэгтэй.

Image tag хийх

Байгаа image-д шинэ tag нэмэхэд docker tag:

bash
# Одоогийн tag → шинэ tag
docker tag myapp:1.0 myapp:latest
docker tag myapp:1.0 username/myapp:1.0

docker images — image харах

bash
# Бүх image
docker images

# Нэрээр шүүх
docker images myapp

# Форматтайгаар харах
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
код
REPOSITORY   TAG       SIZE
myapp        1.0       142MB
myapp        latest    142MB
node         20-alpine 131MB

myapp:1.0 ба myapp:latest нэг IMAGE ID-тэй бол нэг image — зөвхөн tag ялгаатай. Disk дээр хоёр удаа хадгалагдахгүй.

docker rmi — image устгах

bash
# Tag-аар устгах
docker rmi myapp:1.0

# IMAGE ID-аар устгах
docker rmi 3f2a1b4c5d6e

# Олон image нэгэн зэрэг
docker rmi myapp:1.0 myapp:latest

# Ашиглагдаагүй image бүгдийг устгах
docker image prune

# Бүх image устгах (ажиллаж байгаа container-тай холбоогүй)
docker image prune -a

Container ашиглаж байгаа image устгах гэвэл алдаа гарна:

код
Error response from daemon: conflict: unable to remove repository reference
"myapp:1.0" (must force) - container 7b3c is using its referenced image

Эхлээд container устгаад image устга.

Бүтэн жишээ — Express апп

Файл бүтэц:

код
express-app/
├── .dockerignore
├── Dockerfile
├── package.json
└── index.js

index.js:

javascript
const express = require("express");
const app = express();

app.get("/", (req, res) => {
  res.json({ message: "Сайн уу!", version: process.env.VERSION || "1.0" });
});

app.listen(3000, () => console.log("Port 3000 дээр ажиллаж байна"));

package.json:

json
{
  "name": "express-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.19.2"
  },
  "scripts": {
    "start": "node index.js"
  }
}

Dockerfile:

dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]

.dockerignore:

код
node_modules
.git
*.md
.env

Build ба ажиллуулах:

bash
# Build
docker build -t express-app:1.0 .

# Ажиллуулах
docker run -p 3000:3000 express-app:1.0

# Шалгах
curl http://localhost:3000
json
{ "message": "Сайн уу!", "version": "1.0" }

Дараагийн хичээлд:

Port mapping-ийг нарийвчлан судлах — -p флаг, EXPOSE, олон port.