์ž๋™ SSL ๋ฐ Let's Encrypt & Nginx

11524 ๋‹จ์–ด securityarchitecturetutorialdocker
๋ณ€๊ฒฝ ๋กœ๊ทธ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ธฐ์‚ฌ ํ•˜๋‹จ์˜ ์—…๋ฐ์ดํŠธ ์š”์•ฝ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.
์ฃผ: 2020๋…„ 12์›”์— letsencrypt-nginx-proxy-companion ํ”„๋กœ์ ํŠธ์˜ v2๊ฐ€ ๋ฐœํ‘œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.์ด ์ ์„ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ด ๊ธ€์„ ์—…๋ฐ์ดํŠธํ–ˆ์ง€๋งŒ, ํŽ˜์ด์ง€ ๋ฐ‘์— ์˜ค๋ž˜๋œ v1 ์ฝ”๋“œ๋ฅผ ๋ณด์กดํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.๊ธฐ์กด ์‹œ์Šคํ…œ์„ ํ˜„์žฌ ์œ„์น˜์—์„œ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ nginx-proxy/docker-letsencrypt-nginx-proxy-companion ์ €์žฅ์†Œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.
2016๋…„ ์ดํ›„ ์ธ์ฆ์„œ ๋ฐœ๊ธ‰๊ธฐ๊ด€์ธ ๋ ›'s Encrypt๋Š” ์•”ํ˜ธํ™” ํ†ต์‹ ์ด ๋„คํŠธ์›Œํฌ์— ์—†๋Š” ๊ณณ์ด ์—†๋„๋ก ๋ฌด๋ฃŒ SSL/TLS ์ธ์ฆ์„œ๋ฅผ ์ œ๊ณตํ–ˆ๋‹ค.๋งŒ์•ฝ ๋‹น์‹ ์ด ์ฆ์„œ๋ฅผ ๊ตฌ๋งคํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด, ์ฆ์„œ๋Š” ๋ณดํ†ต ๋งค์šฐ ๋น„์‹ธ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ์ฆ์„œ๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๊ณผ์ •์€ ์—‰๋ฉ์ด ๊ทผ์œก์˜ ๊ณ ํ†ต์ด๊ณ , ๊ทธ ์ฆ์„œ๋Š” ํœด๊ฐ€๋ฅผ ๋ณด๋‚ผ ๋•Œ ๊ธฐํ•œ์ด ์ง€๋‚˜ ์ •์ง€๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.
Let's Encrypt๊ฐ€ ์žˆ์œผ๋ฉด ๋ชจ๋“  ๋ฌธ์ œ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž๋™ํ™” ์ธ์ฆ์„œ ๊ด€๋ฆฌ ํ™˜๊ฒฝ(ACME) ํ”„๋กœํ† ์ฝœ ๋•๋ถ„์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœํ† ์ฝœ์€ ์ธ์ฆ์„œ์˜ ๊ฒ€์ฆ๊ณผ ๋ฐฐ์น˜๋ฅผ ์ž๋™ํ™”ํ•˜์—ฌ ์ž๊ธˆ๊ณผ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ACME ์ž์ฒด๊ฐ€ ํฅ๋ฏธ๋กœ์šด ํ™”์ œ์ž…๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ๊ฒ€์ฆ ๋ฐฉ๋ฒ• (๋„์ „์ด๋ผ๊ณ  ํ•จ) here์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋” ๋งŽ์ด ์ฝ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์˜ค๋Š˜์€ ์ž๋™ ์ธ์ฆ์„œ ์ƒ์„ฑ, ๊ฒ€์ฆ, ๋ฐฐ์น˜๋ฅผ ํ†ตํ•ด ์—ญ๋ฐฉํ–ฅ ์—์ด์ „ํŠธ๋ฅผ ์‰ฝ๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•  ์ฒซ ๋ฒˆ์งธ ์ผ์€ user defined bridge network์ด๋ผ๋Š” service-network์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.๋‚˜๋Š” ์‚ฌ๋ฌผ์— ์ด๋ฆ„์„ ๋ถ™์ด๋Š” ๊ฒƒ์„ ์ž˜ํ•˜์ง€ ๋ชปํ•˜์ง€๋งŒ, ์ด๊ฒƒ์€ ์ ์šฉ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.
docker network create --subnet 10.10.0.0/24 service-network

๋‹ค์Œ์— ์šฐ๋ฆฌ๋Š” ์—ญ๋ฐฉํ–ฅ ์—์ด์ „ํŠธ๋ฅผ ์„ค์ •ํ•  ๊ฒƒ์ด๋‹ค.์—ญ๋ฐฉํ–ฅ ์—์ด์ „ํŠธ๋Š” ์š”์ฒญ๋งŒ ๋ฐ›์•„๋“ค์ด๊ณ  ๋ฃจํŠธ ๊ทœ์น™ (์˜ˆ๋ฅผ ๋“ค์–ด ์–ด๋–ค ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ด ์–ด๋–ค ์„œ๋น„์Šค ์šฉ๊ธฐ๋กœ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š”์ง€) ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์„œ๋น„์Šค๋กœ ์—์ด์ „ํŠธํ•ฉ๋‹ˆ๋‹ค.๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์•ฝ๊ฐ„ ์ด๋ ‡๊ฒŒ ๋ณด์ธ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

Jason Wilder ์ด๋ฏธ์ง€ jwilder/nginx-proxy์„ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.์ด๊ฒƒ์€ ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ์ข‹์€ ํ”„๋กœ์ ํŠธ๋กœ ๋งŽ์€ ๋ฌธ์„œ๊ฐ€ ์žˆ๋‹ค.ํฌํŠธ 80๊ณผ 443์„ ์ปจํ…Œ์ด๋„ˆ์— ๋งคํ•‘ํ•˜์—ฌ HTTP ๋ฐ HTTPS ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.์šฐ๋ฆฌ๋„ ๋งŽ์€ ๋ณผ๋ฅจ์ด ์žˆ๋Š”๋ฐ, ์„ธ ๊ฐœ๋Š” ํ‘œ์ค€ docker ๋ณผ๋ฅจ์ด๊ณ , ํ•˜๋‚˜๋Š” docker daemon UNIX socket์ด๋‹ค.
์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ธด ํ˜•์‹ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋น„๋ก ์šฐ๋ฆฌ๋Š” ์‰ฝ๊ฒŒ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•˜๊ณ  ๊ทธ๊ฒƒ์„ ํ•œ ์ค„์— ๋†“์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๊ฒƒ์€ ์žฅ๋ž˜์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•  ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋„์›€์ด ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.
docker run \
  --detach \
  --restart always \
  --publish 80:80 \
  --publish 443:443 \
  --name nginx-proxy \
  --network service-network \
  --volume /var/run/docker.sock:/tmp/docker.sock:ro \
  --volume nginx-certs:/etc/nginx/certs \
  --volume nginx-vhost:/etc/nginx/vhost.d \
  --volume nginx-html:/usr/share/nginx/html \
  jwilder/nginx-proxy

์ด์ œ ๋ฆฌ๋ฒ„์Šค ์—์ด์ „ํŠธ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ Let's Encrypt companion์„ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Yves Blusseau์˜ ์ด๋ฏธ์ง€ jrcs/letsencrypt-nginx-proxy-companion์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๊ฑฐ์˜ 1๋…„ ๋™์•ˆ ์™„๋ฒฝํ•˜๊ฒŒ ์‚ฌ์šฉํ–ˆ๋‹ค.
์šฐ๋ฆฌ๋Š” ๊ฐ™์€ ๋ณผ๋ฅจ์„ ์ด ์šฉ๊ธฐ์— ๋น„์ถ”์ง€๋งŒ, ์–ด๋–ค ํฌํŠธ๋„ ๋ฐœํ‘œํ•˜์ง€ ์•Š์•˜๋‹ค.์šฐ๋ฆฌ๋Š” NGINX_PROXY_CONTAINER ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ”„๋ก์‹œ ์šฉ๊ธฐ์˜ ์ด๋ฆ„๊ณผ ์ผ์น˜ํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ง€ ์ด๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค.์ƒˆ ์„œ๋น„์Šค ์šฉ๊ธฐ๊ฐ€ ๊ฒ€์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ด ์šฉ๊ธฐ๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•˜๋ฉฐ ์ตœ์‹ ์œผ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
docker run \
  --detach \
  --restart always \
  --name nginx-proxy-letsencrypt \
  --network service-network \
  --volumes-from nginx-proxy \
  --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  --volume /etc/acme.sh \
  --env "DEFAULT_EMAIL=mail@yourdomain.tld" \
  jrcs/letsencrypt-nginx-proxy-companion

๋งˆ์ง€๋ง‰์œผ๋กœ ์„œ๋น„์Šค ์šฉ๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๊ฐ€ ๋˜์—ˆ๋‹ค.์šฐ๋ฆฌ๋Š” tutum/hello-world ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ์œ ํ–‰ํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ด๋ฏธ์ง€์ด๋‹ค.์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” DNS์˜ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.์šฐ๋ฆฌ๋Š” hello-world.example.com์„ ์‚ฌ์šฉํ•˜๋Š” ์ฒ™ํ•˜๊ณ  ์ด ์„œ๋ฒ„์˜ IP ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” A ๊ธฐ๋ก์„ ์„ค์ •ํ•œ ์ฒ™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
docker run \
  --detach \
  --restart always \
  --name hello-world \
  --network service-network \
  --env VIRTUAL_HOST=hello-world.example.com \
  --env LETSENCRYPT_HOST=hello-world.example.com \
  --env LETSENCRYPT_EMAIL="youremail@example.com" \
  tutum/hello-world

์—ฌ๊ธฐ์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€ ๋ด…์‹œ๋‹ค.์šฐ๋ฆฌ๋Š” ๊ฐ์ฒญ ํฌํŠธ 80๊ณผ 443์„ ์œ„ํ•œ ์—์ด์ „ํŠธ ์šฉ๊ธฐ๋ฅผ ์„ค์น˜ํ–ˆ๋‹ค.๊ทธ๋Ÿฐ ๋‹ค์Œ ์ธ์ฆ์„œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ACME ์ธ์ฆ์„œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” Hello World ์šฉ๊ธฐ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.ํ™˜๊ฒฝ ๋ณ€์ˆ˜ VIRTUAL_HOST์„ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ์šฉ๊ธฐ์— ์š”์ฒญํ•œ ๋ฃจํŠธ๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋„๋ก ์—์ด์ „ํŠธ๊ฐ€ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.์‚ฌ์šฉ์ž ์ •์˜ ๋ธŒ๋ฆฌ์ง€ service-network์„ ํ†ตํ•ด ๋ผ์šฐํŒ…์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.๋˜ํ•œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ LETSENCRYPT_HOST๊ณผ LETSENCRYPT_EMAIL์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€์ˆ˜๋Š” ACME ์šฉ๊ธฐ์—์„œ ๊ฐ€์ ธ์˜ค๊ณ  ์ธ์ฆ์„œ๋ฅผ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.์ฐธ๊ณ ๋กœ ๋‘ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์€ ํ•ญ์ƒ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(VIRTUAL_HOST ๋ฐ LETSENCRYPT_HOST).
์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•  ์ผ์€ ์ด ์„ธ ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜์˜ ์šฉ๊ธฐ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์—์ด์ „ํŠธ์™€ ACME ์šฉ๊ธฐ๋Š” ๊ทธ๊ฒƒ์„ ๊ฒ€์ถœํ•˜๊ณ , ๊ณง ์ž‘๋™ํ•  ๊ฒƒ์ด๋‹ค.
์ง€๊ธˆ ๋ช‡ ๊ฐ€์ง€ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ผ์ด ์žˆ๋‹ค.ํฌํŠธ ๊ฒ€์ƒ‰ - ์—์ด์ „ํŠธ๋Š” ์–ด๋–ค ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” Helloworld ์ด๋ฏธ์ง€๋Š” Dockerfile์˜ ํฌํŠธ๊ฐ€ EXPOSE 80์ด๋ผ๋Š” ๊ฒƒ์„ ๋ณด์—ฌ ์ค๋‹ˆ๋‹ค.์ด๊ฒƒ์€ ํ•ญ์ƒ ์šฐ์„ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ์ง€์— ๋…ธ์ถœ๋œ ํฌํŠธ๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.๋‹จ, Dockerfile์— ๊ณต๊ฐœ๋œ ํฌํŠธ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๊ฑฐ๋‚˜, ์‹คํ–‰ํ•  ๋•Œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ (์˜ˆ: HTTP_PORT=8000) ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํฌํŠธ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, --expose ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—์ด์ „ํŠธ์—๊ฒŒ ์–ด๋–ค ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํฌํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ VIRTUAL_PORT๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ํฌํŠธ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ง์”€๋“œ๋ฆฌ์ง€๋งŒ, Dockerfile EXPOSE์€ --expose ๋งค๊ฐœ ๋ณ€์ˆ˜๋ณด๋‹ค ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค.
ํ˜„์žฌ, https://hello-world.example.com์„ ๋ˆŒ๋ €์„ ๋•Œ, DNS ์„œ๋ฒ„๋Š” ๊ณต๊ณต IP๊ฐ€ ์žˆ๋Š” A ๊ธฐ๋ก์„ ๋˜๋Œ๋ ค์ฃผ๊ณ , ๋ธŒ๋ผ์šฐ์ €๋Š” ํฌํŠธ 443์˜ IP ์ฃผ์†Œ์— ์—ฐ๊ฒฐํ•œ ๋‹ค์Œ, ํ˜ธ์ŠคํŠธ๋Š” ์ด ์—ฐ๊ฒฐ์„ nginx-proxy ์šฉ๊ธฐ์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.SSL์„ ์ข…๋ฃŒํ•˜๊ณ  ์š”์ฒญ์„ ์ผ๋ฐ˜ HTTP ์š”์ฒญ ์—์ด์ „ํŠธ๋กœ hello-world ์ปจํ…Œ์ด๋„ˆ์— ํ”„๋ก์‹œํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๋˜ ๋‹ค๋ฅธ ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.HTTP์—์„œ HTTPS๋กœ์˜ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ”„๋ก์‹œ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ข‹์ง€๋งŒ, ๋•Œ๋•Œ๋กœ www/apex ์˜์—ญ์„ ๋‹ค์‹œ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.์ผ๋ถ€ ๋„๋ฉ”์ธ ๋“ฑ๋ก๊ธฐ ์ œ์–ดํŒ์—์„œ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์€ ๋‹ค๋ฅธ IP ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฒˆ์— ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  ์ด๋ฏธ์ง€๋Š” ์‚ฌ์‹ค์ƒ ๋‚˜์˜ ๊ฒƒ์ด๋‹ค. adamkdean/redirect.
๊ทธ๊ฒƒ์˜ ์ž‘์—… ๋ฐฉ์‹์€ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค.VIRTUAL_HOST์„ ๋ฐ”๊ฟ€ ์˜์—ญ์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ๋‹ค๋ฅธ ์šฉ๊ธฐ์˜ ๋ชฉํ‘œ๋ฅผ ์„ค์ •ํ•˜์‹ญ์‹œ์˜ค.์˜ˆ๋ฅผ ๋“ค์–ด ์šฐ๋ฆฌ๋Š” example.com์ด ์žˆ๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์ด ํ•ญ์ƒ www.example.com์œผ๋กœ ๋ฐ”๋€Œ๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์šฐ๋ฆฌ๋Š” www๋ฅผ ์ข‹์•„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์šฐ๋ฆฌ์˜ ์ฃผ์š” ์ด๋ฏธ์ง€๋Š” www.example.com์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
docker run \
  --detach \
  --restart always \
  --name example-website \
  --network service-network \
  --env VIRTUAL_HOST=www.example.com \
  example/website
๊ทธ ๋‹ค์Œ์— ์šฐ๋ฆฌ๋Š” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค์–ด example.com์— ๊ท€์†์‹œํ‚ค๊ณ  ํ™˜๊ฒฝ ๋ณ€์ˆ˜ REDIRECT_LOCATION์„ ์šฐ๋ฆฌ์˜ ์ฒซ ๋ฒˆ์งธ ๋ชฉํ‘œ๋กœ ์„ค์ •ํ•˜๋ฉฐ REDIRECT_STATUS_CODE์„ ์ ์šฉ๋˜๋Š” ๋ชฉํ‘œ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
docker run \
  --detach \
  --restart always \
  --name example-redirect \
  --network service-network \
  --env VIRTUAL_HOST=example.com \
  --env REDIRECT_LOCATION="http://www.example.com" \
  --env REDIRECT_STATUS_CODE=301 \
  adamkdean/redirect
ํ˜„์žฌ ๋ฐœ์ƒํ•œ ๊ฒƒ์€ example.com์— ๋Œ€ํ•œ ์š”์ฒญ์ด ์ด ๋ฆฌ์…‹ ์šฉ๊ธฐ์— ๋งž์•˜๊ณ  REDIRECT_STATUS_CODE๊ณผ REDIRECT_LOCATION์œผ๋กœ ์‘๋‹ตํ–ˆ๋‹ค.
์šฐ๋ฆฌ๋Š” ๋‹น์—ฐํžˆ Let's Encrypt with the this๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
docker run \
  --detach \
  --restart always \
  --name example-website \
  --network service-network \
  --env VIRTUAL_HOST=www.example.com \
  --env LETSENCRYPT_HOST=www.example.com \
  --env LETSENCRYPT_EMAIL="youremail@example.com" \
  example/website

docker run \
  --detach \
  --restart always \
  --name example-redirect \
  --network service-network \
  --env VIRTUAL_HOST=example.com \
  --env LETSENCRYPT_HOST=example.com \
  --env LETSENCRYPT_EMAIL="youremail@example.com" \
  --env REDIRECT_LOCATION="https://www.example.com" \
  --env REDIRECT_STATUS_CODE=301 \
  adamkdean/redirect
์ด ๊ฒฝ์šฐ example.com์˜ ์ดˆ๊ธฐ ์š”์ฒญ ๋ช…์ค‘ ์—์ด์ „ํŠธ์— ๋Œ€ํ•ด ์—์ด์ „ํŠธ๋Š” SSL์„ ์ค‘์ง€ํ•˜๊ณ  example-redirect ์šฉ๊ธฐ์— ์—์ด์ „ํŠธ๋ฅผ ์ฃผ๊ณ  ์ด ์šฉ๊ธฐ๋Š” 301์—์„œ www.example.com์œผ๋กœ ์‘๋‹ตํ•œ๋‹ค.ํ˜„์žฌ www.example.com์˜ ๋‹ค์Œ ์š”์ฒญ์— ๋Œ€ํ•ด ์—์ด์ „ํŠธ๋ฅผ ํด๋ฆญํ•˜๊ณ  example-website ์šฉ๊ธฐ๋ฅผ ํ†ตํ•ด ์—์ด์ „ํŠธ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
Fig F
๋‚˜๋Š” ์ด๊ฒƒ์ด ๋„ˆ์—๊ฒŒ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค.์ด ์„ค์ •์€ ํ•œ ์‚ฌ์ดํŠธ ๋˜๋Š” ์—ฌ๋Ÿฌ ์‚ฌ์ดํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋Œ€ํ˜• ์šฉ๊ธฐ ํ”Œ๋žซํผ์„ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ข€ ์ง€๋‚˜์นœ ์ƒํ™ฉ์—์„œ ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค. (๋ธ”๋กœ๊ทธ์˜kubernetes๋Š” ๋งค์šฐ ์ข‹๋‹ค. ๊ทธ๋ ‡์ง€?)
๊ทธ๊ฒƒ์€ ๋งค์šฐ ์‰ฝ๊ฒŒ ๊ฐฑ์‹ ๋˜๊ณ  ๋ฐฐ์น˜๋˜๋ฉฐ, ์ด๋ฏธ ์‚ฌ์šฉ๋œ ์ง€ 1๋…„์ด ๋„˜์—ˆ๊ณ , ๋งค์šฐ ์ž˜ ์ผํ•œ๋‹ค.์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
์—…๋ฐ์ดํŠธ(2020๋…„ 2์›” 21์ผ): ์š”๊ตฌ์— ๋”ฐ๋ผ docker-compose.yml ๋ฒ„์ „์ด ์žˆ์Šต๋‹ˆ๋‹ค.
version: "3"

services:
  web:
    image: example/website
    expose:
     - 8000
    environment:
      HTTP_PORT: 8000
      VIRTUAL_HOST: www.example.com
      LETSENCRYPT_HOST: www.example.com
      LETSENCRYPT_EMAIL: "example@example.com"
    networks:
      service_network:

  web-redirect:
    image: adamkdean/redirect
    environment:
      VIRTUAL_HOST: example.com
      LETSENCRYPT_HOST: example.com
      LETSENCRYPT_EMAIL: "example@example.com"
      REDIRECT_LOCATION: "https://www.example.com"
    networks:
      service_network:

  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
      - 80:80
      - 443:443
    container_name: nginx-proxy
    networks:
      service_network:
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - nginx-certs:/etc/nginx/certs
      - nginx-vhost:/etc/nginx/vhost.d
      - nginx-html:/usr/share/nginx/html

  nginx-proxy-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    environment:
      NGINX_PROXY_CONTAINER: "nginx-proxy"
    networks:
      service_network:
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - nginx-certs:/etc/nginx/certs
      - nginx-vhost:/etc/nginx/vhost.d
      - nginx-html:/usr/share/nginx/html

networks:
  service_network:

volumes:
  nginx-certs:
  nginx-vhost:
  nginx-html:
์—…๋ฐ์ดํŠธ(2020๋…„ 2์›” 28์ผ):
๋‚˜๋Š” ๋‚ด๊ฐ€ VIRTUAL_PORT์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•  ๋•Œ ์ž˜๋ชป์„ ์ €์งˆ๋ €๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜๋‹ค.๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์ง€๋งŒ, ์—์ด์ „ํŠธ๊ฐ€ Docker ํŒŒ์ผ์˜ EXPOSE ๋ช…๋ น๊ณผ Docker ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค์˜ --expose ๋งค๊ฐœ ๋ณ€์ˆ˜์—์„œ ์–ด๋–ค ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ณ  ์‹ถ์„ ๋ฟ์ž…๋‹ˆ๋‹ค.๋…ธ์ถœ๋œ ํฌํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ VIRTUAL_PORT ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋…ธ์ถœ๋œ ํฌํŠธ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ—ท๊ฐˆ๋ ค์„œ ๋ฏธ์•ˆํ•ด!
์—…๋ฐ์ดํŠธ(2020๋…„ 4์›” 22์ผ):
๋ณด์•ˆ ๋ฆฌ๋””๋ ‰์…˜ ์„ธ์…˜์— ๋ถ€์กฑํ•œ ๋ฐ˜์‚ฌ๋ด‰์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.์•„์ด๊ตฌ!
์—…๋ฐ์ดํŠธ(2020๋…„ 12์›” 11์ผ):
letsencrypt nginx proxy companion์˜ v1 ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
docker run \
  --detach \
  --restart always \
  --name nginx-proxy-letsencrypt \
  --network service-network \
  --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  --volume nginx-certs:/etc/nginx/certs \
  --volume nginx-vhost:/etc/nginx/vhost.d \
  --volume nginx-html:/usr/share/nginx/html \
  --env NGINX_PROXY_CONTAINER="nginx-proxy" \
  jrcs/letsencrypt-nginx-proxy-companion:v1.13.1
๋งŒ์•ฝ ๋„ค๊ฐ€ ์ด ๊ธ€์„ ์ข‹์•„ํ•œ๋‹ค๋ฉด, ๋„ˆ๋Š” ๋‚˜์˜ ๋‹ค์Œ ๊ธ€์„ ์ข‹์•„ํ•  ๊ฒƒ์ด๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ๊นŠ์ด ์žˆ๊ฒŒ ์—ฐ๊ตฌํ•  ๊ฒƒ์ด๋‹ค. ๋„ˆ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์šฉ๊ธฐ๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๋ธ”๋ž™๋ฐ•์Šค ์•ˆ์—์„œ ๋„๋Œ€์ฒด ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
docker์— ๋Œ€ํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.sock: docker ์ˆ˜ํ˜ธ ํ”„๋กœ์„ธ์Šค UNIX ํ”Œ๋Ÿฌ๊ทธ์ธ (/var/run/docker.sock) ์€ docker์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•˜๋ฉด ๋ฃจํŠธ ์ ‘๊ทผ์ž…๋‹ˆ๋‹ค.์ œ3์ž ๊ทธ๋ฆผ์„ ์‹คํ–‰ํ•  ๋•Œ, ์ž์‹ ์ด ๋ฌด์—‡์„ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์‹คํžˆ ์•Œ์•„์•ผ ํ•œ๋‹ค.

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ