Dockerfile: создаём свой образ
Dockerfile — текстовый рецепт для сборки образа. Каждая инструкция добавляет слой.
Минимальный Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]docker build -t my-app . # собрать
docker run -p 3000:3000 my-app # запуститьПопробуй в симуляции
Инструкции
FROM — базовый образ
FROM ubuntu:22.04
FROM node:20-alpine # предпочтительно (меньше размер)
FROM scratch # пустой образ (для Go бинарников)WORKDIR — рабочая директория
WORKDIR /appСоздаёт директорию если не существует. Все следующие инструкции выполняются относительно неё.
COPY и ADD
COPY src/ /app/src/ # скопировать папку
COPY package*.json ./ # glob паттерн
ADD archive.tar.gz /app/ # распакует архив автоматическиИспользуй COPY — предсказуемее. ADD нужен только для распаковки архивов.
RUN — выполнить команду при сборке
RUN apt-get update && apt-get install -y curl
RUN npm install
RUN go build -o app .Каждый RUN — отдельный слой. Объединяй связанные команды через &&:
# Плохо: 3 слоя, промежуточные файлы не удалятся
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
# Хорошо: 1 слой, всё чисто
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*ENV — переменные окружения
ENV NODE_ENV=production
ENV PORT=3000Доступны во время сборки и во время работы контейнера.
EXPOSE — документирует порт
EXPOSE 3000
EXPOSE 80/tcpТолько документация — реально порт не открывается. Для этого нужен -p в docker run.
CMD и ENTRYPOINT — точка входа
# CMD — команда по умолчанию (можно перезаписать)
CMD ["node", "server.js"]
CMD ["npm", "start"]
# ENTRYPOINT — всегда выполняется
ENTRYPOINT ["nginx", "-g", "daemon off;"]Exec-форма (рекомендуется): ["executable", "arg1"] — запускает напрямую, без shell.
Shell-форма: command arg1 — запускается через /bin/sh -c, обрабатывает переменные.
.dockerignore
Как .gitignore, но для контекста сборки. Уменьшает размер образа:
node_modules
.git
*.log
.env
dist
coverage
Без .dockerignore COPY . . скопирует node_modules (сотни MB) в контейнер.
Полный пример: Node.js API
FROM node:20-alpine
WORKDIR /app
# Сначала зависимости (лучший кэш)
COPY package*.json ./
RUN npm ci --only=production
# Потом исходники
COPY src/ ./src/
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "src/index.js"]В следующем уроке — слои и кэш: как писать Dockerfile для быстрой сборки.