Что означает пользователь, которого указываешь в Dockerfile?

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

Ответ

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

Почему это важно для безопасности: По умолчанию контейнеры запускаются от root (UID 0). Если злоумышленник скомпрометирует приложение внутри контейнера, он получит root-привилегии на хосте (при определенных настройках). Использование непривилегированного пользователя снижает этот риск.

Практический пример:

FROM node:18-alpine

# 1. Создаем непривилегированного пользователя и группу
RUN addgroup -g 1001 -S appgroup && 
    adduser -S appuser -u 1001 -G appgroup

# 2. Копируем файлы и меняем владельца
WORKDIR /app
COPY --chown=appuser:appgroup package*.json ./
RUN npm ci --only=production
COPY --chown=appuser:appgroup . .

# 3. ПЕРЕКЛЮЧАЕМСЯ на непривилегированного пользователя ПЕРЕД запуском приложения
USER appuser

EXPOSE 3000
CMD ["node", "server.js"]

Ключевые рекомендации:

  • Используйте числовой UID/GID, а не имена. Это предотвращает проблемы, если пользователь с таким именем не существует в базовом образе.
    USER 1001:1001
  • Переключайтесь на непривилегированного пользователя как можно позже в Dockerfile. Все операции, требующие прав root (установка пакетов, изменение системных файлов), должны выполняться до директивы USER.
  • Для некоторых сценариев (например, контейнер, которому нужен доступ к порту ниже 1024) можно использовать setcap вместо запуска от root.