(Ubuntu + Docker CLI 기준)
0. 3줄 요약
- Ubuntu 서버에 Docker + Nginx Proxy Manager(NPM) 를 CLI로 설치합니다.
- Cloudflare에서 도메인 + DNS + API 토큰을 설정하고,
- NPM에서 DNS Challenge 방식으로 와일드카드 SSL 인증서(https) 까지 한 번에 완성합니다.
1. 준비물 체크
✅ 필수 준비 사항
- 공유기 포트포워딩 설정(80,443) (맨 하단에 설명 있습니다.)
- Ubuntu Server (미니PC, 데스크탑, NAS 등 어떤 장비든 상관없습니다)
- 설치 가능한 도메인 1개 (예:
mydomain.com) (참고로 저는 호스팅케이알에서 도메인을 구입했습니다.) - Cloudflare 계정
- 서버에 SSH 접속 가능해야 함
✅ Docker / docker compose 설치
아직 Docker가 없다면 아래 명령으로 설치합니다.
curl -fsSL https://get.docker.com | sh sudo apt-get install -y docker-compose-plugin docker -v docker compose version
curl -fsSL https://get.docker.com | shsudo apt-get install -y docker-compose-plugindocker -vdocker compose version
두 명령 모두 버전이 출력되면 준비 완료입니다.
2. Nginx Proxy Manager를 CLI로 설치하기 (docker compose)
2-1. 구성 폴더 만들기
mkdir -p /mnt/docker/npm cd /mnt/docker/npm nano docker-compose.yml
mkdir -p /mnt/docker/npmcd /mnt/docker/npmnano docker-compose.yml
2-2. docker-compose.yml 작성
version: "3.8"
services:
npm:
container_name: npm
image: jc21/nginx-proxy-manager:latest
restart: unless-stopped
ports:
- "80:80" # HTTP
- "81:81" # 관리자 페이지
- "443:443" # HTTPS
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
environment:
- TZ=Asia/Seoul
version: "3.8"services: npm: container_name: npm image: jc21/nginx-proxy-manager:latest restart: unless-stopped ports: - "80:80" # HTTP - "81:81" # 관리자 페이지 - "443:443" # HTTPS volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt environment: - TZ=Asia/Seoul
2-3. 컨테이너 실행
docker compose up -d
docker compose up -d
3. NPM 첫 접속 & 기본 설정
브라우저에서 반드시 아래처럼 접속합니다.
http://서버IP:81
http://서버IP:81

기본 로그인 정보
- 이메일:
admin@example.com - 비밀번호:
changeme
로그인 후 바로:
- 이메일 / 비밀번호 변경
- 우측 상단 → Settings → General 에서 Timezone을 Asia/Seoul로 변경
4. Cloudflare에서 도메인 & DNS 설정
4-1. 도메인 추가
- https://www.cloudflare.com 로그인
- Add a site 클릭 →
mydomain.com입력 - 플랜은 Free 선택
- 안내에 따라 진행하면 Cloudflare가 새로운 네임서버(NS) 두 개를 보여줍니다.

4-2. 도메인 구매처에서 네임서버 변경
- 호스팅케이알/가비아/닷네임 등 도메인 구매처에 로그인
- 네임서버를 Cloudflare가 알려준 두 주소로 변경

⏱ DNS 전파 시간 주의
네임서버 변경 후에는 최소 1시간 ~ 최대 24시간 까지 반영이 지연될 수 있습니다.
바로 접속이 안 되더라도 “망했다” 생각하지 마시고,
여유 있게 반나절~하루 정도 기다렸다가 다시 테스트해 보세요.
4-3. Cloudflare DNS A 레코드 추가
Cloudflare 대시보드 → 해당 도메인 선택 → DNS 메뉴에서:
- 루트 도메인(@) 또는 원하는 서브도메인(home 등)을 서버 공인 IP와 연결합니다.

☁️ Proxy가 주황색 구름(Proxied)
- 실제 IP가 숨겨지고
- SSL, CDN, 보안 기능을 쓸 수 있습니다.
5. Cloudflare SSL 모드 설정
Cloudflare → 해당 도메인 → SSL/TLS → Overview
- SSL/TLS encryption mode 를 Full 로 설정합니다.
▫ Flexible: 서버와 Cloudflare 사이가 HTTP라 권장하지 않습니다.
▫ Full: 서버에 자체 서명 인증서만 있어도 암호화가 유지됩니다.
▫ Full (Strict): 설정이 조금만 틀어져도 접속이 막힐 수 있어 초보자에게는 비추천입니다.
6. Cloudflare API 토큰 발급 (DNS Challenge용)
- Cloudflare 우측 상단 아이콘 → My Profile
- 왼쪽 메뉴에서 API Tokens
- Create Token → “Edit zone DNS” 템플릿 선택
- Zone Resources에서 내 도메인 선택
- 토큰 생성 후 나오는 API Token 문자열을 복사해 둡니다.

이 토큰은 NPM이 Cloudflare DNS에
“이 도메인의 TXT 레코드를 잠깐 만들었다 지우는 작업”을 대신할 수 있게 해 주는 열쇠입니다.
7. NPM에서 DNS Challenge로 와일드카드 SSL 인증서 발급
이제 NPM에서 바로 Let’s Encrypt 인증서를 받아 보겠습니다.

- NPM 화면 상단 메뉴 → SSL Certificates
- Add SSL Certificate → Request a New Certificate 클릭
- 아래처럼 입력합니다.

- Domain Names:
*.mydomain.com- (와일드카드 사용 시 모든 서브도메인에 한 번에 사용 가능)
- Email Address: 본인 이메일
- Use a DNS Challenge 체크
- DNS Provider: Cloudflare
- API Token: 아까 복사한 토큰 입력
- Agree to Terms of Service 체크
- Save / 발급 요청
정상적으로 발급되면 리스트에 초록색 상태로 표시됩니다.
8. Proxy Host 생성 + SSL 붙이기 (서비스 1개 예시)
이제 내부 서비스 하나를 도메인으로 노출해 보겠습니다.
예시로 다음과 같이 가정하겠습니다.
- 내부에서
http://192.168.0.11:9000으로 접속되는 웹 서비스(Portainer/Immich 등)
8-1. Proxy Host 만들기
NPM 상단 메뉴 → Hosts → Proxy Hosts → Add Proxy Host
Details 탭
- Domain Names:
portainer.mydomain.com - Scheme:
http - Forward Hostname / IP:
10.10.252.250 (내 서버 사설IP) - Forward Port:
9000 - Cache Assets: OFF (필요에 따라)
- Block Common Exploits: ON 추천

SSL 탭
- SSL Certificate: 아까 만든
*.mydomain.com선택 - Force SSL: ON (http로 접속해도 https로 자동 전환)
- HTTP/2 Support: ON 추천
저장하면 설정은 끝입니다.
이제 브라우저에서:
https://portainer.mydomain.com
https://service.mydomain.com
으로 접속해 보시면,
내부 서비스가 SSL이 적용된 도메인으로 열리는 것을 확인하실 수 있습니다.
(네임서버 변경 직후라면 DNS 전파 때문에 조금 더 기다리셔야 할 수 있습니다.)
9. 간단 오류 체크리스트
service.mydomain.com이 아예 열리지 않을 때- Cloudflare DNS A 레코드에 공인 IP가 맞게 들어갔는지 확인
- 네임서버 변경 후 1~24시간 정도 지났는지 확인
ERR_SSL_HANDSHAKE/ 525 / 526 오류- Cloudflare SSL 모드를 Full 로 설정했는지 확인
- NPM에서 인증서 발급 실패
- API Token 권한이 “Edit zone DNS” 인지 확인
- DNS Challenge 사용 여부, 도메인 오타 확인
- 공유기 포트포워딩 확인
- 외부 포트: TCP
80,443
- 외부 포트: TCP
나의 경우 공유기는 딜라이브에서 제공해준 공유기를 사용한다.
(원래 기존에는 딜라이브 공유기를 브릿지모드로 하고 하단에 iptime을 사용하였다가 nego가 안맞아서 순정공유기를 사용중이다. 아마도 통신사 장비인 OLT나 CMTS 같은 장비와 가정 내 공유기 간 통신사에서 가입자서비스 프로파일을 할당하여 관리하기 때문에 그런듯하다. 하지만 딜라이브만 그렇다는것이지 이전에 SKB 사용시에는 문제 없었다.)
참고로 딜라이브 공유기에서 아래와 같이 포트포워딩을 설정하였다.
딜라이브 공유기 접속방법
– web접속 : 192.168.200.254:10010
-계정 : admin / admin(신호이름뒷 4자리)



답글 남기기