VPS

Deploy Laravel lên VPS: quyền, queue và scheduler

Thanh Nguyễn Đăng 9 phút đọc 8 khối lệnh

Deploy Laravel lên VPS: quyền, queue và scheduler
Mục lục bài viết
  1. Chuẩn bị máy chủ
  2. Đưa mã nguồn lên và cài gói
  3. Quyền thư mục, thủ phạm số một của lỗi 500
  4. Queue worker chạy như một dịch vụ
  5. Scheduler và tinh chỉnh cho production
  6. Đặt quyền thư mục cho đúng ngay từ đầu
  7. Ba việc phải làm khi đưa lên chạy thật
  8. Quy trình triển khai không làm hỏng hàng đợi
  9. Câu hỏi thường gặp
  10. Bài viết liên quan

Trả lời nhanh: Một lần Laravel deploy đầy đủ gồm bốn phần mà người mới hay bỏ sót ba: đưa mã nguồn lên và cài gói, đặt đúng quyền cho hai thư mục storage và bootstrap/cache, chạy queue worker như một dịch vụ nền thay vì chạy tay, và bật scheduler bằng đúng một dòng cron. Thiếu phần quyền thì trang trắng, thiếu queue thì email không gửi, thiếu cron thì mọi tác vụ định kỳ im lặng không chạy.

Laravel chạy ngon trên máy lập trình rồi lên máy chủ thì lỗi 500, đó là cảnh quen thuộc với ai deploy lần đầu. Nguyên nhân hiếm khi nằm ở code, mà nằm ở những thứ máy cá nhân tự lo hộ: quyền ghi thư mục, tiến trình nền, và lịch chạy tự động. Bài này đi trọn quy trình đưa một dự án Laravel lên VPS Ubuntu, theo thứ tự thực tế bạn sẽ gặp.

Chuẩn bị máy chủ

Bắt đầu với VPS Ubuntu bản LTS. Cài PHP kèm các phần mở rộng Laravel cần, Composer, Nginx và database:

TerminalChuẩn bị máy chủbash
sudo apt updatesudo apt install -y php8.3-fpm php8.3-cli php8.3-mysql php8.3-mbstring   php8.3-xml php8.3-curl php8.3-zip php8.3-bcmath php8.3-intl   nginx mysql-server unzip git # Composercurl -sS https://getcomposer.org/installer | phpsudo mv composer.phar /usr/local/bin/composer

Số hiệu phiên bản PHP thay đổi theo thời điểm, hãy chọn bản còn được hỗ trợ và khớp với yêu cầu trong file composer.json của dự án. Nếu máy chủ vừa nhận về còn trắng, làm trước các bước an toàn cơ bản trong bài 12 việc làm ngay sau khi nhận VPS.

Đưa mã nguồn lên và cài gói

TerminalĐưa mã nguồn lên và cài góibash
cd /var/wwwsudo git clone <repo> app && cd app # Cai goi cho ban chay that, khong cai goi danh cho lap trinhcomposer install --no-dev --optimize-autoloader cp .env.example .envphp artisan key:generate

Sửa file .env cho đúng môi trường thật: APP_ENV=production, APP_DEBUG=false, thông tin database, và địa chỉ trang. Để APP_DEBUG=true trên máy chủ thật là lỗi bảo mật nghiêm trọng, vì mỗi lỗi phát sinh sẽ phơi ra đường dẫn, biến môi trường và một phần mã nguồn cho bất kỳ ai truy cập.

Sau đó chạy migration và bật các bản cache dành cho production:

TerminalĐưa mã nguồn lên và cài góibash
php artisan migrate --forcephp artisan config:cachephp artisan route:cachephp artisan view:cache

Nhớ một điều dễ quên: mỗi lần bạn sửa .env, phải chạy lại php artisan config:cache, nếu không ứng dụng vẫn đọc giá trị cũ và bạn sẽ ngồi gỡ một lỗi không tồn tại.

Quyền thư mục, thủ phạm số một của lỗi 500

Laravel cần ghi vào hai chỗ: storage cho log, cache, file tải lên, và bootstrap/cache cho cache cấu hình. Người dùng chạy PHP-FPM phải sở hữu hai thư mục này:

TerminalQuyền thư mục, thủ phạm số một của lỗi 500bash
sudo chown -R www-data:www-data storage bootstrap/cachesudo find storage -type d -exec chmod 775 {} ;sudo find storage -type f -exec chmod 664 {} ;

Đừng dùng quyền 777 cho nhanh. Nó khiến mọi người dùng trên máy chủ ghi được vào thư mục ứng dụng, và với máy chủ dùng chung thì đó là cửa mở sẵn. Nếu bạn deploy bằng tài khoản khác tài khoản chạy web, hãy thêm tài khoản đó vào nhóm www-data thay vì nới quyền.

Khi gặp lỗi 500 mà không hiểu vì sao, chỗ đầu tiên cần xem luôn là storage/logs/laravel.log, sau đó tới log lỗi của PHP-FPM và Nginx.

Queue worker chạy như một dịch vụ

Gửi email, xử lý ảnh, gọi API bên ngoài đều nên đẩy vào hàng đợi để người dùng không phải chờ. Nhưng php artisan queue:work gõ tay sẽ chết ngay khi bạn đóng phiên SSH. Cách đúng là để systemd trông:

TerminalQueue worker chạy như một dịch vụbash
# /etc/systemd/system/laravel-queue.service[Unit]Description=Laravel queue workerAfter=network.target [Service]User=www-dataRestart=alwaysRestartSec=3ExecStart=/usr/bin/php /var/www/app/artisan queue:work --sleep=3 --tries=3 --max-time=3600 [Install]WantedBy=multi-user.target
TerminalQueue worker chạy như một dịch vụbash
sudo systemctl enable --now laravel-queuesudo systemctl status laravel-queue

Hai chi tiết đáng chú ý: Restart=always để worker tự sống lại sau khi lỗi, và để tiến trình tự kết thúc theo chu kỳ, tránh rò rỉ bộ nhớ tích tụ. Và nhớ quy tắc quan trọng: mỗi lần deploy code mới phải khởi động lại worker, vì tiến trình cũ vẫn giữ mã nguồn cũ trong bộ nhớ.

Scheduler và tinh chỉnh cho production

Toàn bộ tác vụ định kỳ của Laravel chỉ cần đúng một dòng cron:

TerminalScheduler và tinh chỉnh cho productionbash
* * * * * cd /var/www/app && php artisan schedule:run >> /dev/null 2>&1

Laravel tự quyết định tác vụ nào tới giờ, nên bạn không phải thêm dòng cron cho từng việc. Thiếu dòng này thì mọi lịch trong routes/console.php im lặng không chạy, và đây là lỗi rất khó nhận ra vì không có thông báo nào cả.

Về hiệu năng, ba việc đáng làm: bật OPcache cho PHP, đặt số tiến trình PHP-FPM khớp với RAM thực có, và chuyển session cùng cache sang Redis nếu ứng dụng có nhiều người dùng đồng thời. Cách đọc và chỉnh các tham số PHP-FPM nằm ở bài riêng trong cụm này. Còn khi ứng dụng chậm mà không rõ nghẽn ở đâu, phần lớn trường hợp là truy vấn database chứ không phải PHP, hãy soi theo bài database chậm.

Đặt quyền thư mục cho đúng ngay từ đầu

TerminalĐặt quyền thư mục cho đúng ngay từ đầubash
# Nguyen tac: ma nguon thuoc ve nguoi trien khai,# nhung thu muc ghi phai cho may chu web ghi duoc # 1. Dat chu so huu cho toan bo ma nguonchown -R nguoi-trien-khai:www-data /var/www/ungdung # 2. Quyen co banfind /var/www/ungdung -type f -exec chmod 644 {} \;find /var/www/ungdung -type d -exec chmod 755 {} \; # 3. Hai thu muc PHAI ghi duoc, day la cho hay sai nhatchmod -R 775 /var/www/ungdung/storagechmod -R 775 /var/www/ungdung/bootstrap/cachechown -R nguoi-trien-khai:www-data /var/www/ungdung/storage /var/www/ungdung/bootstrap/cache # 4. Kiem log de biet loi that su la gitail -50 /var/www/ungdung/storage/logs/laravel.logtail -50 /var/log/nginx/error.log # 5. Tep cau hinh moi truong khong duoc doc tu ben ngoaichmod 600 /var/www/ungdung/.envcurl -sI https://tenmien.vn/.env | head -1   # phai la 403 hoac 404

Lệnh cuối là phép kiểm bắt buộc: tệp cấu hình môi trường chứa mật khẩu cơ sở dữ liệu và khóa ứng dụng. Nếu nó đọc được từ internet thì toàn bộ hệ thống coi như đã lộ.

Ba việc phải làm khi đưa lên chạy thật

ViệcVì sao
Tắt chế độ gỡ lỗiBật chế độ này là hiển thị đường dẫn, cấu hình và một phần mã nguồn cho mọi người
Lưu đệm cấu hình và định tuyếnTăng tốc đáng kể, nhưng nhớ xóa đệm mỗi lần triển khai
Đặt tiến trình chạy nền như một dịch vụ hệ thốngChạy bằng tay là chết khi đóng phiên đăng nhập

Quy trình triển khai không làm hỏng hàng đợi

  1. Đưa mã mới lên và cài gói.
  2. Chạy các thay đổi cấu trúc cơ sở dữ liệu.
  3. Xóa và tạo lại bộ nhớ đệm cấu hình.
  4. Khởi động lại tiến trình chạy nền. Bước này hay bị quên, và hậu quả là tiến trình cũ vẫn chạy mã cũ, gây lỗi rất khó hiểu.
  5. Kiểm nhật ký lỗi trong vài phút đầu sau khi triển khai.

Chi tiết về tiến trình chạy nền nằm ở bài về hàng đợi công việc.

Câu hỏi thường gặp

Vì sao deploy xong trang trắng hoặc lỗi 500?

Chín trên mười trường hợp là quyền thư mục storage và bootstrap/cache chưa thuộc về người dùng chạy PHP-FPM, hoặc file .env chưa có APP_KEY. Mở storage/logs/laravel.log ra đọc trước, thông báo lỗi ở đó thường chỉ thẳng nguyên nhân.

Có cần Supervisor cho queue worker không?

Không bắt buộc. Systemd có sẵn trên Ubuntu và làm được đúng việc đó với ít phần mềm hơn. Supervisor tiện khi bạn cần chạy nhiều worker cùng cấu hình và muốn quản lý tập trung, nhưng với một hai worker thì systemd gọn hơn.

Deploy code mới có cần làm gì thêm không?

Có ba việc: chạy lại migration nếu có thay đổi database, tạo lại cache cấu hình và route, và khởi động lại queue worker. Bỏ bước cuối là nguyên nhân phổ biến khiến code mới đã lên nhưng job nền vẫn chạy logic cũ.

VPS cấu hình bao nhiêu cho một dự án Laravel?

Trang giới thiệu hoặc ứng dụng nội bộ ít người dùng chạy tốt với 2 vCPU và 4GB RAM. Ứng dụng có nhiều truy vấn và job nền nên bắt đầu từ 4 vCPU và 8GB. Yếu tố ảnh hưởng nhiều không kém là tốc độ ổ đĩa, vì database và cache đều đọc ghi liên tục.

Chia sẻ:Facebook

Thanh Nguyễn

TND

Tư vấn bản quyền, VPS và máy chủ kèm hóa đơn VAT, hợp đồng đầy đủ cho doanh nghiệp.