본문 바로가기
서버, 인프라

[Claude 블로그 자동화] nginx + certbot SSL 설정으로 도메인 연결하기 4편

by 요즘IT 2026. 5. 30.

http://서버IP:5000

이 주소로 접속하고 있으면, 솔직히 좀 찜찜하죠.

포트 번호 붙어있고, http에, IP 주소 그대로고.

브라우저에서 "안전하지 않은 사이트"라고 뜨는 순간 의욕이 떨어지거든요.

오늘은 이걸 정리해요.

nginx 리버스 프록시로 Flask 앱을 도메인에 연결하고, HTTPS까지 올리는 작업이에요.

이 작업전에 jenkins를 활용해 RSS 사이트의 자동 배포 파이프라인을 구축했었어요. 그부분은 아래 링크에서 확인 가능해요.

 

이전글 : [서버, 인프라] - Jenkins로 Docker 자동 배포 파이프라인 구축하기 3편


예전 글에서 이미 다뤘어요

nginx + certbot + SSL 인증서 발급 전체 과정은 이전에 정리한 글이 있어요.

Docker Compose 환경에서 Certbot을 컨테이너로 올리는 방법, Hetzner 방화벽 443 포트 오픈, 자동 갱신 crontab까지 다 들어있거든요.

도메인 연결하고 HTTPS까지 적용해봤습니다 — Hetzner 실전 세팅 7편

nginx나 certbot이 처음이거나, 설치부터 다시 보고 싶다면 위 글 먼저 보고 오는 걸 추천해요.

이번 글은 그 설정이 이미 돼있다는 전제에서, web-scrap-note 전용 nginx 설정만 추가하는 과정을 다뤄요.


이 프로젝트에서 달라지는 부분

이전 글은 Next.js 프론트 + Spring Boot 백엔드 구성이었어요.

이번엔 Python Flask 앱 하나만 연결하면 돼요.

구조는 훨씬 단순해요.

사용자 → nginx(443) → Flask 앱(5000 포트)

기존 nginx 설정 파일에 서브도메인 블록 하나만 추가하면 끝이에요.


nginx 설정 추가

기존 nginx/conf.d/default.conf에 아래 블록을 추가해요.

# HTTP → HTTPS 리다이렉트
server {
    listen 80;
    server_name 서브도메인.내도메인.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPS
server {
    listen 443 ssl;
    server_name 서브도메인.내도메인.com;

    ssl_certificate     /etc/letsencrypt/live/내도메인.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/내도메인.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://web-scrap-note:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

포인트는 proxy_pass http://web-scrap-note:5000 이 부분이에요.

도커 컨테이너끼리는 컨테이너 이름으로 통신이 돼요.

IP 주소 몰라도 되고, 컨테이너 이름이랑 포트만 맞으면 되거든요.


DNS A 레코드 추가

도메인 등록 업체 콘솔에서 서브도메인 A 레코드를 추가해요.

타입: A
호스트: 서브도메인 (예: scrap)
값: 서버 공인 IP
TTL: 3600

 

여기서 잠깐.

DNS 반영 시간이 "보통 5~10분"이라고 나와있는데, 실제로는 더 걸릴 수 있어요.

제 Hetzner 서버 기준으로는 15~20분 넘게 걸렸거든요.

어? 왜 안 되지? 싶어서 설정 다시 확인하고, nginx 재시작하고, 이것저것 건드려봤는데 사실 그냥 DNS가 안 퍼진 거였어요.

이건 기다리는 게 답이에요. 진짜로.

확인은 이걸로.

nslookup 서브도메인.내도메인.com
# 서버 IP가 나오면 정상

서버 IP가 나올 때까지 커피 한 잔 마시고 오면 돼요.


SSL 인증서에 서브도메인 추가 발급

기존 인증서가 있다면, 서브도메인을 추가해서 재발급해요.

docker compose run --rm certbot certonly --webroot \
  -w /var/www/certbot \
  -d 내도메인.com \
  -d 서브도메인.내도메인.com \
  --email 이메일주소 \
  --agree-tos \
  --no-eff-email

Successfully received certificate 나오면 완료예요.

이후 nginx 재시작하면 적용돼요.

docker compose restart nginx

HTTPS SSL certificate browser padlock
HTTPS SSL certificate browser padlock

브라우저에서 도메인 접속했을 때 자물쇠 아이콘 뜨면 성공이에요.


502 Bad Gateway 뜨면

nginx 설정 다 맞는데 접속이 안 되는 경우, 원인은 거의 세 가지예요.

컨테이너가 안 떠있거나 → docker ps로 상태 확인
컨테이너 이름이 다르거나 → docker ps에서 이름 확인 후 proxy_pass 수정
같은 도커 네트워크가 아니거나 → docker-compose.yml 네트워크 설정 확인

# nginx 에러 로그
docker logs nginx

# Flask 앱 로그
docker logs web-scrap-note

로그 보면 대부분 원인이 나와요.

nginx reverse proxy SSL architecture diagram
nginx reverse proxy SSL architecture diagram

 

여기까지 정리하면

기존 nginx + certbot 환경에 서브도메인 블록 하나 추가하는 것만으로 연결이 됐어요.

https://서브도메인.내도메인.com 으로 깔끔하게 접속되는 구조 완성이에요.

지금까지 만든 걸 쭉 이어보면,

1편 — 서버에 Docker + Claude Code 올리기
2편 — Flask + RSS 자동 수집 시스템
3편 — Jenkins CI/CD 파이프라인
4편 — nginx + SSL 도메인 연결 ← 여기

다음 편이 마지막이에요.

수집부터 Claude.ai 활용, 티스토리 발행까지 전체 흐름을 한번에 정리해요.

결국 핵심은 이거예요.

한 번 세팅해둔 인프라는 새 프로젝트마다 재활용된다.