Что указывается в директиве USER в Dockerfile?

«Что указывается в директиве USER в Dockerfile?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Директива USER в Dockerfile задаёт имя пользователя (или его UID) и опционально группу (или GID), от имени которого будут запускаться все последующие инструкции RUN, CMD и ENTRYPOINT в этом образе.

Форматы указания:

  • USER <user> (например, USER app)
  • USER <uid> (например, USER 1000)
  • USER <user>:<group> (например, USER app:app)
  • USER <uid>:<gid> (например, USER 1000:1000)

Пример в Dockerfile:

FROM alpine:latest
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Копируем файлы от root
COPY --chown=appuser:appgroup app.jar /opt/app/
# Переключаем пользователя
USER appuser
WORKDIR /opt/app
CMD ["java", "-jar", "app.jar"]

Зачем это нужно с точки зрения DevOps и безопасности:

  1. Снижение привилегий (Principle of Least Privilege): Запуск контейнера от root (по умолчанию, если USER не указан) даёт процессу внутри контейнера неограниченные права. Если злоумышленник скомпрометирует такое приложение, он получит root-доступ к хостовой системе (особенно при использовании --privileged флага или уязвимостей в ядре). Запуск от непривилегированного пользователя минимизирует этот риск.
  2. Соответствие стандартам безопасности: Требования многих compliance-стандартов (например, PCI DSS, CIS Benchmarks) прямо запрещают запуск контейнеров от root.
  3. Изоляция от хоста: Использование несуществующего на хосте высокого UID (например, USER 10000:10000) может добавить дополнительный уровень изоляции.

Важные замечания:

  • Указанный пользователь или UID/GID должны существовать внутри образа. Их нужно создать с помощью RUN (как в примере выше) или использовать базовый образ, где они уже есть.
  • Директива USER влияет только на инструкции, следующие за ней в Dockerfile. Инструкции до USER выполняются от root (или от пользователя, заданного предыдущей директивой USER).
  • Пользователя можно переопределить при запуске контейнера флагом docker run -u <user>.