๐ SWAG : ๋น์ ์ homelab์ ํ์ ํ Reverse Proxy Docker!
Source: Dev.to
SWAG๋ ์ ํํ ๋ฌด์์ธ๊ฐ์?
SWAG๋ nginx ๊ธฐ๋ฐ์ ์ฌ์ธ์ ๋ฆฌ๋ฒ์ค ํ๋ก์๋ก, Letโs Encrypt SSL ์ธ์ฆ์๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํด ์ค๋๋ค. ์ฝ๊ฒ ๋งํด, ์ฌ๋ฌ๋ถ์ ๋์งํธ ๋ฌธ์ง๊ธฐ๋ก์:
- ๐ SSL ์ธ์ฆ์๋ก ์๋น์ค๋ฅผ ์๋ ๋ณดํธ
- ๐ ์๋น์ค๋ฅผ ๊ณ ์ ํ ์๋ธ๋๋ฉ์ธ์ ๋ ธ์ถ
- ๐ก๏ธ ์ค์ ์ธ์ฆ์ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ๋ณดํธ
- ๐ ๊ฐ๋จํ ์ค์ ๋ง์ผ๋ก ๋ชจ๋ ๊ฒ์ ๊ด๋ฆฌ
์ SWAG๋ฅผ ์ ํํด์ผ ํ ๊น์?
SWAG๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์๋ ์ผ๋ฐ nginx์ certbot์ ์ง์ ๋ค๋ค๋๋ฐโฆ ์ ๋ง ๊ณจ์น ์ํ ์ต๋๋ค! ์ธ์ฆ์ ๊ฐฑ์ ์คํจ, ์๋ nginx ์ค์ , ๋๋ฉ์ธ ๊ด๋ฆฌ ๋ฑ ์ฌ๋ฌ ๋ฌธ์ ๋ฅผ ํ ๋ฒ์ ํด๊ฒฐํด ์ฃผ๋ ๊ฒ์ด SWAG์์ต๋๋ค:
- ์๋ ์์ผ๋์นด๋ ์ธ์ฆ์
- ์ธ๊ธฐ ์๋น์ค์ฉ ์ฌ์ ์ค์ ํ์ผ ์ ๊ณต
- Docker์์ ๋ค์ดํฐ๋ธ ํตํฉ
- ์ธ์ฆ ์ง์ (Authelia, OAuth ๋ฑ)
๋ชฉํ ์ํคํ ์ฒ
์ ๊ณต์ ์ฒด ์ค์ ์์ (Free)
- Freebox ๊ด๋ฆฌ ํ์ด์ง์ ๋ก๊ทธ์ธ
- Freebox ์ค์ โ ํฌํธ ๊ด๋ฆฌ
- ํฌํธ ํฌ์๋ฉ ์ค์ :
| ์ธ๋ถ ํฌํธ | ๋ด๋ถ ํฌํธ | ๋์ IP | ํ๋กํ ์ฝ |
|---|---|---|---|
| 443 (HTTPS) | 443 | 192.168.1.100 (์์) | TCP |
| 80 (HTTP) | 80 | 192.168.1.100 | TCP |
๐ก ๋ณด์ ํ: 80/443 ํฌํธ๋ฅผ ๋ฐ๋ก ์ด๊ธฐ๋ณด๋ค ์ปค์คํ ํฌํธ(์: 8443)๋ฅผ ์ฌ์ฉํ๊ณ ํฌ์๋ฉํ๋ฉด ๋ ์์ ํฉ๋๋ค.
DuckDNS ์ค์
- DuckDNS์ ํ์๊ฐ์
- ๋๋ฉ์ธ ์์ฑ:
monhomelab.duckdns.org - ํ ํฐ์ ๊ธฐ๋ก (Docker์์ ์ฌ์ฉ)
๋์ฒด DNS ์ ๊ณต์ ์ฒด
| ๋ฌด๋ฃ | ์ ๋ฃ |
|---|---|
| DuckDNS | Cloudflare |
| FreeDNS | OVH |
| NoโIP | Gandi |
| Route53 | |
| DigitalOcean | |
| Namecheap |
Cloudflare ์ค์ ์์:
environment:
- URL=mondomaine.com
- VALIDATION=dns
- DNSPLUGIN=cloudflare
- EMAIL=votre-email@example.com
- CLOUDFLARETOKEN=votre-api-token-cloudflare
๊ณต์ธ IP ํ์ธ
# ๊ณต์ธ IP ํ์ธ
curl ifconfig.me
# DuckDNS๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๊ฐ๋ฆฌํค๋์ง ํ์ธ
nslookup monhomelab.duckdns.org
IP๊ฐ ์ผ์นํ๋ฉด OK! ๐ฏ
์ฐ๊ฒฐ ํ ์คํธ
# ๋ก์ปฌ ์๋ฒ ๊ฐ๋จํ ์คํ
python3 -m http.server 8080
# ์ธ๋ถ์์ ๋๋ฉ์ธ์ผ๋ก ํ
์คํธ
curl http://monhomelab.duckdns.org:8080
์ ์ ๋์ํ๋ฉด SWAG๋ฅผ ์ค์นํ ์ค๋น๊ฐ ๋ ๊ฒ์ ๋๋ค!
Docker Compose๋ก ์ค์น
ํ๊ฒฝ ๋ณ์ ์ค๋น
version: "3.8"
networks:
web-proxy:
external: false
services:
swag:
image: lscr.io/linuxserver/swag:latest
container_name: swag
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Paris
- URL=monhomelab.duckdns.org # DuckDNS ๋๋ฉ์ธ
- VALIDATION=duckdns # DuckDNS ์ธ์ฆ
- DUCKDNSTOKEN=12345678-1234-1234-1234-123456789012 # DuckDNS ํ ํฐ
- SUBDOMAINS=wildcard # *.monhomelab.duckdns.org ํ์ฉ
- EMAIL=votre-email@example.com
- ONLY_SUBDOMAINS=false # ๋ฉ์ธ ๋๋ฉ์ธ๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก
volumes:
- ./swag/data:/config
ports:
- "80:80" # HTTP (HTTPS๋ก ๋ฆฌ๋ค์ด๋ ํธ)
- "443:443" # HTTPS (๋ณด์ ์๋น์ค)
networks:
- web-proxy
restart: unless-stopped
์ฃผ์ ๋ณ์
URLโฏ: ์ ์ฒด ๋๋ฉ์ธ (DuckDNS, Cloudflare ๋ฑ)VALIDATIONโฏ: DNS ์ ๊ณต์ ์ฒด์ ๋ง๋ ์ธ์ฆ ๋ฐฉ์SUBDOMAINS=wildcardโฏ: ๋ชจ๋ ์๋ธ๋๋ฉ์ธ์ ๋ํ ์ธ์ฆ์ ์์ฑDUCKDNSTOKENโฏ: DNS ์ ๊ณต์ ์ฒด ํ ํฐ / API ํคONLY_SUBDOMAINS=falseโฏ: ๋ฉ์ธ ๋๋ฉ์ธ๋ ๋์์ ์ฌ์ฉ ๊ฐ๋ฅ
SWAG ์์
docker-compose up -d swag
docker logs swag # โServer readyโ์ โCertificate renewal successfulโ ๋ฉ์์ง๊ฐ ๋ณด์ผ ๊ฒ๋๋ค
์์ฑ๋ ํด๋ ๊ตฌ์กฐ
swag/data/
โโโ nginx/
โ โโโ nginx.conf
โ โโโ site-confs/
โ โโโ proxy-confs/ # โ ์๋น์ค๋ณ ํ๋ก์ ์ค์
โโโ keys/
โ โโโ letsencrypt/ # โ SSL ์ธ์ฆ์
โโโ log/
์ฒซ ๋ฒ์งธ ์๋น์ค ์ถ๊ฐ
์๋น์คโฏ1โฏ: Home Assistant
๊ฐ์ dockerโcompose.yml์ ์๋ ๋ด์ฉ์ ์ถ๊ฐ:
homeassistant:
image: homeassistant/home-assistant:stable
container_name: homeassistant
environment:
- TZ=Europe/Paris
volumes:
- ./homeassistant/data:/config
networks:
- web-proxy
ports:
- "8123:8123" # ๋ก์ปฌ ์ง์ ์ ๊ทผ์ฉ (์ ํ)
restart: unless-stopped
SWAG ํ๋ก์ ์ค์
swag/data/nginx/proxy-confs/homeassistant.subdomain.conf ํ์ผ์ ๋ง๋ค๊ณ :
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name homeassistant.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app homeassistant;
set $upstream_port 8123;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
# WebSocket ์ง์ (Home Assistant ํ์!)
location /api/websocket {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app homeassistant;
set $upstream_port 8123;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
์ค์ ํ ์คํธ
# ์ปจํ
์ด๋๊ฐ ์คํ ์ค์ธ์ง ํ์ธ
docker ps | grep homeassistant
# ์ธ๋ถ์์ ์ ๊ทผ ํ
์คํธ
curl -k https://homeassistant.monhomelab.duckdns.org
Home Assistant ๋ก๊ทธ์ธ ํ๋ฉด์ด ๋ณด์ด๋ฉด ์ฑ๊ณต!
๋คํธ์ํฌ ํธ๋ฌ๋ธ์ํ
์ ์ฉ Docker ๋คํธ์ํฌ
SWAG, Home Assistant ๋ฑ ๋ชจ๋ ์๋น์ค๊ฐ ๋์ผํ Docker ๋คํธ์ํฌ(web-proxy)์ ์ฐ๊ฒฐ๋ผ ์๋์ง ํ์ธํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด ํฌํธ ๊ณต๊ฐ ์์ด ์ปจํ
์ด๋ ์ด๋ฆ(homeassistant, swag ๋ฑ)๋ง์ผ๋ก ์๋ก ํต์ ํ ์ ์์ต๋๋ค.
๋ก๊ทธ ๊ด๋ฆฌ
docker logs swag # ๋ฆฌ๋ฒ์ค ํ๋ก์ ๋ก๊ทธ
docker logs homeassistant
SWAG ๋ก๊ทธ๋ swag/data/log/์๋ ์ ์ฅ๋ฉ๋๋ค.
์ค์ ๊ฒ์ฆ
- ์ธ์ฆ์๊ฐ ์์ฑ๋๋์ง ํ์ธ:
ls swag/data/keys/letsencrypt/live/monhomelab.duckdns.org/ - HTTP โ HTTPS ๋ฆฌ๋ค์ด๋ ํธ ํ
์คํธ:
curl -I http://monhomelab.duckdns.org
์์ผ๋์นด๋ ์ธ์ฆ์
SWAG๋ ์๋์ผ๋ก *.monhomelab.duckdns.org ์์ผ๋์นด๋ ์ธ์ฆ์๋ฅผ ๋ฐ๊ธํฉ๋๋ค. ์๋ธ๋๋ฉ์ธ๋ง๋ค ๋ณ๋ ์ธ์ฆ์๋ฅผ ๋ง๋ค ํ์๊ฐ ์์ต๋๋ค.
Authelia๋ก ๋ณด์ ๊ฐํ (๋ณด๋์ค)
Authelia๋ฅผ ์ธ์ฆ ๋ฏธ๋ค์จ์ด๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค:
authelia:
image: authelia/authelia
container_name: authelia
environment:
- TZ=Europe/Paris
volumes:
- ./authelia/config:/config
networks:
- web-proxy
restart: unless-stopped
๊ทธ ํ ์๋น์ค ํ๋ก์ ํ์ผ์ ๋ค์์ ์ฝ์ :
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
auth_request /authelia;
auth_request_set $user $upstream_http_remote_user;
proxy_set_header Remote-User $user;
# โฆ
}
์ ์ฒด ์ค์ ๋ฐฉ๋ฒ์ Authelia ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์ต์ข ๊ฒฐ๊ณผ
- ๋จ์ผ ์ง์
์ (
https://monhomelab.duckdns.org)์ด ๋ชจ๋ ์๋น์ค๋ก ๋ผ์ฐํ - ์๋ ๊ฐฑ์ ๋๋ SSL ์ธ์ฆ์
- ์ค์ํ๋ ๋ก๊ทธ์ Docker ๋คํธ์ํฌ ๊ด๋ฆฌ
ํํ ๋ฐ์ํ๋ ๋ฌธ์ ์ ํด๊ฒฐ๋ฒ
| ๋ฌธ์ | ํ์ธ ๋ฐฉ๋ฒ | ํด๊ฒฐ์ฑ |
|---|---|---|
| ์ธ์ฆ์๊ฐ ์์ฑ๋์ง ์์ | docker logs swag | DuckDNS ํ ํฐ๊ณผ ์ธํฐ๋ท ์ฐ๊ฒฐ ์ํ ํ์ธ |
| 443 ํฌํธ ์ฐจ๋จ | nc -zv votre-ip 443 | ๋ผ์ฐํฐ/๋ชจ๋์์ ํฌํธ ํฌ์๋ฉ ์ค์ ํ์ธ |
| ์๋น์ค ์ ๊ทผ ๋ถ๊ฐ | curl -I https://homeassistant.monhomelab.duckdns.org | ์ปจํ ์ด๋๊ฐ ๋์ผํ Docker ๋คํธ์ํฌ์ ์๋์ง ํ์ธ |
| DNS๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ง์ ๋์ง ์์ | nslookup monhomelab.duckdns.org | DuckDNS ํน์ ์ฌ์ฉ ์ค์ธ DNS ์ ๊ณต์ ์ฒด์์ IP ์ ๋ฐ์ดํธ |
๊ฒฐ๋ก
SWAG๋ homelab์ SSL์ด ์ ์ฉ๋ ๋ฆฌ๋ฒ์ค ํ๋ก์๋ฅผ ์์ฝ๊ฒ ๊ตฌ์ถํ๋๋ก ๋์์ค๋๋ค. Docker, DuckDNS(๋๋ ๋ค๋ฅธ DNS ์ ๊ณต์ ์ฒด)์ ์ฌ์ ์ค์ ๋ ๊ตฌ์ฑ ํ์ผ์ ๊ฒฐํฉํ๋ฉด ์๊ฐยท๋ณด์ยท์ ์ฐ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
๋ค์ ๋จ๊ณ
- SWAG ๊ณต์ ๋ฌธ์
- ์ง์ DNS ์ ๊ณต์ ์ฒด ์ ์ฒด ๊ฐ์ด๋
- Authelia ํํ ๋ฆฌ์ผ
- ์ ์ฒด ์คํ ์์ (Traefik, Portainer ๋ฑ)