Перейти к содержимому

5. Dockerfile

Dockerfile — это текстовый файл с набором инструкций, описывающих, как собрать Docker-образ. Каждая инструкция создаёт новый слой в образе. Правильно составленный Dockerfile — основа эффективной контейнеризации.

Базовый Dockerfile для Node.js приложения:

# Базовый образ
FROM node:20-alpine
# Метаданные образа
LABEL maintainer="[email protected]"
LABEL version="1.0"
# Рабочая директория внутри контейнера
WORKDIR /app
# Копировать файлы зависимостей
COPY package*.json ./
# Установить зависимости
RUN npm ci --only=production
# Копировать исходный код
COPY . .
# Переменная окружения
ENV NODE_ENV=production
ENV PORT=3000
# Открыть порт
EXPOSE 3000
# Команда запуска
CMD ["node", "server.js"]
# Обязательная первая инструкция
FROM node:20-alpine
# С алиасом для multi-stage builds
FROM node:20-alpine AS builder
# Пустой образ (для статических бинарников)
FROM scratch
# Одна команда
RUN npm install
# Несколько команд в одном слое (рекомендуется)
RUN apt-get update && \
apt-get install -y curl wget && \
rm -rf /var/lib/apt/lists/*
# Exec-форма (без shell)
RUN ["npm", "ci"]
# Копировать файл
COPY package.json /app/package.json
# Копировать директорию
COPY src/ /app/src/
# Использовать .dockerignore для исключений
COPY . /app
# ADD может распаковывать архивы и загружать URL
ADD app.tar.gz /app
# Но COPY предпочтительнее для обычных файлов
# Установить переменную
ENV NODE_ENV=production
# Несколько переменных
ENV PORT=3000 \
HOST=0.0.0.0 \
LOG_LEVEL=info
# Сообщить, что контейнер слушает этот порт
# (не публикует порт автоматически!)
EXPOSE 3000
EXPOSE 80/tcp
EXPOSE 53/udp
WORKDIR /app
# Создаёт директорию если не существует
# Все последующие инструкции выполняются в /app
# CMD — команда по умолчанию (можно переопределить)
CMD ["node", "server.js"]
CMD npm start
# ENTRYPOINT — точка входа (нельзя переопределить без --entrypoint)
ENTRYPOINT ["node"]
CMD ["server.js"] # аргумент для ENTRYPOINT
# Переопределение при запуске:
docker run myapp # → node server.js
docker run myapp app.js # → node app.js
docker run --entrypoint python myapp script.py # → python script.py
# Объявить аргумент сборки
ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine
ARG APP_VERSION
LABEL version=${APP_VERSION}
# Передать при сборке
# docker build --build-arg APP_VERSION=1.2.3 .
# Создать непривилегированного пользователя
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# Объявить том для данных
VOLUME /app/data
VOLUME /var/log