Docker 安全
非 root 用户
# Dockerfile:创建并切换到非 root 用户
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --chown=appuser:appgroup . .
USER appuser
EXPOSE 3000
CMD ["node", "server.js"]
# 运行时覆盖用户
docker run --user 1001:1001 myapp
只读文件系统
# 以只读根文件系统运行
docker run \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid \
--tmpfs /run:rw,noexec,nosuid \
myapp
# 允许特定目录可写
docker run \
--read-only \
-v app-logs:/app/logs \
--tmpfs /tmp \
myapp
Linux 能力
# 丢弃所有能力,仅添加必要的
docker run \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
myapp
# 常用能力说明:
# NET_BIND_SERVICE - 绑定 1024 以下端口
# NET_ADMIN - 网络配置(iptables 等)
# SYS_PTRACE - 进程追踪(调试器)
镜像扫描
# Trivy(开源漏洞扫描器)
trivy image nginx:latest
trivy image --severity CRITICAL,HIGH myapp:v1.0
# Docker Scout
docker scout cves nginx:latest
docker scout recommendations myapp:latest
# CI 中扫描(发现高危漏洞时失败)
trivy image --exit-code 1 --severity CRITICAL myapp:${TAG}
密钥管理
# 切勿在 Dockerfile 中使用 ENV/ARG 存储密钥
# 错误示例:ARG DB_PASSWORD=secret(会留在镜像层中)
# Docker Compose secrets
services:
app:
image: myapp
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt
# BuildKit secret(不写入镜像层)
# Dockerfile:
# RUN --mount=type=secret,id=npmrc cat /run/secrets/npmrc
# docker build --secret id=npmrc,src=$HOME/.npmrc .