Facebook Pixel

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

02 Jul, 2021

Docker cùng Nginx. Let's Encrypt. 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.

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

Mục Lục

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ả:

Trang blog cá nhân của mình 

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

  1. Có một VPS/Server có thể SSH vào được (hoặc xem hướng dẫn tạo Droplet Digital Ocean).
  2. Sở hữu một domain cá nhân. Bạn có thể mua tại Namecheap.com. À nhớ trỏ domain vào IP public của VPS/Server nhé.
  3. Vì dùng Docker nên bạn cần hiểu một chút Docker nhé. Xem thêm Docker là gì? Tại sao lại cần nó?

Để 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:

Bash
ssh root@your_domain
Cài đặt docker trên VPS/Server

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

Bash
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.
Trường hợp bị lỗi không tìm thấy package containerd.io

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

Bash
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

Bash
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:

Bash
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

Website đã được deploy thành công

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.

Bash
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

Bash
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

Website hiện đã có SSL

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:

JrCs/docker-nginx-proxy-letsencrypt
Automated nginx proxy with letsencrypt client inside. DEPRECATED in favor of docker-letsencrypt-nginx-proxy-companion. - JrCs/docker-nginx-proxy-letsencrypt

Lời 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é.

Nếu bạn có định hướng trở thành DevOps chuyên nghiệp thì bạn có thể tham khảo khoá học DevOps for Backend Developer tại đây.

Bài viết liên quan:

Bài viết liên quan

Lập trình backend expressjs

xây dựng hệ thống microservices
  • Kiến trúc Hexagonal và ứng dụngal font-
  • TypeScript: OOP và nguyên lý SOLIDal font-
  • Event-Driven Architecture, Queue & PubSubal font-
  • Basic scalable System Designal font-

Đăng ký nhận thông báo

Đừng bỏ lỡ những bài viết thú vị từ 200Lab