+3

Docker: Deploy Nginx, Let's Encrypt web service có SSL đơn giản nhất

image.png

Trong bài viết này mình sẽ hướng dẫn các bạn cách sử dụng Docker để deploy một website có SSL (tức là https) rất đơn giản. Ví dụ kết quả:

image.png

Các bước chuẩn bị

Để chuẩn bị thì mình đã tạo 1 domain: demo.viettranx.com trỏ vào Droplet IP.

Cài đặt Docker trên VPS/Server

Do bài trước mình đã hướng dẫn các bạn tạo VPS Ubuntu nên bài này mình đi tiếp cho tiện nhé. Hãy chắc rằng bạn đã SSH vào được VPS với lệnh:

ssh root@your_domain

image.png

Thực thi tiếp các câu lệnh sau:

sudo apt-get update

sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Xem chi tiết tai document cài đặt Docker cho từng OS tại đây: https://docs.docker.com/engine/install/ubuntu/

Rất có khả năng các bạn sẽ gặp lỗi liên quan tới containerd.io.

image.png

Nếu vậy các bạn chạy tiếp các câu sau:

sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic test"

sudo apt update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Nếu mọi thứ đã ngon lành, các bạn thử với lệnh: docker -v và thấy version Docker in ra là ngon lành.

Run lần lượt các container cần thiết

Container Nginx

docker run -d -p 80:80 -p 443:443 --name nginx-proxy  --privileged=true \
  -e ENABLE_IPV6=true \
  -v ~/nginx/vhost.d:/etc/nginx/vhost.d \
  -v ~/nginx-certs:/etc/nginx/certs:ro \
  -v ~/nginx-conf:/etc/nginx/conf.d \
  -v ~/nginx-logs:/var/log/nginx \
  -v /usr/share/nginx/html \
  -v /var/run/docker.sock:/tmp/docker.sock:ro \
  jwilder/nginx-proxy

Nginx mục đích để chúng ta có một reverse proxy, chịu trách nhiệm điều hướng các request từ ngoài vào đúng các service. Đương nhiên Nginx sẽ còn nhiều chức năng khác, tuy nhiên trong giới hạn bài viết này mình chỉ cần nó cho mục đích đơn giản vậy thôi.

Xem thêm các tham số cấu hình container jwilder/nginx-proxy: https://github.com/nginx-proxy/nginx-proxy

Bản chất container này là automated Nginx. Tức là nó sẽ tự động thiết lập cho toàn bộ các container khi có có các biến môi trường phù hợp. Phần tiếp theo sẽ cho các bạn thấy rõ điều đó.

Container web service

Nhân vật chính mà chúng ta cần deploy đây rồi. Để đơn giản mình sẽ dùng lại Image yeasy/simple-web:

docker run -it -d --name simple-web \
  -e VIRTUAL_HOST="demo.viettranx.com" \
  -e VIRTUAL_PORT=80 \
  yeasy/simple-web

Trong đó có 2 ENV cần lưu ý:

  • VIRTUAL_HOST: Domain của bạn (ở đây mình dùng demo.viettranx.com)
  • VIRTUAL_PORT: PORT kết nối vào webservice.

Cả 2 ENV này đều không phải bản thân container yeasy/simple-web. Chúng là của container jwilder/nginx-proxy. Nói đơn giản là nginx container này sẽ theo dõi tất cả container run lên nếu có 2 ENV đó là nó tự phát sinh config phù hợp và reload Nginx. Bình thường chúng ta phải làm bằng tay, quá tuyệt.

Bạn có thể dùng với bất kỳ một service container nào cũng được nhé!!

Kết quả bạn mở trình duyệt và chạy url: http://demo.viettranx.com

image.png

Cấu hình SSL – Hoàn toàn miễn phí

Tới đây các bạn đã có được một website chạy trên chính doamin của bạn. Tuy nhiên nó là http thôi, không có mã hoá đường truyền. Vì thế trước URL trên trình duyệt sẽ có “Not Secure“.

Điều này khiến website bạn có độ tin cậy kém, đặc biệt là những chỗ login hoặc thanh toán là người dùng sẽ e dè ngay. Thêm vào đó website bạn sẽ khó mà tương tác được với các nền tảng dùng https.

OK. Để dùng được https, bạn có thể mua một SSL xịn hẳn hoi, loại basic cũng cỡ 4$/năm thôi. Tuy nhiên có một giải pháp nữa là dùng SSL FREE từ Let’s Encrypt.

docker run -d --privileged=true \
  -v ~/nginx/vhost.d:/etc/nginx/vhost.d \
  -v ~/nginx-certs:/etc/nginx/certs:rw \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  --volumes-from nginx-proxy \
  jrcs/letsencrypt-nginx-proxy-companion

Khoan nha, chưa effect gì đâu, các bạn cần gỡ container web ra và chạy lại với lệnh sau

docker rm -f simple-web

docker run -it -d --name simple-web \
  -e VIRTUAL_HOST="demo.viettranx.com" \
  -e VIRTUAL_PORT=80 \
  -e LETSENCRYPT_HOST="demo.viettranx.com" \
  -e LETSENCRYPT_EMAIL="blog@demo.viettranx.com" \
  yeasy/simple-web

Đợi tầm 60s, các bạn truy cập web với URL: https://demo.viettranx.com

image.png

Chuyện gì vừa xảy ra vậy!!

Bản chất container jrcs/letsencrypt-nginx-proxy-companion cũng tự động theo dõi các container, nó phối hợp cùng container nginx trước đó để có thể cung cấp SSL Let’s Encrypt. Miễn là container có chứa ENV:

  • LETSENCRYPT_HOST: Domain của bạn (ở đây mình dùng demo.viettranx.com)
  • LETSENCRYPT_EMAIL: Email bạn muốn dùng để đăng ký SSL, không cần là một email thật nhé.

Không những cấp SSL Let’s Encrypt, container này còn tự động check và gian hạn cho chúng ta luôn. Hạn sử dụng của SSL này là 90 ngày thôi. Hồi đó mình cứ phải canh để chạy câu lệnh gia hạn hoặc set cron job nhưng giờ thì hết rồi. Quá tiện lợi đúng không?!

Xem thêm các cấu hình khác tại:

https://github.com/JrCs/docker-nginx-proxy-letsencrypt

Kết

Bài viết này nhằm giúp các bạn có được một service bất kỳ run với Docker để có được Nginx làm reverse proxy và SSL FREE với Let’s Encrypt đơn giản nhất. Những yếu tố nặng nề kỹ thuật hoặc cơ chế vận hành mình xin được bỏ qua. Chúc các bạn deploy được các service của mình nhanh chóng và hiệu quả hơn với phương pháp này nhé.

Bạn có thể xem bài viết đầy đủ tại 200Lab Education


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí