안녕하세요! 🚀 수많은 웹 서비스를 운영하면서 매번 Nginx 설정 파일을 직접 수정하고, SSL 인증서를 갱신하느라 번거로움을 겪으셨나요? 더 이상 걱정하지 마세요! 오늘은 이 모든 과정을 마법처럼 쉽고 직관적으로 만들어주는 Nginx Proxy Manager(NPM)를 Docker Compose를 이용해 설치하고 활용하는 방법에 대해 자세히 알아보겠습니다.
💡 1. Nginx Proxy Manager(NPM)란 무엇인가요?
Nginx Proxy Manager는 이름에서 알 수 있듯이, Nginx를 기반으로 하는 리버스 프록시(Reverse Proxy) 관리 도구입니다. 하지만 단순히 프록시 기능만 제공하는 것이 아닙니다. 웹 기반의 직관적인 사용자 인터페이스(GUI)를 통해 다음과 같은 강력한 기능들을 제공합니다.
- 리버스 프록시 설정: 외부에서 들어오는 요청을 내부의 특정 서버(예: 웹 서버, 애플리케이션 서버)로 전달하는 기능을 쉽게 설정할 수 있습니다. 예를 들어,
blog.example.com
으로 들어온 요청을 내부의192.168.1.100:2368
포트에서 실행 중인 Ghost 블로그로 연결하는 식이죠. - SSL 인증서 관리 (Let’s Encrypt 자동화): 가장 큰 장점 중 하나입니다! Let’s Encrypt를 통해 무료 SSL/TLS 인증서를 손쉽게 발급받고, 자동으로 갱신할 수 있습니다. 웹사이트 보안을 강화하고 HTTPS를 활성화하는 데 필수적인 작업이죠. 🔒
- 사용자 정의 Nginx 지시문: 고급 사용자를 위해 특정 프록시 호스트에 커스텀 Nginx 설정(예: 캐싱, 보안 헤더 추가)을 추가할 수 있습니다.
- 리다이렉션 및 404 페이지 설정: 특정 URL을 다른 URL로 리다이렉션하거나, 존재하지 않는 페이지에 대한 404 에러 페이지를 설정할 수 있습니다.
- 접근 제어 (Basic Auth): 특정 프록시 호스트에 접근할 때 사용자 이름과 비밀번호를 요구하도록 설정할 수 있습니다.
한마디로, NPM은 Nginx 설정과 SSL 인증서 관리를 위한 복잡한 명령어나 설정 파일 편집 없이 웹 브라우저만으로 모든 작업을 처리할 수 있게 해주는 도구입니다.
🤔 2. 왜 Nginx Proxy Manager를 사용해야 할까요?
기존에 Nginx를 직접 설정해 보신 분이라면, nginx.conf
파일을 수정하고, systemctl reload nginx
명령어를 입력하며, Let’s Encrypt certbot
을 수동으로 실행했던 경험이 있을 겁니다. 이 과정은 다음과 같은 문제점을 가지고 있습니다.
- 복잡한 설정 파일: Nginx 설정은 문법이 까다롭고, 오타 하나에도 서비스가 중단될 수 있습니다.
- SSL 인증서 갱신: Let’s Encrypt 인증서는 90일마다 갱신해야 하는데, 이를 수동으로 관리하면 놓치기 쉽습니다.
- 다수의 서비스 관리: 여러 개의 웹 서비스(워드프레스, Nextcloud, Home Assistant 등)를 운영할 경우, 각각의 Nginx 설정을 관리하는 것이 매우 번거롭습니다.
NPM은 이러한 문제들을 해결해 줍니다.
- 직관적인 GUI: 복잡한 Nginx 문법을 몰라도 몇 번의 클릭만으로 프록시 호스트를 생성하고 SSL을 적용할 수 있습니다.
- 자동화된 SSL: Let’s Encrypt 인증서 발급 및 갱신이 완전히 자동화되어, 잊어버릴 걱정이 없습니다.
- 중앙 집중식 관리: 모든 웹 서비스의 리버스 프록시 설정을 NPM 대시보드 한 곳에서 관리할 수 있습니다.
- 시간 절약: 설정에 드는 시간을 줄여 핵심 서비스 개발 및 운영에 집중할 수 있습니다.
🛠️ 3. Docker Compose를 이용한 NPM 설치
Nginx Proxy Manager는 Docker 환경에서 가장 쉽게 배포할 수 있습니다. 특히 Docker Compose를 사용하면 몇 줄의 설정만으로 NPM과 필요한 데이터베이스를 한 번에 구성할 수 있습니다.
3.1. 준비물
- Docker 및 Docker Compose 설치: 서버에 Docker와 Docker Compose가 설치되어 있어야 합니다. 설치되어 있지 않다면, 공식 문서를 참고하여 설치해 주세요. (예:
sudo apt-get install docker.io docker-compose
) - 도메인: 프록시할 서비스에 연결할 도메인 (예:
your-app.com
,blog.your-domain.com
)이 필요하며, 이 도메인의 DNS 설정에서 서버의 공인 IP를 가리키도록 A 레코드 또는 CNAME 레코드가 구성되어 있어야 합니다.
3.2. Docker Compose 파일 작성
NPM은 설정 정보를 저장하기 위한 데이터베이스(MariaDB 또는 MySQL)를 필요로 합니다. 따라서 docker-compose.yml
파일에는 NPM 컨테이너와 데이터베이스 컨테이너 두 가지가 정의됩니다.
# docker-compose.yml
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
ports:
# 웹 트래픽(HTTP)
- '80:80'
# 보안 웹 트래픽(HTTPS)
- '443:443'
# NPM 관리 페이지 (HTTP)
- '81:81'
environment:
DB_MYSQL_HOST: db
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: 'npmuser'
DB_MYSQL_PASSWORD: 'your_db_password' # 강력한 비밀번호로 변경하세요!
DB_MYSQL_DATABASE: 'npm'
volumes:
# NPM 설정 및 인증서 데이터 (영구 저장)
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
depends_on:
- db
restart: unless-stopped
db:
image: 'jc21/mariadb-aria:latest' # 또는 'mysql:8.0'
container_name: nginx-proxy-manager-db
environment:
MYSQL_ROOT_PASSWORD: 'your_root_password' # 강력한 비밀번호로 변경하세요!
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npmuser'
MYSQL_PASSWORD: 'your_db_password' # app 서비스의 DB_MYSQL_PASSWORD와 동일하게 설정
volumes:
# DB 데이터 (영구 저장)
- npm_db:/var/lib/mysql
restart: unless-stopped
volumes:
npm_data:
npm_letsencrypt:
npm_db:
🤔 각 설정의 의미는?
version: '3.8'
: Docker Compose 파일의 버전을 명시합니다. 최신 버전을 사용하는 것이 좋습니다.services
: 실행할 컨테이너들을 정의합니다.app
(NPM 컨테이너):image: 'jc21/nginx-proxy-manager:latest'
: Nginx Proxy Manager 공식 이미지를 사용합니다.container_name: nginx-proxy-manager
: 컨테이너 이름을 지정하여 쉽게 식별할 수 있게 합니다.ports
:80:80
: 외부의 80번 포트를 컨테이너의 80번 포트에 연결 (HTTP).443:443
: 외부의 443번 포트를 컨테이너의 443번 포트에 연결 (HTTPS).81:81
: 외부의 81번 포트를 컨테이너의 81번 포트에 연결 (NPM 관리 UI).- ⚠️ 중요: 서버의 80, 443, 81 포트가 다른 서비스에 의해 사용 중이지 않아야 합니다.
environment
: 데이터베이스 연결 정보를 정의합니다.DB_MYSQL_HOST
는db
서비스의 이름을 사용합니다.volumes
: 컨테이너 내부의 데이터를 호스트 머신에 영구적으로 저장하기 위한 볼륨을 연결합니다.npm_data
는 NPM의 설정 파일과 로그,npm_letsencrypt
는 Let’s Encrypt 인증서 파일을 저장합니다.depends_on: - db
:app
컨테이너가db
컨테이너가 먼저 시작된 후에 실행되도록 지정합니다.restart: unless-stopped
: 컨테이너가 종료되더라도 자동으로 재시작하도록 설정합니다.
db
(데이터베이스 컨테이너):image: 'jc21/mariadb-aria:latest'
: MariaDB 이미지를 사용합니다. MySQL을 원하면mysql:8.0
등으로 변경할 수 있습니다.container_name: nginx-proxy-manager-db
: 데이터베이스 컨테이너의 이름입니다.environment
: 데이터베이스의 루트 비밀번호, 데이터베이스 이름, 사용자 이름, 사용자 비밀번호를 설정합니다. 반드시 강력한 비밀번호로 변경하세요! (MYSQL_USER
와MYSQL_PASSWORD
는app
컨테이너의DB_MYSQL_USER
와DB_MYSQL_PASSWORD
와 동일해야 합니다.)volumes: - npm_db:/var/lib/mysql
: 데이터베이스 데이터를 영구적으로 저장하기 위한 볼륨입니다.
volumes
:services
섹션에서 사용될 명명된 볼륨(Named Volume)을 정의합니다. Docker가 자동으로 생성하고 관리합니다.
3.3. NPM 실행
- 위
docker-compose.yml
파일을 서버의 원하는 디렉토리(예:~/npm
)에 생성합니다. - 해당 디렉토리로 이동합니다.
cd ~/npm
- Docker Compose를 이용하여 컨테이너를 실행합니다.
docker compose up -d
up
은 컨테이너를 생성하고 시작하며,-d
옵션은 백그라운드에서 실행하도록 합니다.
모든 과정이 정상적으로 완료되면, docker compose ps
명령어로 컨테이너들이 잘 실행되고 있는지 확인할 수 있습니다.
docker compose ps
출력에서 nginx-proxy-manager
와 nginx-proxy-manager-db
컨테이너의 상태가 Up
으로 표시되어야 합니다.
🌐 4. Nginx Proxy Manager 기본 설정 및 활용
컨테이너가 성공적으로 실행되었다면, 이제 웹 브라우저를 통해 NPM 관리 페이지에 접속해 설정을 시작할 수 있습니다.
4.1. NPM 관리 페이지 접속
웹 브라우저를 열고 서버의 IP 주소와 81번 포트를 이용하여 접속합니다.
http://서버_IP_주소:81
(예: http://192.168.1.100:81
)
4.2. 초기 로그인 정보
최초 로그인 시 다음 기본 계정 정보를 사용합니다.
- Email:
admin@example.com
- Password:
changeme
로그인 후에는 보안을 위해 반드시 이메일 주소와 비밀번호를 변경하라는 메시지가 나타납니다. 즉시 변경해 주세요. 🔒
4.3. 프록시 호스트 추가 (Proxy Hosts)
이제 NPM의 핵심 기능인 ‘프록시 호스트’를 추가해 보겠습니다.
-
NPM 대시보드에서 좌측 메뉴의 ‘Hosts’ -> ‘Proxy Hosts’를 클릭합니다.
-
우측 상단의 ‘Add Proxy Host’ 버튼을 클릭합니다.
-
Details 탭 설정:
- Domain Names: 이 프록시 호스트로 접근할 도메인 이름을 입력합니다. (예:
blog.your-domain.com
) 여러 개를 추가할 수 있습니다. - Scheme: 내부 서비스의 프로토콜 (HTTP 또는 HTTPS)을 선택합니다. 대부분
http
를 사용합니다. - Forward Hostname / IP: 내부 서비스가 실행 중인 서버의 IP 주소 또는 호스트 이름을 입력합니다. (예:
192.168.1.10
또는my-app-server
) - Forward Port: 내부 서비스가 사용 중인 포트 번호를 입력합니다. (예:
2368
for Ghost,8000
for Django) Block Common Exploits
: 일반적인 웹 공격을 차단하는 옵션입니다. 활성화하는 것을 권장합니다.Websockets Support
: 웹소켓을 사용하는 서비스 (예: Home Assistant, 채팅 앱)라면 활성화합니다.
(예시: blog.your-domain.com -> http://192.168.1.10:2368)
- Domain Names: 이 프록시 호스트로 접근할 도메인 이름을 입력합니다. (예:
-
SSL 탭 설정:
- SSL Certificate:
Request a new SSL Certificate
를 선택합니다. Force SSL
: HTTP 요청을 HTTPS로 강제 리다이렉션합니다. 보안을 위해 반드시 활성화하세요.HTTP/2 Support
: 최신 HTTP/2 프로토콜을 사용합니다. 성능 향상을 위해 활성화하는 것이 좋습니다.I Agree to the Let's Encrypt Terms of Service
: 약관 동의를 체크합니다.Email Address for Let's Encrypt
: Let’s Encrypt 관련 알림을 받을 이메일 주소를 입력합니다.
- SSL Certificate:
-
Advanced 탭 (선택 사항):
- Nginx 설정 파일에 직접 추가하고 싶은 지시문이 있다면 이곳에 입력합니다. 예를 들어, 특정 캐싱 규칙이나 보안 헤더를 추가할 수 있습니다.
- 예시:
add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff";
-
모든 설정을 마쳤다면 ‘Save’ 버튼을 클릭합니다.
잠시 후, NPM이 Let’s Encrypt를 통해 SSL 인증서를 자동으로 발급받고 Nginx 설정을 적용합니다. 모든 과정이 성공적으로 완료되면, 이제 https://blog.your-domain.com
과 같이 설정한 도메인으로 접속하여 서비스를 확인할 수 있습니다! ✨
4.4. 기타 활용 기능
- Redirection Hosts: 특정 도메인을 다른 URL로 리다이렉션할 때 사용합니다. (예:
old-site.com
->new-site.com
) - 404 Hosts: 존재하지 않는 페이지에 대한 기본 404 에러 페이지를 설정합니다.
- Streams: TCP/UDP 포트 포워딩을 설정할 때 사용합니다. (HTTP/HTTPS가 아닌 다른 프로토콜의 트래픽을 전달할 때 유용)
- Users: NPM 관리 페이지에 접근할 수 있는 추가 사용자를 관리합니다.
- Audit Log: NPM에서 발생한 모든 설정 변경 및 이벤트 기록을 확인할 수 있습니다. 문제 발생 시 디버깅에 유용합니다.
⚠️ 5. 팁 및 주의사항
- DNS 설정 필수!
NPM이 Let’s Encrypt 인증서를 성공적으로 발급받고, 외부에서 서비스에 접근하려면 설정하려는 도메인이 반드시 NPM이 설치된 서버의 공인 IP 주소를 가리키고 있어야 합니다. 도메인 등록 업체나 DNS 관리 서비스에서 A 레코드(
your-domain.com
->서버_IP_주소
) 또는 CNAME 레코드(sub.your-domain.com
->your-domain.com
또는 다른 도메인)를 올바르게 설정해야 합니다. - 방화벽 설정
서버의 방화벽(예:
ufw
또는 클라우드 서비스의 보안 그룹)에서 80번 (HTTP), 443번 (HTTPS), 81번 (NPM 관리 페이지) 포트를 외부에서 접근할 수 있도록 열어주어야 합니다.sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow 81/tcp sudo ufw reload
- 데이터 백업 💾
docker-compose.yml
파일에서 정의한npm_data
,npm_letsencrypt
,npm_db
볼륨에는 NPM의 모든 설정, 인증서, 데이터베이스 정보가 저장됩니다. 서버에 문제가 발생할 경우를 대비하여 이 볼륨들을 정기적으로 백업하는 것이 중요합니다. (예:docker cp nginx-proxy-manager:/data ./npm_data_backup
) - 포트 충돌 해결
만약 서버의 80번 또는 443번 포트가 이미 다른 웹 서버(Apache, Nginx 등)에 의해 사용 중이라면, Docker Compose 파일을 수정하여 NPM의 호스트 포트를 변경할 수 있습니다.
ports: - '8080:80' # 호스트의 8080 포트를 NPM의 80 포트에 연결 - '8443:443' # 호스트의 8443 포트를 NPM의 443 포트에 연결 - '81:81'
이렇게 변경하면 외부에서
http://your-domain.com:8080
또는https://your-domain.com:8443
으로 접속해야 합니다. 이는 추천하지 않는 방법이며, 가급적 80/443 포트를 NPM이 단독으로 사용하도록 하는 것이 좋습니다. 기존 웹 서버를 중단하거나 NPM이 기존 웹 서버 앞에 위치하도록 구성하는 방법을 고려해 보세요. - 보안 강화
- NPM 관리자 계정의 비밀번호를 강력하고 유추하기 어려운 것으로 설정하세요.
- NPM 및 기반 Docker 이미지를 최신 상태로 유지하여 보안 취약점을 패치하세요. (
docker compose pull
후docker compose up -d
)
- 내부 서비스는 HTTP로! NPM은 리버스 프록시로 동작하기 때문에, 내부 서비스(예: Node.js 앱, Apache 서버)는 굳이 HTTPS로 구성할 필요가 없습니다. NPM이 외부의 HTTPS 요청을 받아 내부 서비스로 HTTP로 전달하고, 내부 서비스의 응답을 다시 HTTPS로 외부로 전달하는 방식으로 동작합니다. 이는 관리 복잡도를 줄여줍니다.
✅ 결론
Nginx Proxy Manager는 웹 서비스 운영에 있어 번거로운 Nginx 설정과 SSL 인증서 관리를 획기적으로 단순화시켜주는 강력한 도구입니다. Docker Compose를 활용하면 단 몇 분 만에 완벽하게 동작하는 NPM 환경을 구축할 수 있으며, 직관적인 웹 UI를 통해 모든 서비스를 손쉽게 관리할 수 있습니다.
이제 여러분도 Nginx Proxy Manager와 함께 웹 서비스 관리에 들이는 시간을 절약하고, 더 중요한 작업에 집중할 수 있을 것입니다. 궁금한 점이 있다면 언제든지 댓글로 질문해주세요! 행복한 서버 운영 되세요! 💻✨