Перейти к содержимому

16. Безопасность

Безопасность контейнеров — критически важный аспект production-развёртываний. Docker предоставляет множество механизмов для ограничения привилегий, изоляции и мониторинга контейнеров.

Самая важная практика: никогда не запускайте контейнер от root в продакшене.

# ❌ Небезопасно — по умолчанию root
FROM node:20-alpine
WORKDIR /app
COPY . .
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 whoami
docker exec mycontainer id
Окно терминала
# Запустить с read-only корневой файловой системой
docker run -d \
--read-only \
--tmpfs /tmp \ # разрешить запись только в /tmp
--tmpfs /run \
-v app_data:/app/data \ # именованный том для данных
myapp
# В docker-compose.yml
services:
api:
image: myapp
read_only: true
tmpfs:
- /tmp
- /run
volumes:
- app_data:/app/data

Linux capabilities позволяют точечно выдавать привилегии:

Окно терминала
# Убрать все capability и добавить только нужные
docker run -d \
--cap-drop=ALL \ # убрать все
--cap-add=NET_BIND_SERVICE \ # разрешить порты < 1024
--cap-add=CHOWN \ # разрешить изменение владельца файлов
nginx
# Никогда не используйте --privileged в продакшене!
# docker run --privileged myapp ← ОПАСНО!
Окно терминала
# Запретить получение новых привилегий через setuid
docker 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
# Snyk
snyk container test myapp:latest
# Вывод Trivy показывает:
# CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN уязвимости
# CVE номера и рекомендации по исправлению
Окно терминала
# 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:1
FROM node:20-alpine
RUN --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 .
# 1. Используйте конкретные версии образов (не latest)
FROM node:20.11.0-alpine3.19
# 2. Непривилегированный пользователь
RUN adduser -D -u 1001 appuser
USER 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 не устанавливаем