로컬 서버를 인터넷에 노출하는 방법 (포트 포워딩 없이)
Source: Dev.to
TL;DR: Cloudflare Tunnel을 사용하면 라우터 설정 없이도 집에 있는 서버를 어디서든 접근할 수 있습니다. 무료이며 보안도 뛰어나고, 포트 포워딩이 필요 없습니다.
최근에 노트북에서 실행 중인 웹 앱을 실제 도메인에 배포했습니다—클라우드 호스팅도, VPS도, 월 요금도 없습니다. 노트북 하나와 도메인, 그리고 Cloudflare Tunnel만 있으면 됩니다. 바로 제가 한 방법을 소개합니다.
왜 터널을 사용하나요?
- 라우터 관리 패널에 접근할 수 없음
- 동적 IP 주소
- 포트 포워딩이 옵션이 아님
- 포트 80/443을 직접 열면 작동하지 않음
Cloudflare Tunnel (구 Argo Tunnel)은 서버에서 Cloudflare의 엣지로 아웃바운드 연결을 생성하므로 들어오는 포트가 필요하지 않습니다.
Internet → Cloudflare (SSL) → Tunnel → Your laptop
- 무료이며 SSL을 자동으로 처리
- 모든 도메인 레지스트라와 호환
- Linux, macOS, Windows에서 작동
Prerequisites
| Item | Details |
|---|---|
| Domain name | Any registrar (e.g., Porkbun) |
| Cloudflare account | Free tier is sufficient |
| Machine running app | Linux/macOS/Windows |
| Time | ~10 minutes |
사전 요구 사항
| 항목 | 세부 정보 |
|---|---|
| 도메인 이름 | 모든 레지스트라(예: Porkbun) |
| Cloudflare 계정 | 무료 플랜이면 충분합니다 |
| 앱이 실행되는 머신 | Linux/macOS/Windows |
| 시간 | 약 10분 |
1. 도메인을 Cloudflare에 연결하기
- dash.cloudflare.com 로 이동 → Add a site(사이트 추가)를 클릭합니다.
- 도메인을 입력합니다(예:
myapp.com). - Free 플랜을 선택합니다.
- Cloudflare가 두 개의 네임서버를 표시합니다(예:
carter.ns.cloudflare.com,vita.ns.cloudflare.com). - 도메인 등록기관의 제어판에서 기존 네임서버를 Cloudflare가 제공한 네임서버로 교체합니다.
- DNS 전파가 완료될 때까지 5~30분 정도 기다립니다.
2. Cloudflare Zero Trust에서 터널 만들기
- Cloudflare 대시보드에서 Zero Trust(왼쪽 사이드바)를 엽니다.
- Networks → Tunnels 로 이동합니다.
- Create a tunnel을 클릭하고 이름을 지정합니다(예:
my-server). - Cloudflare는 일회용 토큰이 포함된 설치 명령을 표시합니다.
3. cloudflared 데몬 설치
Ubuntu / Debian
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
macOS
brew install cloudflared
Windows
**GitHub releases 페이지**에서 최신 릴리스를 다운로드하고 수동으로 설치합니다.
4. 터널을 서비스로 등록하기
2단계에서 받은 명령어를 토큰으로 교체하여 실행합니다:
sudo cloudflared service install <TOKEN>
이 명령은 부팅 시 자동으로 시작되는 시스템 서비스를 생성합니다.
실행 중인지 확인합니다:
sudo systemctl status cloudflared
5. 공개 호스트 이름 추가
- Cloudflare 대시보드에서 Tunnels →
→ Configure 로 이동합니다. - Public Hostname → Add a public hostname 을 클릭합니다.
- 아래 필드를 입력합니다:
| Field | Value |
|---|---|
| Subdomain | (비워 두거나 www 사용) |
| Domain | 도메인 (myapp.com) 선택 |
| Service Type | HTTP |
| URL | localhost:80 (또는 앱이 사용하는 포트) |
- 저장합니다.
“DNS record already exists”라는 메시지가 보이면, 먼저 DNS → Records에서 충돌하는 A 레코드를 삭제하세요.
이제 브라우저에서 https://myapp.com을 열면, 로컬 앱이 HTTPS로 제공되는 것을 볼 수 있습니다.
명령줄에서 테스트
curl https://myapp.com
6. 여러 서비스 라우팅
공개 호스트명을 추가하여 여러 로컬 서비스를 노출할 수 있습니다:
| 공개 호스트명 | 로컬 서비스 |
|---|---|
myapp.com | localhost:3000 (frontend) |
api.myapp.com | localhost:8080 (API) |
각 항목에 대해 “Add a public hostname” 단계를 반복하면 됩니다.
7. Nginx 기반 설정 예시
textstack.app → localhost:80 → nginx → React frontend
textstack.app/api → localhost:80 → nginx → Docker API (port 8080)
textstack.dev → localhost:80 → nginx → Same app, different site
모든 것이 거실에 있는 노트북에서 실행됩니다.
8. 로컬 방화벽 (선택 사항이지만 권장)
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # Tunnel (local only)
sudo ufw enable
- 관리자 패널을 인터넷에 노출하지 마세요;
localhost에만 바인딩하십시오.
9. 보안 및 접근 제어
- Cloudflare는 SSL을 자동으로 제공하므로 Let’s Encrypt가 필요 없습니다.
- Access Policies(Zero Trust)를 사용하여 민감한 경로에 인증을 요구합니다.
10. 문제 해결
| 증상 | 확인 사항 |
|---|---|
| 사이트가 로드되지 않음 | sudo systemctl status cloudflared |
| 앱이 응답하지 않음 | curl localhost:80 |
| DNS가 해결되지 않음 | dig myapp.com |
| 모바일에서 “주소를 찾을 수 없음” | 비행기 모드를 토글하고 DNS를 1.1.1.1로 전환한 뒤 15–30 분 기다리기 |
| 502 Bad Gateway | 터널이 실행 중인지와 로컬 서비스가 수신 대기 중인지 확인 |
11. Cloudflare Tunnel을 사용하면 안 되는 경우
- 고트래픽 프로덕션 앱(가정용 인터넷 대역폭 제한)
- 99.99 % 가동 시간을 요구하는 앱(노트북이 다운될 수 있음)
- 적절한 보안 강화 없이 민감한 데이터
심각한 프로덕션 워크로드의 경우, 적절한 클라우드 제공자를 고려하세요.
12. 이상적인 사용 사례
- 사이드 프로젝트
- 개발 / 스테이징 환경
- 자체 호스팅 앱(예: 홈 자동화 대시보드)
- 개인 API
13. 마무리
제가 15 분 정도면 “앱이 로컬에서 실행 중” 상태에서 “HTTPS로 전 세계에서 접근 가능한 앱” 상태로 전환할 수 있었습니다. 클라우드 비용도 없고, DevOps 복잡성도 없습니다—그냥 여러분의 하드웨어 위에 있는 코드가 어디서든 접근 가능할 뿐입니다.
질문이 있나요? 아래에 댓글을 남기시거나 Twitter/X에서 찾아 주세요.
이 설정으로 멋진 무언가를 만들고 있나요? 여러분의 이야기를 듣고 싶습니다!