返回首页

IaC 服务器的 Docker Compose:设置

使用 Docker Compose 进行 IaC 个人服务器的方法:bootstrap 和 host-facts 脚本、幂等 nftables 防火墙、带清理的 WireGuard。通过 rsync+ssh 部署、Renovate 更新。DNS/VPN/监控的仓库模板。

IaC 服务器:无需 Ansible 的 Docker Compose up
Advertisement 728x90

用 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 配置)偶尔需要调整。

Google AdInline article slot
# 简化的 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)。实现完全幂等性:

Google AdInline article slot
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、接口。

Google AdInline article slot
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

Advertisement 728x90

继续阅读