От какого пользователя выполняется команда, указанная в CMD или ENTRYPOINT в Docker?

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

Ответ

Пользователь, от которого запускается процесс внутри контейнера, определяется следующим приоритетом (от высшего к низшему):

  1. Аргумент --user в команде docker run: Напрямую переопределяет любого пользователя, заданного в Dockerfile.
    docker run --user 1000:1000 my-image
  2. Директива USER в Dockerfile: Если она указана, то все последующие инструкции RUN, CMD и ENTRYPOINT будут выполняться от этого пользователя и группы.
    FROM alpine
    RUN addgroup -S appgroup && adduser -S appuser -G appgroup
    USER appuser:appgroup
    CMD ["whoami"] # Выведет 'appuser'
  3. Пользователь по умолчанию: Если ни --user, ни USER не заданы, процесс запускается от root (UID 0, GID 0).

Критически важные практики для безопасности:

  • Никогда не запускать приложение от root: Это серьезная уязвимость. Если злоумышленник скомпрометирует приложение, он получит root-доступ к хосту через escape-векторы в ядре.
  • Создавать не-root пользователя в Dockerfile: Это должно быть стандартным шагом для production-образов.
  • Устанавливать правильные права на файлы: Убедиться, что рабочие директории и файлы, к которым нужно писать (логи, временные файлы), принадлежат пользователю контейнера или доступны ему на запись.

Пример безопасного Dockerfile:

FROM node:18-alpine
# Создаем непривилегированного пользователя и группу
RUN addgroup -g 1001 -S nodejs && 
    adduser -S nodejs -u 1001 -G nodejs
# Устанавливаем зависимости от root
COPY package*.json ./
RUN npm ci --only=production
# Копируем код и меняем владельца
COPY --chown=nodejs:nodejs . .
# Переключаемся на непривилегированного пользователя
USER nodejs
EXPOSE 3000
CMD ["node", "server.js"]

В этом примере приложение server.js будет запущено от пользователя nodejs (UID 1001), что минимизирует риски в случае компрометации.