HTTPS trên Magento với Nginx Reverse Proxy trên Host và Apache trên Docker Container

Lời mở đầu

Như thường lệ mỗi bài viết về kỹ thuật trên story của mình đều liên quan đến một câu chuyện nào đó, hôm nay lại là một câu chuyện liên quan đến https =))), vui quá nên chém gió tí nhé :3.

Chả là tuần trước có dự án tích hợp với thằng paypalhere còn 1 vấn đề cần resolve để bàn giao cho khách hàng, và mình nhận nhiệm vụ setup server để test tìm nguyên nhân. Sau 10 phút hì hục setup với vài lần bấm phím nhàm chán thì mình cũng tạo được 1 cái site tạm goi là được để cho anh em test. Anh em ưng lắm, vào test tủng các thứ, Abel còn test cả ngày cả đêm để tìm nguyên nhân. Sau khoảng 3 - 4 ngày bới code tìm bug, bằng các biện pháp nghiệp vụ, anh chàng “Quả Chuông” của chúng ta đã tìm ra được bug là do paypalhere =)). Bằng 1 tâm trạng hào hứng và phấn khởi, anh chàng quả chuông bèn message ngay cho mình và anh Mike tai không sơn về bug này đồng thời cũng message ngay cho bên paypal yêu cầu hỗ trợ để giải quyết. Nhưng đời không như mơ, cậu bé bị paypal câu giờ liên tục và cứ bắt giải thích đi giải thích lại suốt - chắc bên đấy mùa này lực cũng yếu. Đâu đấy cỡ 4 - 5 lần thì lời thỉnh cầu được chấp nhận (các cụ bảo chày cối là thành huyền thoại quả không sai). Nhưng… khổ lỗi là được 2 ngày bên đấy báo là không truy cập được site mình tạo ra. Anh chàng quả chuông lại 1 lần nữa message vào nhóm để tìm kiếm sự giúp đỡ xem thằng Oliver nó có làm gì sai không. Nhưng mà không, site thằng Oliver tạo chuẩn bỏ mẹ, lỗi làm sao được. Anh chàng quả chuông lại message lại cho paypal hỏi xem lỗi như nào, thì bên đó mô tả kỹ hơn kèm 1 chiếc Thuỳ Linh đến site test mà mình tạo ra, không quên đính kèm chữ “s” đằng sau http, và vấn đề bắt đầu từ đây. Anh em bắt đầu hỏi nhau và đự đoán - chắc thằng này sợ mình lấy thông tin gì đây nên chỉ dùng link https. Mà https thì trước giờ mình đã cài bao giờ đâu mà truy cập được. Thế là một nhiệm vụ mới được hình thành và mình lại đóng vai một anh chàng culi đi setup https cho cái site test đấy =)).

Kiến trúc

  • 1 con vps
  • Nginx cài trực tiếp trên VPS để làm Reverse Proxy
  • Các containers bên trong để chạy các site Magento 2 trên Apache 2

Tại sao lại làm theo cách này?

Tại vì trên con vps kia của mình đã có sẵn các containers kia cài Magento 2 rồi và nó đang sử dụng không stop được, sau một hồi research và tham khảo ý kiến của anh Walter thì chỉ có cách cài thêm Nginx làm proxy cho nó khả thi thôi, và nó cũng vừa sức với mức kiến thức hiện tại của mình.

Điều kiện tiên quyết

  • Có 1 con VPS
  • Có domain thực tế trỏ về IP của VPS.
  • Biết sử dụng docker, docker-compose(up, start, stop) mấy lệnh cơ bản thôi
  • Biết sử dụng linux commands
  • docker-compose file được build riêng cho việc cài đặt Magento từ Oil Team (với những image khác có thể Apache được build và config khác đi, có thể bạn phải sửa thêm vài config nữa).

Bài viết không hướng dẫn cài magento 2 trên docker containers, bạn có thể tham khảo hướng dẫn tại bài viết khác, sau đó cài đặt magento trước khi bắt đầu.

Các bước thực hiện

Cài Nginx trên host

  1. SSH đến VPS của bạn và thực hiện update packages
    sudo apt update -yqq
  2. Install nginx
    sudo apt install nginx

Cài đặt và cấu hình mod_rpaf

Đây là module Apache, rewrite lại giá trị REMOTE_ADDR, HTTPS và HTTP_PORT dựa trên các giá trị được cung cấp bởi Reverse Proxy. Không có module này, ta có thể phải sửa lại code Magento để nó hoạt động trơn tru sau Reverse Proxy.

  1. Login vào container với quyền root
    docker exec -it -u root <container_id> bash

    Với <container_id> là id của container chứa Apache đang chạy

  2. Update packages
    apt update -yqq

  3. Install required software
    apt install unzip wget build-essential apache2-dev

  4. Download mod_rpaf
    wget https://github.com/gnif/mod_rpaf/archive/stable.zip

  5. Unzip

    unzip stable.zip
    cd mod_rpaf-stable
    
  6. Install

    make
    make install
    
  7. Tạo 1 file trong thư mục mods-available
    nano /etc/apache2/mods-available/rpaf.load

    Nội dung
    LoadModule rpaf_module /usr/lib/apache2/modules/mod_rpaf.so
    Sau đó lưu file lại

  8. Tạo 1 file nữa cũng trong mods-available
    nano /etc/apache2/mods-available/rpaf.conf

    Nội dung

    <IfModule mod_rpaf.c>
        RPAF_Enable             On
        RPAF_Header             X-Real-Ip
        RPAF_ProxyIPs           your_server_ip
        RPAF_SetHostName        On
        RPAF_SetHTTPS           On
        RPAF_SetPort            On
    </IfModule>
    

    thay your_server_ip bằng địa chỉ IP VPS của bạn, sau đó lưu lại

  9. Enable module
    a2enmod rpaf

  10. Test lại apache config
    apachectl -t

  11. Reload lại apache config
    service apache2 reload

  12. Thoát ra khỏi container
    exit

Sau bước này nhớ check lại xem site còn hoạt động không.

Cài SSL Certs với Lets Encrypt

  1. Thêm certbot repository
    sudo add-apt-repository ppa:certbot/certbot

  2. Update packages
    sudo apt update

  3. Install certbot nginx
    sudo apt install python-certbot-nginx

  4. Install certificate
    sudo certbot --nginx -d <yourdomain.com>

    Thay <yourdomain.com> bằng domain trỏ

  5. Kiểm tra lại certificate
    sudo certbot certificates

    Nó hiện ra certificate với domain vừa tạo là được.

  6. Xem lại config Nginx
    sudo cat sudo cp /etc/nginx/sites-available/default

    Như hình dưới bạn có thể để ý, phần tô xanh là domain của bạn, ô đỏ đầu tiên là khai báo server name, ô đỏ thứ 2 là config route cho các request, ô đỏ cuối cùng là config SSL do certbot vừa tạo.

Sửa lại config Nginx.

  1. Làm cái backup config trước đã
    sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
  2. Sửa lại phần config ở section location (khung đỏ số 2 ở bước trên).
    sudo nano /etc/nginx/sites-available/default
    Content cũ
    location / {
    	# First attempt to serve request as file, then
    	# as directory, then fall back to displaying a 404.
    	try_files $uri $uri/ =404;
    }
    
    Content mới
    location / {
    	# First attempt to serve request as file, then
    	# as directory, then fall back to displaying a 404.
    	# try_files $uri $uri/ =404;
    	proxy_pass <your_server_ip>;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
    Với your_server_ip là IP vps của bạn.
  3. Check lại config nginx xem có bị lỗi gì không
    sudo nginx -t
  4. Reload lại Nginx config
    sudo service nginx reload

Config lại magento base url

Nếu bạn vẫn config truy cập website magento qua IP và port như này
http://<your_server_ip>:<port_number>
Thì cần update lại thành domain website của bạn và bỏ phần port đi vì mình đã config nginx làm Reverse Proxy rồi.

  1. Login vào data base container
    docker exec -it -u root <container_id>
  2. Login vào database
    mysql -u root -p <database_name> -A
  3. Update base url
    update core_config_data set value="http://<yourdomain.com>/" where path like '%base_url%' and scope='default';
  4. Thoát khỏi mysql và database container
     exit; 
     exit;
    
  5. Login vào web container
    docker exec -it -u ww-data <container_id> bash
  6. Update lại magento config
    php bin/magento setup:store-config:set --use-secure 1
    php bin/magento setup:store-config:set --base-url-secure https://<yourdomain.com>/
    php bin/magento setup:store-config:set --use-secure-admin 1
    php bin/magento setup:static-content:deploy -f
    php bin/magento cache:flush
    
  7. Vào lại website Magento bằng Domain của bạn.

Bài viết có tham khảo

  1. https://stories.magestore.com/t/how-to-configure-ssl-for-magento-2-website/160
  2. https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-web-server-and-reverse-proxy-for-apache-on-one-ubuntu-18-04-server
    và một số bài viết khác trên Internet
2 Likes

Thật ra là anh có cách khác làm ngon hơn là phải dựng riêng một con làm Reverse Proxy ở ngoài rồi @oliver ạ! Anh sẽ sớm public cho các chú hưởng hàng với mọi docker container sử dụng apache or nginx nhé

Bài viết ngày xưa mình viết giờ đọc lại đến mình còn đéo làm được nữa là người khác =)))

2 Likes