Ответ
Для смены пользователя в Dockerfile используется инструкция USER. Это критически важно для безопасности, чтобы контейнер не работал от root без необходимости.
Базовый пример:
FROM alpine:3.18
RUN addgroup -g 1000 appgroup &&
adduser -u 1000 -G appgroup -D appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
USER appuser
CMD ["node", "index.js"]
Практические сценарии:
-
Снижение привилегий после установки пакетов:
FROM ubuntu:22.04 RUN apt-get update && apt-get install -y python3 && rm -rf /var/lib/apt/lists/* RUN useradd -m -u 1001 apprunner USER apprunner -
Использование UID вместо имени (рекомендуется для Kubernetes):
USER 1001 -
Многоступенчатая сборка со сменой пользователя:
FROM golang:1.21 AS builder WORKDIR /build COPY . . RUN CGO_ENABLED=0 go build -o app .
FROM scratch COPY --from=builder /build/app /app USER 1000:1000 ENTRYPOINT ["/app"]
**Важные моменты:**
- Пользователь должен существовать (создан через `RUN useradd/adduser`)
- `USER` влияет на все последующие `RUN`, `CMD`, `ENTRYPOINT`
- В Kubernetes SecurityContext может переопределять пользователя контейнера
- Для доступа к привилегированным портам (<1024) всё равно потребуется root или `NET_BIND_SERVICE` capability