Ответ
Директива 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.