Docker Compose安全加固指南

为家庭实验室和自托管环境提供结构化、安全加固且易于维护的Docker Compose堆栈参考指南,包含最佳实践、故障排除和监控配置。

  • by UniversalSyntropy
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 UniversalSyntropy/docker-compose-field-guide

使用说明

Docker编写字段指南

构建结构良好、安全可靠且易于维护的Docker Compose堆栈的参考。针对家庭实验室和自托管设置。

它为两个读者服务:通过指南和食谱的人,以及通过人工智能编码代理的人 机器可读标准(CLAUDE.md, 代理商.md)和a MCP服务器 这将指南作为可调用的工具公开。第二部分是什么 它与众不同——你的工具遵循与你相同的标准。

要求: 使用Docker Compose v2的Docker引擎24+(docker compose 插件)。

范围: 家庭实验室/自托管/面向局域网的服务。 如果你将服务暴露在互联网上,这是一个合理的起点,但你还需要一个具有TLS、速率限制和更严格网络策略的反向代理。 请参阅 威胁模型注释.

货币: 这样的参考只有在最后一次维护通过时才有效 图像标签和外部链接腐烂——检查 更新日志 在部署任何东西之前,请根据注册表验证映像引脚。


这是给谁的

  • 您运行家庭实验室、NAS、Pi或小型服务器
  • 您了解基本的Linux,并且之前至少运行过一个容器
  • 您希望在不读取CIS Benchmark端到端的情况下正确地执行操作——安全、备份、日志轮换
  • 你厌倦了从Stack Overflow片段拼凑而成的Compose文件

这不是什么

  • 初学者教程——如果你从未使用过Docker,请从 DOCKER-BASICS.md
  • 大规模生产、Kubernetes或Swarm部署指南
  • 一种即插即用的解决方案——您需要使模板适应您的服务

包含什么

  • 注释 docker-compose.yml 模板 --把它复制到你的项目中。包括安全默认值、日志轮换、资源限制和健康检查作为起始基线。
  • 21节最佳做法 --从 网络信任区 和 秘密管理 到 USB直通 和 跨平台陷阱。仅WSL2/NNTFS警告即可为您节省数小时。
  • 故障排除指南 --循序渐进 调试手册, 决策树,并修复了孤立容器、端口冲突和重新创建后“消失”的数据。
  • 监控堆栈 --Prometheus、Grafana、节点导出器和cAdvisor。您希望适应您的设置的参考配置(Node Exporter仅在Linux上提供有意义的主机指标)。
  • 硬化食谱 --已准备好部署模板 Pi孔, 云端下一站,以及 交通 安全例外情况已内联记录。
  • 反向代理和HTTPS指南 --如何使用自动Let’s Encrypt证书将Traefik放在您的服务前面。
  • 高级机密管理 --从纯文本秘密到SOPS、Doppler或git crypt。
  • 辅助脚本 --安全重置、硬盘重置、磁盘报告和修剪。所以你不必记住国旗。
  • 术语表 和 索引 --查找任何术语,或查找文档中讨论主题的位置。
  • 路线图 --v1.2的目标是:每个服务验证、CI引导测试、块目录和更大的配方集。
  • 快速入门堆栈 --主页仪表板+Uptime Kuma,指南推荐的每种模式的双服务演示。如果你通过示例学习,请先部署它。
  • MCP服务器 --11个工具让AI代理加载标准、获取食谱和lint按需组成YAML。看 代理商设置.md 注册。
  • AI代理说明 --对于Claude Code、Copilot、Codex和Cursor,您的编码工具遵循与您相同的标准。

值得一看:

第节 你得到了什么
图像信任框架(T1-T5) 决定是否信任容器映像的实用模型
安全例外表 如何记录 为什么 一项服务违反了规则——以及如何补偿
CIS基准映射 与笔测试仪标记的内容相对应的安全控制
LLM提示模板 复制粘贴提示,让LLM设计、审查和调试您的堆栈
清理水平(安全→ 核能) Docker清理的五个级别,从项目范围到“删除所有内容”
能力备忘单 每种服务类型实际需要哪些Linux功能

从哪里开始

如果你想… 去这里
先尝试一个可用的演示堆栈 快速入门
了解Docker和Compose是什么 DOCKER-BASICS.md
正确设置新堆栈 最佳实践
部署一个真正的应用程序(Pi hole、Nextcloud) 菜谱
使用HTTPS添加反向代理 反向代理指南
加密静态秘密 秘密管理
修理坏了的东西 故障排除
查找一个术语 术语表
查找讨论主题的位置 索引
复制现成的模板 docker-compose.yml
添加监控 监测/
清理磁盘空间或重置堆栈 脚本/
将其与AI编码代理一起使用 代理设置
通过MCP公开现场指导工具 MCP服务器

快速开始

尝试快速启动堆栈

一个准备运行的堆栈,带有仪表板和监控工具,用于演示 本指南中的每个模式:

cd quickstart
cp .env.example .env
docker compose up -d
# Dashboard: http://localhost:3000   Monitoring: http://localhost:3001

看 快速入门/README.md 有关设置的详细信息。

在您自己的项目中使用该模板

# 1. Copy the template into your project
cp docker-compose.yml ~/my-project/docker-compose.yml
cp .env.example ~/my-project/.env

# 2. Create secrets (never committed to git)
mkdir -p ~/my-project/secrets
echo -n "your-password" > ~/my-project/secrets/db_password.txt

# 3. Validate before deploying
cd ~/my-project
docker compose config --quiet

# 4. Deploy
docker compose up -d

# 5. Verify
docker compose ps

模板是 起点,不是一滴解决方案。你需要交换自己的图像、卷和秘密。注释解释了每个块的作用及其原因。


建筑

从用户的浏览器开始,一个坚固的家庭实验室堆栈是如何组合在一起的 到隔离容器和只读卷:

flowchart TD
    User([User / Browser])
    User -->|HTTPS 443| Proxy

    subgraph docker [Docker Host]
        Proxy[Reverse Proxy<br/>Traefik / Caddy]

        subgraph frontend [Frontend Network]
            App1[App Container<br/>e.g. Nextcloud]
            App2[App Container<br/>e.g. Grafana]
        end

        subgraph backend [Backend Network — no external access]
            DB[(Database<br/>Postgres / MariaDB)]
            Cache[(Cache<br/>Redis)]
        end

        subgraph storage [Volumes & Secrets]
            Vols[Bind Mounts<br/>read-only where possible]
            Secrets["/run/secrets/*<br/>file-based, never in .env"]
        end

        Proxy -->|HTTP internal| App1
        Proxy -->|HTTP internal| App2
        App1 --> DB
        App1 --> Cache
        App2 --> DB
        DB --- Vols
        DB --- Secrets
        App1 --- Vols
    end

    style Proxy fill:#4a9eff,color:#fff
    style DB fill:#e67e22,color:#fff
    style Cache fill:#e67e22,color:#fff
    style App1 fill:#2ecc71,color:#fff
    style App2 fill:#2ecc71,color:#fff
    style Secrets fill:#e74c3c,color:#fff
    style backend fill:#fff3e0,stroke:#e67e22
    style frontend fill:#e8f5e9,stroke:#2ecc71

每个容器都与 cap_drop: ALL, no-new-privileges,资源 限制和日志轮换。网络隔离信任区域——数据库 无法从互联网访问,机密以文件形式挂载,而不是 作为环境变量传递。


硬化是什么样子的

简单的Compose服务与应用本指南默认值的相同服务:

Before — common but fragile
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    restart: always
After — hardened baseline
services:
  web:
    image: nginx:1.27.4                    # Pin to exact version
    security_opt:
      - no-new-privileges:true             # Block privilege escalation
    cap_drop: [ALL]                        # Drop all capabilities
    cap_add:
      - NET_BIND_SERVICE                   # Only what's needed for port 80
    read_only: true                        # Immutable root filesystem
    tmpfs:
      - /tmp
      - /var/cache/nginx
      - /run
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro    # Read-only bind mount
    mem_limit: 128m                        # Prevent OOM killing neighbours
    cpus: 0.5                              # Prevent CPU starvation
    pids_limit: 100                        # Prevent fork bombs
    restart: unless-stopped                # Respect manual stops
    logging:
      driver: json-file
      options: { max-size: "10m", max-file: "3" }
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
    networks:
      - frontend

每个指令都在 最佳实践. 这 带注释的模板 是复制粘贴的起点。


辅助脚本

# Restart a stack without losing data
./scripts/safe-reset.sh [path/to/docker-compose.yml]

# Full teardown + rebuild (WARNING: deletes volumes)
./scripts/hard-reset.sh [path/to/docker-compose.yml]

# See what Docker is using on disk
./scripts/docker-disk-report.sh

# Remove unused resources (stopped containers, dangling images, etc.)
./scripts/prune-unused.sh              # Safe mode
./scripts/prune-unused.sh --aggressive # Also removes all unused images + volumes

最佳做法----所涉主题

# 主题 # 主题
1 编写文件结构 12 更新管理
2 图像管理 13 备份和灾难恢复
3 安全加固 14 监控
4 存储和容量 15 跨平台兼容性
5 主机文件系统设置 16 USB和硬件设备
6 环境和配置 17 渗透测试准备就绪
7 网络 18 容器来源验证
8 资源限制 19 LLM辅助工作流程
9 健康检查和依赖关系 20 新服务清单
10 日志记录 21 参考文献
11 优雅关闭

回购结构

├── README.md                              ← You are here
├── quickstart/
│   ├── README.md                          ← Try this first — working demo stack
│   ├── docker-compose.yml                 ← Homepage dashboard + Uptime Kuma monitoring
│   ├── .env.example                       ← Quickstart environment template
│   └── config/homepage/                   ← Dashboard configuration files
├── CONTRIBUTING.md                        ← How to contribute
├── SECURITY.md                            ← Security policy
├── CHANGELOG.md                           ← What changed
├── GITHUB-METADATA.md                     ← Repo metadata and publication guide
├── LICENSE                                ← MIT licence
├── CLAUDE.md                              ← Claude Code project instructions
├── AGENTS.md                              ← OpenAI Codex agent instructions
├── docker-compose.yml                     ← Annotated template (copy into your project)
├── .env.example                           ← Environment variable template
├── Makefile                               ← Local linting (make lint)
├── recipes/
│   ├── README.md                          ← Recipe overview and usage
│   ├── pihole.yml                         ← Pi-hole DNS ad blocker (hardened)
│   ├── nextcloud.yml                      ← Nextcloud + MariaDB + Redis (hardened)
│   └── traefik.yml                        ← Traefik v3 reverse proxy with HTTPS
├── docs/
│   ├── BEST-PRACTICES.md                  ← Best practices (21 sections)
│   ├── DOCKER-BASICS.md                   ← New to Docker? Start here
│   ├── TROUBLESHOOTING.md                 ← Gotchas, debugging, cleanup, reset recipes
│   ├── REVERSE-PROXY.md                   ← Reverse proxy & HTTPS with Traefik
│   ├── SECRETS-MANAGEMENT.md              ← Advanced secrets: SOPS, Doppler, git-crypt
│   ├── GLOSSARY.md                        ← Definitions for every Docker/Compose term
│   ├── INDEX.md                           ← Find any topic across all files
│   ├── STYLE.md                           ← Voice and style guide for contributors
│   ├── AGENT-SETUP.md                     ← Multi-agent skill pack setup guide
│   └── reviews/                           ← Review reports
├── mcp-server/
│   ├── README.md                         ← MCP server setup and registration
│   ├── server.py                         ← MCP server — exposes tools for AI agents
│   └── requirements.txt                  ← Python dependency (mcp>=1.2.0)
├── .github/
│   ├── copilot-instructions.md            ← GitHub Copilot repo instructions
│   ├── dependabot.yml                     ← Automated Docker + Actions updates
│   ├── ISSUE_TEMPLATE/                    ← Bug report and feature request templates
│   ├── PULL_REQUEST_TEMPLATE.md           ← PR checklist
│   └── workflows/validate.yml             ← CI: lint, validate, live stack test
├── monitoring/
│   ├── docker-compose.yml                 ← Prometheus + Grafana + exporters stack
│   └── prometheus/prometheus.yml          ← Prometheus scrape config template
└── scripts/
    ├── safe-reset.sh                      ← Restart stack without data loss
    ├── hard-reset.sh                      ← Full teardown + rebuild (destroys volumes)
    ├── docker-disk-report.sh              ← Show what Docker is using on disk
    └── prune-unused.sh                    ← Remove unused resources (safe or aggressive)

安全方法

本指南遵循 CIS Docker基准测试 和 OWASP Docker安全备忘单 作为基线。默认值为:

  • 删除所有Linux功能,只添加所需的功能
  • 阻止权限升级(no-new-privileges)
  • 在映像支持的非根目录下运行
  • 使用Docker secrets作为密码(不是环境变量)
  • 尽可能只读根文件系统

这些是 家庭实验室局域网的安全默认值。它们会减少你的攻击面,并抓住常见的错误。 它们不是一个完整的安全架构——如果你将服务暴露在互联网上,你需要更多(反向代理、TLS、WAF、网络策略)。 这 安全硬化段 解释每个控件、何时放松以及如何记录异常。


信任和限制

本指南是:

  • A. 硬化起点 适用于家庭实验室和自托管堆栈
  • 基于已发布的标准(CIS Docker Benchmark、OWASP Docker Security)
  • 在Linux、macOS和Windows/WSL2上使用Docker Engine 24+和Compose v2进行了测试

本指南是 不:

  • 安全审计的替代品
  • 已针对面向互联网的生产进行验证,无需额外控制(反向代理、TLS、WAF)
  • 保证——Docker、Compose和上游镜像会发生变化;根据您的环境进行验证
  • 由安全团队维护——它是一个社区参考

如果你发现错误或差距, 打开一个问题.


标准


快速修复故障

服务无法连接到其他服务

可能原因: 使用 localhost 而不是服务名称。在Compose网络内部, localhost 指容器本身。

修复: 使用服务名称作为主机名(例如。, database:5432,不 localhost:5432).

重启后数据消失

可能原因: 数据存储在容器文件系统或匿名卷中,或 down -v 已删除命名卷。

修复: 对所有持久数据使用显式命名卷或绑定挂载。从备份还原(如果可用)。

端口冲突(“地址已在使用中”)

可能原因: 另一个容器或主机进程正在使用该端口。

修复:

docker ps --format "table {{.Names}}\t{{.Ports}}"
docker compose down --remove-orphans
docker compose up -d

有关完整的调试剧本、决策树和更多修复,请参阅 故障排除.md.


贡献

看 贡献.md 关于如何运行检查、PR中应包含哪些内容以及欢迎哪些更改。 声音和风格指南在 风格.md.

许可证

麻省理工学院