홈으로 돌아가기

IaC 서버를 위한 Docker Compose: 설정

IaC 개인 서버를 위한 Docker Compose 접근법: bootstrap 및 host-facts 스크립트, 멱등 nftables 방화벽, 정리 포함 WireGuard. rsync+ssh를 통한 배포, Renovate 업데이트. DNS/VPN/모니터링을 위한 Repo 템플릿.

IaC 서버: Ansible 없이 Docker Compose up
Advertisement 728x90

Docker Compose로 개인 서버 IaC 관리하기

실제 경험으로 입증된 바에 따르면, docker compose up으로 1~5대 서버를 관리하면 Ansible 없이도 인프라 as 코드(IaC)를 효율적으로 구현할 수 있습니다. 이 방법은 docker-compose.yml에 익숙하고, 수동 설정 경험이 있으며 자동화에 대한 열정이 있어야 합니다. 핵심 요소는 rsync + SSH 배포 스크립트와 Git에 비밀을 저장하는 것(git-secret이나 sops 사용)입니다. Docker Compose는 멱등성을 제공해 수동 작업을 크게 줄여줍니다.

템플릿이 포함된 리포지토리는 DNS/이메일(주/보), VPN(WireGuard), nftables 방화벽, Netdata 모니터링(Telegram 알림)을 보여줍니다. 문서와 인프라 다이어그램도 포함되어 있습니다.

초기 설정 및 부트스트랩

새 서버의 경우 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를 설정하고, 컨테이너가 upmigrate.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의 bind-mount를 통해 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

다음 읽기