Ответ
Технически — можно, но в продакшене это считается плохой практикой и создает серьезные угрозы безопасности.
По умолчанию, если в Dockerfile не указан пользователь (USER), контейнер запускается от root (UID 0). Этот root внутри контейнера по умолчанию имеет привилегии root на хостовой системе, что может привести к:
- Escaping the container: Уязвимости или misconfiguration могут позволить процессу из контейнера получить root-доступ к хосту.
- Изменение хостовых файлов: Смонтированные томы (
-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 для предоставления минимально необходимых привилегий.