Ответ
Запуск контейнеров от непривилегированного пользователя — критически важная практика безопасности. Я использую несколько подходов в зависимости от контекста.
1. Через Dockerfile (рекомендуемый способ) Создаю пользователя на этапе сборки образа:
FROM alpine:3.18
# Создаем непривилегированного пользователя
RUN addgroup -g 1000 -S appgroup &&
adduser -u 1000 -S appuser -G appgroup
# Копируем приложение с правильными правами
COPY --chown=appuser:appgroup app /app
# Переключаемся на непривилегированного пользователя
USER appuser
CMD ["/app/start.sh"]
2. При запуске контейнера (для отладки или переопределения)
# По UID:GID
docker run --user 1000:1000 my-app:latest
# По имени пользователя (должен существовать в контейнере)
docker run --user appuser my-app:latest
# С сохранением пользователя хоста для volume
docker run --user $(id -u):$(id -g) -v $(pwd)/data:/data my-app:latest
3. В Docker Compose
version: '3.8'
services:
app:
image: my-app:latest
user: "1000:1000"
# Или
user: "appuser:appgroup"
4. Для Kubernetes в манифесте
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
containers:
- name: app
image: my-app:latest
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
Ключевые практики безопасности:
- Никогда не запускаю production-контейнеры от root
- Использую не-root базовые образы (например,
node:18-alpineвместоnode:18) - Настраиваю правильные права на volume через
fsGroupв Kubernetes - Проверяю запущенного пользователя:
docker exec <container-id> whoami docker exec <container-id> id - Для legacy-приложений, требующих root, использую
USER rootтолько на этапе установки, затем переключаюсь на непривилегированного пользователя