Можно ли и стоит ли работать от root внутри Docker-контейнера?

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

Ответ

Технически — можно, но в продакшене это считается плохой практикой и создает серьезные угрозы безопасности.

По умолчанию, если в Dockerfile не указан пользователь (USER), контейнер запускается от root (UID 0). Этот root внутри контейнера по умолчанию имеет привилегии root на хостовой системе, что может привести к:

  1. Escaping the container: Уязвимости или misconfiguration могут позволить процессу из контейнера получить root-доступ к хосту.
  2. Изменение хостовых файлов: Смонтированные томы (-v) могут быть изменены с правами root.

Правильная практика в DevOps:

1. Создавать и использовать непривилегированного пользователя в Dockerfile.

FROM alpine:latest

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

# Копируем файлы и меняем владельца ДО переключения пользователя
COPY --chown=appuser:appgroup app /app
WORKDIR /app

# Переключаемся на непривилегированного пользователя
USER appuser

CMD ["./start.sh"]

2. Использовать случайный UID (как в OpenShift/Kubernetes Pod Security Standards).

# Запуск от заранее неизвестного UID (устанавливается при запуске)
USER 10001

Или при запуске:

docker run --user $(id -u):$(id -g) my_image

3. Если приложению нужны привилегии (например, прослушивание порта < 1024), использовать Linux Capabilities вместо полного root.

# Вместо --privileged даем только нужные возможности
# Например, NET_BIND_SERVICE для привязки к порту 80
docker run --cap-add=NET_BIND_SERVICE my_image

4. В оркестраторах (Kubernetes) настраивать Security Context:

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  allowPrivilegeEscalation: false
  capabilities:
    drop:
      - ALL

Исключения, где root может быть оправдан: init-контейнеры, требующие установки пакетов, или специализированные системные контейнеры. Но даже тогда следует использовать --cap-add для предоставления минимально необходимых привилегий.