Files
nginx-proxy-manager/PROJECT_DOCUMENTATION.md
kappa 4b3e1a0baf docs: Update PROJECT_DOCUMENTATION.md with Podman + Quadlet automation
Complete rewrite of project documentation focusing on Podman containerization
and systemd-based auto-start using Quadlet. Key improvements:

- Replace Cloudflare R2 log streaming with container automation
- Add comprehensive kernel tuning for production workloads
- Implement rootless container with privileged port binding
- Document complete auto-start system with 40-second boot time
- Include troubleshooting, security considerations, and operations guide
- Validate all configurations through reboot testing

System: Debian 13 (Trixie) + Podman 5.4.2 + Quadlet + systemd
Ports: 80 (HTTP), 81 (Admin UI), 443 (HTTPS)
Auto-start:  Verified with full reboot test

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 10:17:40 +09:00

9.0 KiB

Nginx Proxy Manager 자동화 구축 문서

📅 프로젝트 개요

작업일: 2025년 9월 11일
서버: AWS EC2 Instance (3.35.209.51)
OS: Debian 13 (Trixie), Kernel 6.12.41
목적: Podman + Quadlet을 활용한 nginx-proxy-manager 자동 실행 시스템 구축

🏗️ 시스템 아키텍처

1. 컨테이너 런타임

  • Podman 5.4.2: Rootless 컨테이너 엔진
  • Quadlet: systemd 기반 컨테이너 오케스트레이션
  • systemd: 서비스 자동 시작 및 관리

2. 네트워크 구성

  • 포트 바인딩: 80 (HTTP), 81 (관리 UI), 443 (HTTPS)
  • 네트워크 백엔드: netavark (Podman 기본)
  • DNS: pasta를 통한 네트워크 격리

🔧 시스템 설정

1. 커널 튜닝 설정

파일: /etc/sysctl.d/99-container-tuning.conf

# 메모리 관리
vm.swappiness=10
vm.dirty_ratio=15
vm.vfs_cache_pressure=50

# 네트워크 최적화 (프록시 워크로드)
net.core.somaxconn=65535
net.core.netdev_max_backlog=5000
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_max_syn_backlog=8192
net.ipv4.ip_unprivileged_port_start=80

# 컨테이너 최적화
kernel.pid_max=4194304
vm.max_map_count=262144
fs.file-max=2097152

핵심 설정:

  • net.ipv4.ip_unprivileged_port_start=80: rootless 컨테이너에서 포트 80 사용 허용
  • vm.swappiness=10: 스왑 사용률 최소화로 컨테이너 성능 향상
  • net.core.somaxconn=65535: 대용량 연결 처리를 위한 소켓 큐 확장

2. systemd 리소스 제한

파일: /etc/systemd/system.conf.d/limits.conf

[Manager]
DefaultLimitNOFILE=65536
DefaultLimitNPROC=65536
DefaultLimitCORE=infinity
DefaultLimitMEMLOCK=infinity

3. 사용자 서비스 활성화

# 사용자 서비스 영구 활성화 (로그인 없이 자동 시작)
sudo loginctl enable-linger admin

📦 Quadlet 설정

1. 디렉토리 구조

~/.config/containers/systemd/
└── nginx-proxy-manager.container

2. Quadlet 설정 파일

파일: ~/.config/containers/systemd/nginx-proxy-manager.container

[Unit]
Description=Nginx Proxy Manager
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers

[Container]
Image=docker.io/jc21/nginx-proxy-manager:latest
ContainerName=nginx-proxy-manager
AutoUpdate=registry
PublishPort=80:80
PublishPort=81:81
PublishPort=443:443
Volume=nginx-proxy-manager-data:/data
Volume=nginx-proxy-manager-letsencrypt:/etc/letsencrypt
Environment=DISABLE_IPV6=true

[Service]
Restart=always
TimeoutStartSec=900

[Install]
WantedBy=default.target

3. Quadlet 작동 원리

  1. Quadlet이 .container 파일을 읽어 systemd 서비스 파일 자동 생성
  2. systemd가 생성된 서비스를 default.target에 등록
  3. 부팅 시 자동으로 컨테이너 시작

🚀 설치 및 배포 절차

1. 기본 시스템 설정

# 시스템 업데이트
sudo apt update

# Podman 설치
sudo apt install -y podman

# 사용자 lingering 활성화
sudo loginctl enable-linger admin

2. 커널 튜닝 적용

# 커널 파라미터 설정
sudo tee /etc/sysctl.d/99-container-tuning.conf << EOF
# [위의 커널 튜닝 설정 내용]
EOF

# systemd 리소스 제한 설정
sudo mkdir -p /etc/systemd/system.conf.d
sudo tee /etc/systemd/system.conf.d/limits.conf << EOF
# [위의 systemd 설정 내용]
EOF

# 커널 파라미터 즉시 적용
sudo sysctl -p /etc/sysctl.d/99-container-tuning.conf

3. Quadlet 설정 배포

# Quadlet 디렉토리 생성
mkdir -p ~/.config/containers/systemd

# nginx-proxy-manager 설정 파일 생성
cat > ~/.config/containers/systemd/nginx-proxy-manager.container << EOF
# [위의 Quadlet 설정 내용]
EOF

# systemd 데몬 재로드
systemctl --user daemon-reload

# 서비스 시작
systemctl --user start nginx-proxy-manager.service

📊 리부팅 테스트 결과

부팅 타임라인 (2025-09-11 테스트)

01:13:13 - 시스템 셧다운 시작
01:13:17 - nginx-proxy-manager 정상 종료
-- 리부팅 --
01:13:53 - nginx-proxy-manager 자동 시작 (부팅 후 40초)
01:13:58 - 서비스 완전 준비 완료

검증된 기능

  • 자동 시작: 부팅 후 40초 만에 서비스 시작
  • 포트 바인딩: 80, 81, 443 포트 정상 바인딩
  • 커널 파라미터 유지: 리부팅 후에도 모든 설정 유지
  • 서비스 안정성: systemd를 통한 자동 재시작
  • 컨테이너 생성: 새로운 컨테이너 ID로 정상 생성

🔧 운영 관리

서비스 관리 명령어

# 서비스 상태 확인
systemctl --user status nginx-proxy-manager.service

# 서비스 중지/시작/재시작
systemctl --user stop nginx-proxy-manager.service
systemctl --user start nginx-proxy-manager.service
systemctl --user restart nginx-proxy-manager.service

# 서비스 로그 확인
journalctl --user -u nginx-proxy-manager.service -f

# 컨테이너 상태 확인
podman ps

# 포트 바인딩 확인
ss -tlnp | grep ':80\|:81\|:443'

컨테이너 관리

# 컨테이너 내부 접근
podman exec -it nginx-proxy-manager /bin/bash

# 볼륨 확인
podman volume ls

# 컨테이너 로그 확인
podman logs nginx-proxy-manager

# 이미지 업데이트 (AutoUpdate=registry로 자동)
podman auto-update

시스템 파라미터 확인

# 커널 파라미터 확인
cat /proc/sys/net/ipv4/ip_unprivileged_port_start
cat /proc/sys/vm/swappiness
cat /proc/sys/net/core/somaxconn

# Lingering 상태 확인
loginctl show-user admin | grep Linger

# 서비스 의존성 확인
systemctl --user list-dependencies nginx-proxy-manager.service

🛡️ 보안 고려사항

1. Rootless 컨테이너

  • 루트 권한 없이 컨테이너 실행
  • 호스트 시스템과 격리된 사용자 네임스페이스
  • 보안 취약점 영향 범위 최소화

2. 네트워크 격리

  • pasta를 통한 네트워크 네임스페이스 격리
  • 컨테이너별 독립적인 네트워크 스택
  • 불필요한 포트 노출 차단

3. 자동 업데이트

  • AutoUpdate=registry: 레지스트리에서 최신 이미지 자동 갱신
  • 보안 패치 자동 적용
  • podman auto-update 명령으로 수동 업데이트 가능

📈 성능 최적화

1. 메모리 관리

  • vm.swappiness=10: 메모리 우선 사용으로 I/O 대기 시간 감소
  • vm.dirty_ratio=15: 쓰기 성능 최적화
  • vm.vfs_cache_pressure=50: 파일시스템 캐시 효율성 향상

2. 네트워크 성능

  • net.core.somaxconn=65535: 대용량 동시 연결 처리
  • net.core.netdev_max_backlog=5000: 네트워크 패킷 처리 최적화
  • net.ipv4.tcp_fin_timeout=30: TCP 연결 종료 시간 단축

3. 컨테이너 최적화

  • kernel.pid_max=4194304: 대용량 프로세스 지원
  • fs.file-max=2097152: 파일 디스크립터 한계 확장
  • vm.max_map_count=262144: 메모리 매핑 영역 확장

🔍 트러블슈팅

서비스 시작 실패

# 서비스 상태 및 로그 확인
systemctl --user status nginx-proxy-manager.service --no-pager
journalctl --user -u nginx-proxy-manager.service -n 20

# Quadlet 설정 검증
/usr/libexec/podman/quadlet --user --dryrun

# 포트 충돌 확인
ss -tlnp | grep ':80\|:81\|:443'

포트 바인딩 실패

# 커널 파라미터 확인
cat /proc/sys/net/ipv4/ip_unprivileged_port_start

# 수동으로 커널 파라미터 적용
sudo sysctl net.ipv4.ip_unprivileged_port_start=80

# 영구 설정 확인
cat /etc/sysctl.d/99-container-tuning.conf

자동 시작 실패

# Lingering 상태 확인
loginctl show-user admin | grep Linger

# Lingering 활성화
sudo loginctl enable-linger admin

# 서비스 활성화 확인
systemctl --user is-enabled nginx-proxy-manager.service

🎯 확장 및 개선 방향

1. 모니터링 시스템

  • Prometheus + Grafana를 통한 컨테이너 메트릭 수집
  • 로그 중앙화 (ELK Stack 또는 Loki)
  • 알림 시스템 (서비스 다운 시 Slack/이메일 알림)

2. 백업 및 복구

  • 컨테이너 볼륨 정기 백업
  • 설정 파일 버전 관리 (Git)
  • 재해 복구 절차 수립

3. 고가용성

  • 다중 노드 클러스터 구성
  • 로드 밸런서를 통한 트래픽 분산
  • 헬스체크 및 자동 복구

4. 보안 강화

  • Podman의 SELinux 연동
  • 컨테이너 이미지 취약점 스캔
  • 네트워크 정책 세분화

프로젝트 성과

  1. 완전 자동화: 부팅 시 무인 자동 시작 달성
  2. 안정성: systemd 기반 서비스 관리로 높은 안정성 확보
  3. 성능 최적화: 커널 튜닝을 통한 프록시 워크로드 최적화
  4. 보안: Rootless 컨테이너로 보안 위험 최소화
  5. 유지보수성: Quadlet을 통한 선언적 설정 관리

📝 기술 스택

  • 컨테이너: Podman 5.4.2 (Rootless)
  • 오케스트레이션: Quadlet + systemd
  • 네트워킹: netavark + pasta
  • OS: Debian 13 (Trixie)
  • 관리도구: systemctl, journalctl, podman CLI

Documentation created: 2025-09-11
System tested and operational: 리부팅 테스트 완료
Auto-start verification: 40초 만에 자동 시작 확인