Triển khai dự án laravel với laradock (p.3)
#laravel #laradock
1
Male avatar

certainlyT viết ngày 24/01/2019

[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

alt text

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

alt text

Bật browser lên, gõ địa chỉ và kiểm tra kết quả.

alt text

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

alt text

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:

alt text

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

alt text

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

alt text

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.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

certainlyT

3 bài viết.
1 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
4 1
Phần 1]: Giới thiệu và làm quen với laradock 1) Laradock là gì ? Tại sao nên dùng laradock ? Laradock = laravel + docker. Tức là dùng docker để tr...
certainlyT viết 10 tháng trước
4 1
Male avatar
2 0
Phần 2]: Multi site trên laradock local Phần này ta sẽ tiếp tục những gì đã làm ở (Link). Ta sẽ triển khai thêm 2 project laravel: laravel2 với cấ...
certainlyT viết 9 tháng trước
2 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
3 bài viết.
1 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!