Nginx Proxy Manager와 HAProxy를 활용한 웹서버 구축하기

김상진 ·2025년 3월 24일

infra

목록 보기
3/6

이전 포스트에서는 Terraform을 이용하여 AWS EC2 인스턴스를 프로비저닝하고 기본적인 인프라를 구축했습니다. 이번에는 그 다음 단계로 Nginx Proxy Manager와 HAProxy를 이용한 웹 서버 설정 방법에 대해 살펴보겠습니다.

도메인 연결 및 웹서버 설정하기

1. 공인 IP 확인하기

Terraform으로 EC2 인스턴스를 생성한 후, AWS 콘솔이나 CLI를 통해 할당된 공인 IP를 확인합니다. 이전 포스트에서 생성한 Elastic IP(EIP)를 확인하면 됩니다.

2. 도메인 구매 및 DNS 설정

가비아와 같은 도메인 등록 서비스를 통해 도메인을 구매한 후, DNS 설정을 통해 공인 IP와 연결해야 합니다.

가비아에서 DNS 레코드를 다음과 같이 설정했습니다:

가비아 DNS 레코드 설정

주요 설정 포인트:

  • A 레코드를 생성하여 도메인(또는 서브도메인)을 EC2 인스턴스의 공인 IP와 연결
  • TTL(Time To Live) 값은 적절히 설정 (낮게 설정하면 변경사항이 빨리 반영되지만 DNS 서버에 부하가 증가)

3. Nginx Proxy Manager 설정

EC2 인스턴스에 접속한 후, 브라우저를 통해 공인IP:81/nginx/proxy로 Nginx Proxy Manager의 관리자 페이지에 접속합니다.

참고: 초기 로그인 정보는 일반적으로 이메일: admin@example.com / 비밀번호: changeme 입니다. 최초 로그인 시 비밀번호를 변경해야 합니다.

로그인 후 새로운 호스트를 생성합니다:

호스트 생성 화면

설정 항목:

  • Domain Names: 가비아에서 구매한 도메인 입력 (예: api.cotree.site)
  • Scheme: HTTP 또는 HTTPS 선택
  • Forward Hostname / IP: HAProxy가 실행 중인 컨테이너의 내부 IP 또는 컨테이너 이름(예: ha_proxy_1)
  • Forward Port: HAProxy가 리스닝하는 포트(예: 80)
  • Cache Assets: 정적 자산을 캐싱할지 여부
  • Block Common Exploits: 일반적인 웹 취약점 공격 차단 설정

4. SSL 인증서 설정

보안 연결을 위해 SSL 인증서를 설정하는 것이 중요합니다. Nginx Proxy Manager는 Let's Encrypt를 통한 무료 SSL 인증서 발급을 지원합니다.

SSL 설정 화면:
SSL 설정 화면

SSL 설정 옵션:

  • SSL Certificate: Let's Encrypt 또는 사용자 지정 인증서 선택
  • Force SSL: HTTP 요청을 HTTPS로 리다이렉트 (권장)
  • HTTP/2 Support: 더 빠른 웹 성능을 위한 HTTP/2 프로토콜 활성화
  • HSTS Enabled: HTTPS 연결 강제화를 위한 HSTS(HTTP Strict Transport Security) 설정
  • HSTS Subdomains: 서브도메인에도 HSTS 적용 여부

HAProxy 설정 살펴보기

Terraform 코드에서 이미 HAProxy 설정을 포함했지만, 여기서 좀 더 자세히 살펴보겠습니다.

global
    lua-load /usr/local/etc/haproxy/lua/retry_on_502_504.lua

resolvers docker
    nameserver dns1 127.0.0.11:53
    resolve_retries       3
    timeout retry         1s
    hold valid            10s

defaults
    mode http
    timeout connect 5s
    timeout client 60s
    timeout server 60s

frontend http_front
    bind *:80
    acl host_app1 hdr_beg(host) -i api.cotree.site

    use_backend http_back_1 if host_app1

backend http_back_1
    balance roundrobin
    option httpchk GET /actuator/health
    default-server inter 2s rise 1 fall 1 init-addr last,libc,none resolvers docker
    option redispatch
    http-response lua.retry_on_502_504

    server app_server_1_1 app1_1:8080 check
    server app_server_1_2 app1_2:8080 check

주요 설정 포인트:

  1. Lua 스크립트 로드: 502, 504 에러 발생 시 자동으로 재시도하는 스크립트
  2. Docker DNS 해석기: Docker 컨테이너 네트워크에서 이름 해석을 위한 설정
  3. 타임아웃 설정: 연결, 클라이언트, 서버에 대한 타임아웃 값 지정
  4. 프론트엔드 설정: 호스트 헤더에 따라 백엔드 서버 선택
  5. 백엔드 설정:
    • balance roundrobin: 라운드 로빈 방식의 로드 밸런싱
    • option httpchk: 헬스 체크 설정 (/actuator/health 엔드포인트 사용)
    • default-server: 서버 상태 체크 주기 및 방식 설정
    • option redispatch: 서버 연결 실패 시 다른 서버로 재시도
    • 여러 서버 설정 (app1_1, app1_2)

구성의 장점

이런 구성을 통해 얻을 수 있는 이점은 다음과 같습니다:

  1. 로드 밸런싱: 여러 애플리케이션 서버 간에 트래픽 분산
  2. 자동 장애 복구: 서버 장애 시 다른 서버로 자동 전환
  3. 헬스 체크: 주기적인 상태 확인으로 장애 서버 감지
  4. SSL 오프로딩: Nginx에서 SSL 처리를 담당하여 백엔드 서버의 부담 감소
  5. 보안 강화: 프록시 레이어를 통한 직접적인 서버 접근 방지

다음 단계

웹서버 구성 후 다음과 같은 작업을 추가로 고려해볼 수 있습니다:

  1. 모니터링 설정: Prometheus와 Grafana를 활용한 상세 모니터링
  2. 로그 관리: 중앙화된 로그 수집 및 분석 시스템 구축
  3. 자동화된 백업: 데이터베이스 및 설정 파일 정기 백업
  4. CI/CD 파이프라인: 자동화된 배포 프로세스 구축

마무리

Nginx Proxy Manager와 HAProxy를 조합하여 안정적이고 확장 가능한 웹 서비스 인프라를 구축했습니다. Terraform을 통한 인프라 코드화(IaC)와 함께 이러한 구성은 일관된 환경 설정과 관리를 가능하게 합니다.

Docker 컨테이너를 활용하여 각 서비스를 격리하고, 네트워크로 연결함으로써 유연하게 서비스를 확장하거나 교체할 수 있는 구조를 갖추었습니다.

profile
알고리즘은 백준 허브를 통해 github에 꾸준히 올리고 있습니다.🙂

0개의 댓글