用 Docker Compose 作为 IaC 管理个人服务器
实际经验表明,管理 1–5 台服务器时,使用 docker compose up 可以简化 基础设施即代码(IaC),无需依赖 Ansible。这种方法需要熟悉 docker-compose.yml、手动搭建经验,以及自动化热情。核心组件包括 rsync + SSH 部署脚本,以及使用 sops 或 git-secret 在 Git 中存储密钥。Docker Compose 提供幂等性,大幅减少手动操作。
仓库模板展示了 DNS/邮件(主备)、VPN(WireGuard)、nftables 防火墙,以及带 Telegram 告警的 Netdata 监控。包含文档和基础设施图表。
初始设置与引导
对于新服务器,创建 bootstrap.sh——一个最小化脚本,用于安装 Docker。可手动运行或通过 cloud-init 执行。示例保持变更最小:OS 升级(如 do-release-upgrade)或控制台工具(nvim 配置)偶尔需要调整。
# 简化的 bootstrap.sh 片段
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker compose version
脚本跳过冗余手动步骤,直奔 Docker 主题。
nftables 实现幂等防火墙
Docker 会修改 ip/ip6 族的 nftables 规则。将你的规则存放在 inet 族,避免冲突。bootstrap.sh 设置 /etc/nftables.conf,容器在 up 时应用 migrate.nft。
使用 dockerize 渲染并注入变量(如从 host-facts.sh 获取的 IP)。实现完全幂等性:
flush ruleset inet
flush chain ip filter DOCKER-USER
flush chain ip6 filter DOCKER-USER
table inet filter {
chain prerouting-before-docker {
type filter hook prerouting priority dstnat - 2;
# Docker NAT 前的过滤
}
}
处理 WireGuard 和系统邮件
WireGuard 创建内核接口:停止容器时需拆除。
finish() {
wg-quick down "$INTERFACE"
}
trap finish EXIT
wg-quick up "$INTERFACE"
sleep inf
系统邮件(来自 systemd、unattended-upgrades)通过将 /var/spool/postfix 绑定挂载到 postfix 容器中路由。主机与容器共享队列。
host-facts.sh 获取服务器特定信息
此脚本为 docker-compose.yml 生成环境变量:IP、UID/GID、接口。
uid() { getent passwd "$1" | cut -d: -f3; }
gid() { getent group "$1" | cut -d: -f3; }
metadata() { curl -s "http://169.254.169.254/metadata/v1$1"; }
set -euo pipefail
if test -z "${DEVEL:-}"; then
WAN_IP="$(metadata /interfaces/public/0/ipv4/address)"
UID_POSTFIX="$(uid postfix)"
GID_POSTFIX="$(gid postfix)"
else
WAN_IP=0.0.0.0
UID_POSTFIX=1001
GID_POSTFIX=1001
fi
for _var in WAN_IP UID_POSTFIX GID_POSTFIX; do eval "export $_var=\"$${_var}\""; done
— Editorial Team
暂无评论。