Ответ
Да, для этого используется инструкция USER. Это критически важная практика безопасности, чтобы контейнер не работал от имени root по умолчанию.
Базовый пример:
FROM alpine:latest
# 1. Создаем непривилегированного пользователя и группу
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# 2. Копируем файлы приложения от имени root (у root есть права на запись)
COPY --chown=appuser:appgroup ./app /home/appuser/app
WORKDIR /home/appuser/app
# 3. Меняем пользователя на непривилегированного
USER appuser
# 4. Все последующие инструкции (RUN, CMD, ENTRYPOINT) будут выполняться от имени appuser
CMD ["python", "app.py"]
Ключевые моменты и лучшие практики:
- Порядок инструкций: Инструкции, требующие прав на запись (например,
COPY,RUNдля установки пакетов), должны выполняться доUSER. ПослеUSERконтейнер переходит в непривилегированный режим. - Указание UID/GID: Для лучшей совместимости и контроля прав в Kubernetes лучше явно указывать числовые UID/GID. Это гарантирует, что пользователь будет одинаковым, даже если его имени нет в
/etc/passwdвнутри контейнера.RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -S appuser USER 1001:1001 - Работа с volumes: Если смонтированный volume (том) создан от имени root на хосте, непривилегированный пользователь внутри контейнера не сможет в него писать. Решаю это либо правильной настройкой прав на хосте, либо использованием
docker run --userдля переопределения пользователя при запуске, либо инициализацией прав в entrypoint-скрипте. - Проверка: После сборки образа можно проверить, от какого пользователя запускается процесс по умолчанию:
docker run --rm my-image id # Выведет uid=1001(appuser) gid=1001(appgroup)
Исключения: Некоторые официальные образы (например, nginx) уже содержат непривилегированного пользователя (например, nginx). В таких случаях можно просто указать USER nginx без предварительного создания.