Part I
서버 환경 파악
Traefik(192.168.0.230)은 systemd 서비스로 설치되어 있다. Docker 컨테이너가 아니라 바이너리가 직접 실행되는 구조다. 설정 파일을 이해하면 라우팅 추가는 어렵지 않다.
Traefik 설정 파일 구조
/etc/traefik/
├── traefik.yml
├── acme/
└── dynamic/
└── routes.yml
핵심은 두 파일의 차이다. traefik.yml은 정적 설정이다. 엔트리포인트, 인증서 리졸버, 프로바이더 같은 인프라 수준의 설정이 들어간다. 수정하면 재시작이 필요하다. dynamic/ 폴더 안의 파일은 동적 설정이다. 라우팅 규칙, 서비스 연결 정보가 들어간다. 저장하면 재시작 없이 즉시 반영된다.
traefik.yml (정적 설정)
엔트리포인트 — 80(HTTP), 443(HTTPS)
인증서 리졸버 — Let's Encrypt 연동
프로바이더 — 파일/Consul/Docker 감지
수정 시 재시작 필요
dynamic/*.yml (동적 설정)
라우터 — 도메인/경로 매칭 규칙
서비스 — 백엔드 서버 URL
미들웨어 — 인증, 헤더, Rate Limit
저장 시 즉시 반영 (재시작 불필요)
개발자가 건드리는 것은 dynamic/ 폴더뿐이다. traefik.yml은 인프라 관리자의 영역이다.
Part II
리버스 프록시 추가 — 5단계
작업은 두 곳에서 진행한다. DNS 설정(도메인 관리 업체)과 Traefik 서버(192.168.0.230). 순서를 지키면 5분이면 끝난다.
Step 01
DNS 서브도메인 추가
도메인 관리 업체(가비아, Cloudflare 등)에서 서브도메인의 A 레코드를 Traefik 서버 IP(192.168.0.230)로 연결한다. 백엔드 서버 IP가 아니다.
DNS A 레코드 설정
chris-app.yourdomain.com → A → 192.168.0.230
lucy-app.yourdomain.com → A → 192.168.0.230
*.yourdomain.com → A → 192.168.0.230
Step 02
Traefik 서버 접속
SSH로 Traefik 서버에 접속한다.
SSH
$ ssh traefik@192.168.0.230
Step 03
라우팅 파일 편집
/etc/traefik/dynamic/ 폴더 안의 .yml 파일은 모두 자동 감지된다. 기존 routes.yml에 추가하거나, 서비스별로 새 파일을 만들 수 있다.
파일 편집
$ sudo vim /etc/traefik/dynamic/routes.yml
$ sudo vim /etc/traefik/dynamic/chris-app.yml
Step 04
라우팅 규칙 작성
YAML 파일에 라우터(어떤 도메인으로 들어오면)와 서비스(어떤 서버로 보낼지)를 정의한다. 아래 템플릿에서 [서비스명], [서브도메인], [대상IP], [포트]를 변경한다.
라우팅 규칙 템플릿
http:
routers:
[서비스명]:
rule: "Host(`[서브도메인].yourdomain.com`)"
entryPoints:
- websecure
service: [서비스명]
tls:
certResolver: letsencrypt
services:
[서비스명]:
loadBalancer:
servers:
- url: "http://[대상IP]:[포트]"
Step 05
파일 저장
vim에서 :wq로 저장하면 Traefik이 파일 변경을 자동 감지하여 즉시 적용한다. 서비스 재시작이 필요 없다. SSL 인증서도 Let's Encrypt에서 자동 발급된다.
dynamic/ 폴더의 YAML을 저장하면
재시작 없이 즉시 반영된다.
Part III
실전 예시 3가지
01
개발자 서버 1대 연결
Chris의 개발 서비스를 서브도메인으로 노출
/etc/traefik/dynamic/chris-app.yml
http:
routers:
chris-app:
rule: "Host(`chris-app.yourdomain.com`)"
entryPoints:
- websecure
service: chris-app
tls:
certResolver: letsencrypt
services:
chris-app:
loadBalancer:
servers:
- url: "http://192.168.0.202:8080"
02
개발자 3명 한 파일에 등록
하나의 YAML 파일에서 여러 서비스를 관리
/etc/traefik/dynamic/dev-servers.yml
http:
routers:
chris-app:
rule: "Host(`chris.yourdomain.com`)"
entryPoints:
- websecure
service: chris-app
tls:
certResolver: letsencrypt
lucy-app:
rule: "Host(`lucy.yourdomain.com`)"
entryPoints:
- websecure
service: lucy-app
tls:
certResolver: letsencrypt
evan-app:
rule: "Host(`evan.yourdomain.com`)"
entryPoints:
- websecure
service: evan-app
tls:
certResolver: letsencrypt
services:
chris-app:
loadBalancer:
servers:
- url: "http://192.168.0.202:8080"
lucy-app:
loadBalancer:
servers:
- url: "http://192.168.0.203:8080"
evan-app:
loadBalancer:
servers:
- url: "http://192.168.0.204:8080"
03
경로(Path) 기반 라우팅
하나의 도메인에서 경로로 서비스를 분기
도메인 하나에 여러 서비스를 연결하려면 PathPrefix 조건을 추가한다. app.yourdomain.com/api는 API 서버로, app.yourdomain.com은 프론트엔드로 보내는 식이다.
경로 기반 라우팅
http:
routers:
api-service:
rule: "Host(`app.yourdomain.com`) && PathPrefix(`/api`)"
entryPoints:
- websecure
service: api-service
tls:
certResolver: letsencrypt
services:
api-service:
loadBalancer:
servers:
- url: "http://192.168.0.202:3000"
Part IV
트러블슈팅
설정을 저장했는데 서비스에 접근이 안 되는 경우. 대부분 아래 3가지 중 하나다.
502 Bad Gateway
Traefik이 요청을 받았지만, 백엔드 서버가 응답하지 않는다.
대상 서버에서 해당 포트가 열려있는지 확인한다. 서비스가 실행 중인지, 방화벽이 차단하고 있지 않은지 점검한다. sudo firewall-cmd --list-all로 방화벽 상태를 확인한다.
404 Not Found
Traefik이 해당 도메인에 대한 라우팅 규칙을 찾지 못했다.
Host 규칙의 도메인명에 오타가 없는지 확인한다. DNS가 Traefik(230)을 가리키는지도 확인한다. nslookup chris-app.yourdomain.com으로 DNS 해석 결과를 확인한다.
SSL 인증서 오류
Let's Encrypt 인증서 발급에 실패했다.
/etc/traefik/acme/ 폴더의 권한을 확인한다. Let's Encrypt는 Rate Limit이 있다. 같은 도메인에 반복 요청하면 차단될 수 있다. 1시간 대기 후 재시도한다.
디버깅 명령어
확인 및 디버깅
$ sudo journalctl -u traefik -f
http://192.168.0.230:8080/dashboard/
$ curl -H "Host: chris-app.yourdomain.com" http://192.168.0.230
$ sudo traefik --configFile=/etc/traefik/traefik.yml --log.level=DEBUG
주의사항
/etc/traefik/dynamic/ 폴더 안의 파일만 자동 감지된다 — 하위 폴더는 감지되지 않을 수 있으니 폴더 안에 직접 .yml 파일을 둔다
traefik.yml(메인 설정)을 수정하면 sudo systemctl restart traefik으로 재시작이 필요하다
dynamic/ 폴더의 파일은 저장 즉시 반영, 재시작 불필요
- 파일 편집 시 root 권한이 필요하다 —
sudo vim을 사용한다
- 개발자 개인 서버에 별도 Traefik을 설치하지 않는다 — 중앙 Traefik(230)에서 통합 관리한다
YAML 한 줄이
서비스를 연결한다
DNS를 잡고, YAML을 저장하면 끝이다. 인프라를 두려워할 필요 없다. 규칙만 지키면 5분이면 된다.