16. Безопасность
Безопасность контейнеров — критически важный аспект production-развёртываний. Docker предоставляет множество механизмов для ограничения привилегий, изоляции и мониторинга контейнеров.
Запуск без root-прав
Заголовок раздела «Запуск без root-прав»Самая важная практика: никогда не запускайте контейнер от root в продакшене.
# ❌ Небезопасно — по умолчанию rootFROM node:20-alpineWORKDIR /appCOPY . .CMD ["node", "server.js"]# Запускается как root!
# ✅ Безопасно — непривилегированный пользовательFROM node:20-alpine
# Создать пользователя и группуRUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
# Установить правильные праваCOPY --chown=appuser:appgroup . .RUN npm ci --only=production
# Переключиться на непривилегированного пользователяUSER appuser
CMD ["node", "server.js"]# Проверить, от какого пользователя запущен процессdocker exec mycontainer whoamidocker exec mycontainer idRead-only файловая система
Заголовок раздела «Read-only файловая система»# Запустить с read-only корневой файловой системойdocker run -d \ --read-only \ --tmpfs /tmp \ # разрешить запись только в /tmp --tmpfs /run \ -v app_data:/app/data \ # именованный том для данных myapp
# В docker-compose.ymlservices: api: image: myapp read_only: true tmpfs: - /tmp - /run volumes: - app_data:/app/dataCapabilities (привилегии)
Заголовок раздела «Capabilities (привилегии)»Linux capabilities позволяют точечно выдавать привилегии:
# Убрать все capability и добавить только нужныеdocker run -d \ --cap-drop=ALL \ # убрать все --cap-add=NET_BIND_SERVICE \ # разрешить порты < 1024 --cap-add=CHOWN \ # разрешить изменение владельца файлов nginx
# Никогда не используйте --privileged в продакшене!# docker run --privileged myapp ← ОПАСНО!Security Options
Заголовок раздела «Security Options»# Запретить получение новых привилегий через setuiddocker run -d \ --security-opt no-new-privileges:true \ --security-opt seccomp:custom-seccomp.json \ myapp
# Использовать AppArmor профильdocker run -d \ --security-opt apparmor:docker-default \ myappСканирование образов
Заголовок раздела «Сканирование образов»# Docker Scout (встроен в Docker Desktop)docker scout cves myapp:latest
# Trivy (популярный open-source сканер)trivy image myapp:latest
# Snyksnyk container test myapp:latest
# Вывод Trivy показывает:# CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN уязвимости# CVE номера и рекомендации по исправлениюSecrets Management
Заголовок раздела «Secrets Management»# Docker Secrets (только в Swarm)echo "mysupersecret" | docker secret create db_password -docker service create \ --secret db_password \ --name myservice \ myapp# Секрет доступен как файл: /run/secrets/db_password
# BuildKit secrets (не сохраняются в образе)# syntax=docker/dockerfile:1FROM node:20-alpineRUN --mount=type=secret,id=npm_token \ NPM_TOKEN=$(cat /run/secrets/npm_token) \ npm install --production
# Сборка с секретомdocker build --secret id=npm_token,src=.npm_token .Безопасный Dockerfile: чеклист
Заголовок раздела «Безопасный Dockerfile: чеклист»# 1. Используйте конкретные версии образов (не latest)FROM node:20.11.0-alpine3.19
# 2. Непривилегированный пользовательRUN adduser -D -u 1001 appuserUSER appuser
# 3. Минимальный базовый образFROM alpine:3.19 # или scratch, distroless
# 4. Не копируйте секреты в образ# НЕ: COPY .env .# НЕ: ENV SECRET_KEY=value
# 5. Обновите базовые пакетыRUN apk upgrade --no-cache
# 6. Уберите ненужные инструментыRUN apk add --no-cache curl && \ # curl нужен только для healthcheck # wget, ssh, bash не устанавливаем