Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Triển khai dự án laravel với laradock (p.3)
[Phần 3]: Triển khai dự án laravel với laradock trên môi trường production
Tiếp theo phần 2, lần này ta sẽ triển khai một dự án laravel trên môi trường production.
Việc triển khai giữa 2 môi trường cũng không khác nhau là mấy, tuy nhiên trên môi trường production, bạn sẽ cần nhiều hơn là một chứng chỉ HTTPS tự tạo
Bài viết này sẽ yêu cầu bạn cần có 1 VPS có public IP, 1 domain name. Với 1 số bạn sinh viên, để thử bài viết này, bạn có thể đăng kí 1 tài khoản GCP (Google Cloud Platform), bạn sẽ được 300$ miễn phí để sử dụng thử các dịch vụ của Google Cloud, trong đó có việc tạo 1 VPS để triển khai dự án laravel. Với domain name, các bạn có thể đăng ký 1 tên miền miễn phí với những tên miền có đuôi lạ .ml hoặc .ga
Như phần 1, mình sẽ nêu ra các bước để chạy 1 project laravel trên một con VPS ubuntu đã được cài docker và docker-compose
- Pull code laradock
- Chỉnh sửa cấu hình cho các container (nếu cần)
- Pull code laravel
- Cho các container start lên
- Vào workspace và chạy các câu lệnh cần thiết
- Cài đặt certbot lên nginx container
- Lấy certificate cho trang web của bạn
Mình sẽ start trang web kipalog.renge.vn, nhà nghèo nên xài tạm domain công ty để demo vậy (;¬_¬).
1) Đầu tiên, pull code của laradock về
git clone https://github.com/laradock/laradock.git
Tạo 1 thư mục tên web kế bên. Thư mục này sẽ chứa code web. Clone code của bạn vào thư mục web này, đặt tên là kipalog chẳng hạn
2) Chỉnh sửa cấu hình cho các container
Lấy file .env đã
cp env-example .env
Thay đổi 1 số thứ trong file .env: vi .env.
APP_CODE_PATH_HOST: nơi chứa code của bạn
APP_CODE_PATH_HOST=../web
PHP_VERSION: chọn version cho Php
PHP_VERSION=7.2
WORKSPACE_INSTALL_MYSQL_CLIENT: cài đặt Mysql-client vào workspace. Sau này sẽ cần khi backup dữ liệu. Nếu code của bạn cần thêm gì (yarn, ioncube ...) thì enable nó lên
WORKSPACE_INSTALL_MYSQL_CLIENT=true
Thay đổi các thông số mặc định về username và password của mariadb là rất cần thiết, nhất là root password
MARIADB_DATABASE=kipalog
MARIADB_USER=cute_phomaique
MARIADB_PASSWORD=SuperSecretPassword
MARIADB_PORT=3306
MARIADB_ROOT_PASSWORD=^epGVK75Xz
MARIADB_ENTRYPOINT_INITDB=./mariadb/docker-entrypoint-initdb.d
Thêm file kipalog.conf vào nginx/sites/
server {
listen 80;
listen [::]:80;
server_name kipalog.renge.vn;
root /var/www/kipalog/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fixes timeouts
fastcgi_read_timeout 600;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
error_log /var/log/nginx/kipalog_error.log debug;
access_log /var/log/nginx/kipalog_access.log;
}
3) Cho các container start lên
docker-compose up -d nginx mariadb workspace
4) Vào workspace và chạy các câu lệnh cần thiết
docker-compose exec --user=laradock workspace bash
Giờ bạn đã ở trong workspace container. Mọi thay đổi trong này cũng sẽ thay đổi code bên ngoài do đã được "volume"
Sửa file .env của bạn để laravel có thể kết nối đến database
MARIADB_DATABASE=kipalog
MARIADB_USER=cutephomaique
MARIADB_PASSWORD=SuperSecretPassword
MARIADB_PORT=3306
MARIADB_ROOT_PASSWORD=verySecret
MARIADB_ENTRYPOINT_INITDB=./mariadb/docker-entrypoint-initdb.d
Chạy các câu lệnh cần thiết để cài đặt các gói
composer install && php artisan migrate
và hầm bà lằng các thứ khác nữa
Trỏ DNS tới địa chỉ IP của VPS của bạn. Ở đây mình xài dịch vụ của MatBao, thêm địa chỉ kipalog.renge.vn để trỏ tới IP VPS của mình là 52.220.193.32
Bật browser lên, gõ địa chỉ và kiểm tra kết quả.
Bước tiếp theo mình sẽ lấy ssl certificate cho trang web. Việc lấy này sẽ được thông qua Letsencrypt và certbot
Letsencrypt sẽ đứng ra như 1 CA để xác nhận cho certificate free của bạn. Cơ chế hoạt động của Letsencrypt được giải thích rõ ở đây.
Let’s Encrypt is a free, automated, and open Certificate Authority
Còn Certbot là 1 chương trình trên client để lấy certificate
Certbot is an easy-to-use automatic client that fetches and deploys SSL/TLS certificates for your web server. Certbot was developed by EFF and others as a client for Let’s Encrypt and was previously known as “the official Let’s Encrypt client” or “the Let’s Encrypt Python client.” Certbot will also work with any other CAs that support the ACME protocol.
Nói một cách đơn giản về cách chúng ta sẽ dùng thì certbot sẽ đặt 1 file ở địa chỉ YOUR_DOMAIN/.well-known/acme-challenge
và máy chủ của Letsencrypt sẽ vào đường link đó và tìm file đó xem có tồn tại và đúng hay không. Nếu đúng thì nó xác thực rằng ta là chính chủ của domain đó và cấp 1 chứng chỉ ssl cho dùng trong 3 tháng.
Ưu điểm của Letsencrypt:
- Free
- Ờ thì free là ưu điểm bự nhất còn gì :)
Nhược điểm:
- Chứng chỉ chỉ có 3 tháng thôi. Cứ 3 tháng phải renew 1 lần. Nhưng mà không sao, ta có thể chạy 1 crontab cho nó tự động renew
- Không phù hợp cho công ty có tiền (⌐▨_▨)
Có nhiều cách để sử dụng certbot với một web server. Laradock hỗ trợ sẵn certbot container dùng chung với Caddy. Để sử dụng với nginx, bạn có 2 cách: một là build 1 container certbot cho nginx để chạy độc lập, 2 là cài đặt luôn certbot lên nginx container. Bài viết này mình sẽ hướng dẫn cách thứ 2 đó là cài đặt certbot lên nginx container.
5) Cài đặt certbot lên nginx container
Vào Dockerfile của nginx trong thư mục nginx của laradock, thêm dòng apk add --no-cache certbot
để cài đặt certbot
...
RUN apk update \
&& apk upgrade \
&& apk add --no-cache openssl \
&& apk add --no-cache bash \
&& apk add --no-cache certbot \
&& adduser -D -H -u 1000 -s /bin/bash www-data
...
Cho nginx container stop, sau đó build lại image cho nginx container rồi start lên lại
docker-compose stop nginx
docker-compose build --no-cache nginx
sau khi build xong thì cho up lên thôi
docker-compose up -d nginx
Vậy là ta đã cài đặt xong certbot cho nginx container. Bước tiếp theo là lấy certificate cho trang web của mình thôi
6) Lấy certificate cho trang web
Trước khi thực hành chi tiết, ta cùng xem qua đoạn sau trong file kipalog.conf
...
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
...
Đoạn này báo cho nginx biết rằng khi một client (ở đây là letsencrypt server) truy cập đến đường dẫn YOURDOMAIN/.well-known/acme-challenge, nginx sẽ tìm file trong thư mục /var/www/letsencrypt. Mà thư mục /var/www trong workspace chính là thư mục web bên ngoài máy host.
Vào thư mục web, tạo 1 thư mục tên là letsencrypt.
mkdir letsencrypt
Set quyền cho thư mục letsencrypt
chmod -R 777 letsencrypt
Ở đây mình set full quyền để đảm bảo việc đọc file trong thư mục đó không bị vấn đề gì
Truy cập vào nginx container
docker-compose exec nginx bash
Chạy câu lệnh sau cho certbot
certbot certonly --webroot -d kipalog.renge.vn -w /var/www/letsencrypt --config-dir /etc/nginx/ssl
Ta đi vào chi tiết của từng option của certbot
- certbot: câu lệnh của certbot. Nếu bạn chỉ chạy câu lệnh
certbot
, certbot sẽ cố gắng tự cấu hình nginx để có thể lấy ssl certificate cho bạn. Tuy nhiên, trong nginx container, certbot sẽ không thể tự nhận diện được và cấu hình được nginx cho bạn - certonly: khi certbot không thể tự cấu hình được, certonly bảo chương trình certbot rằng tao chỉ cần lấy certificate thôi
- webroot: bảo certbot rằng cách thức để tao lấy certificate là webroot, tức là đặt 1 file vào đường dẫn /.well-known/acme-challenge
- d: tên miền mà ta cần certificate
- w: thư mục để đặt file vào khi dùng webroot
- config-dir: đường dẫn đặt certificate nếu lấy thành công. Mặc định đường dẫn sẽ là /etc/letsencrypt nhưng trong file docker-compose của laradock ta đã set volume từ /etc/nginx/ssl trong nginx container ra thư mục laradock/nginx/ssl. Nhờ vậy ta sẽ dễ dàng lưu lại certificate kể cả khi container bị stop
Sau khi gõ câu lệnh, bạn sẽ bị hỏi vài thông tin liên quan. Cung cấp 1 email thật để nhận mail khi có certificate gần hết hạn (Letsencrypt sẽ tự động gửi cho bạn mail này).
Nếu lấy certificate thành công, bạn sẽ nhận được thông báo như sau:
Nhập exit
để thoát ra khỏi nginx container. Thay đổi file kipalog.conf như sau:
server {
# listen 80;
# listen [::]:80;
# For https
listen 443 ssl http2;
ssl_certificate /etc/nginx/ssl/live/kipalog.renge.vn/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/kipalog.renge.vn/privkey.pem;
server_name kipalog.renge.vn;
root /var/www/kipalog/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fixes timeouts
fastcgi_read_timeout 600;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
error_log /var/log/nginx/kipalog_error.log;
access_log /var/log/nginx/kipalog_access.log;
}
server {
listen 80;
server_name kipalog.renge.vn;
return 301 https://$host$uri;
}
Restart nginx container
docker-compose restart nginx
Kết quả:
Vì là hàng free nên mỗi 3 tháng ta phải renew lại 1 lần. Câu lệnh để renew là certbot renew --config-dir
. Để không phải bận tâm phải bận tâm certificate hết hạn, mình có thể làm 1 crontab để tự động renew mỗi ngày luôn
Tạo 1 file thực thi crontab.sh như sau
#!/bin/bash
/usr/bin/docker exec laradock_nginx_1 bash -c 'certbot renew --config-dir /etc/nginx/ssl && exit'
Cho quyền thực thi
chmod +x crontab.sh
Chỉnh sửa crontab file
crontab -e
Thay đổi file crontab
@daily sh /home/ubuntu/crontab.sh > /dev/null 2>&1
Xong, giờ ta có thể yên tâm gác chân lên giường mà ngủ. Trang web laravel của chúng ta đã hoạt động ngon lành. Nếu muốn update code mới, chỉ việc vào thư mục web/kipalog rồi git pull về thôi
Một vài best practice cho môi trường production
- Thay đổi mật khẩu mặc định của mariadb
- Tốt nhất là nên tắt luôn adminer để ngăn chặn việc truy cập database từ ngoài. Khi cần thì start lên lại
- Những data/dữ liệu mà bạn muốn giữ thì nên volume ra ngoài để lưu trữ ở host (ví dụ certificate). Khi ta stop container thì sẽ giống như bạn bung file ghost ra vậy (ở đây là bung docker image), dữ liệu bên trong sẽ bị reset lại từ đầu.
Xong vậy là ta đã triển khai thành công trên môi trường production. Phần tiếp theo, ta sẽ tiếp tục với việc backup cho dự án laravel của mình.






