Cài đặt hệ thống
Trang này hướng dẫn theo đúng kiểu cài đặt đang có trong thư mục deployment: đưa mã nguồn lên GitHub, để GitHub Actions đóng gói bản build, rồi dùng SSH để đưa phiên bản mới lên server. Cách này phù hợp khi bạn muốn mỗi lần cập nhật chỉ cần push code là hệ thống tự triển khai.
Hiểu nhanh 6 khái niệm trước khi bắt đầu
GitHub repository: nơi lưu mã nguồn của dự ánGitHub Actions: công cụ tự chạy các bước build và deploy mỗi khi bạn đẩy code lên GitHubserver: máy chủ chạy website thật.env: file chứa cấu hình của phần backend như domain, database, mail, queue.env.admin: file chứa cấu hình riêng của phần admin frontendSSH key: cặp khóa giúp GitHub đăng nhập an toàn vào server mà không cần nhập mật khẩu
Cài đặt này đang hoạt động theo luồng nào?
- Bạn
pushcode lên nhánhdevhoặcmain. GitHub Actionschạy workflowCI/CD.- Workflow tạo file nén chứa mã nguồn và thư mục
.github/deployment. - GitHub dùng
SSHđể chép file nén lên server. - Server tự tạo thư mục release mới, nối
storage,.env,.env.admin, rồi chạy các bước cài đặt. - Khi mọi thứ xong, server đổi liên kết
currentsang bản mới và giữ lại 5 bản gần nhất để dễ quay lại nếu cần.
Bước 1: Chuẩn bị những gì
Bạn nên có sẵn các thông tin sau trước khi bắt đầu:
- quyền truy cập vào repository GitHub của dự án
- quyền tạo
SecretsvàVariablestrong GitHub repository - quyền SSH vào server
- domain chạy website và domain chạy admin
- thông tin database
- thông tin mail, Redis, lưu trữ file nếu dự án có dùng
Về phần mềm trên server, nên kiểm tra trước:
PHPđúng phiên bản đang khai báo trong workflow, hiện file mẫu dùng8.3ComposerNode.jsvàpnpm- gói
aclđể có lệnhsetfacl - web server như
nginxhoặcapache - dịch vụ chạy nền như
supervisorhoặc giải pháp tương đương
Điểm quan trọng cần nhớ
Trong bộ script hiện tại, các bước build dùng pnpm được chạy trực tiếp trên server. Điều này áp dụng cho phần frontend gốc của dự án và cả admin nếu thư mục admin có tồn tại. Vì vậy server phải có sẵn Node.js và pnpm.
Bước 2: Đưa mã nguồn lên GitHub
Nếu dự án chưa có repository:
- Tạo repository mới trên GitHub.
- Đưa toàn bộ source code của dự án lên repository đó.
- Tạo ít nhất 2 nhánh làm việc là
devvàmainnếu bạn muốn tách môi trường thử nghiệm và môi trường chính thức.
Nếu dự án đã có repository, bạn chỉ cần kiểm tra lại:
- nhánh
devdùng cho môi trường thử nghiệm - nhánh
maindùng cho môi trường chính thức - thư mục
.githubđã có trong source code hay chưa
Bước 3: Chép workflow và deployment scripts vào dự án
Trong thư mục deployment/build-script đang có sẵn bộ file mẫu. Bạn cần chép chúng vào source code của dự án như sau:
- Chép file
deployment/build-script/workflows/ci-cd.ymlvào.github/workflows/ci-cd.yml. - Chép cả thư mục
deployment/build-script/deploymentvào.github/deployment/.
Sau khi chép xong, cấu trúc tối thiểu của repo nên có:
.github/
workflows/
ci-cd.yml
deployment/
prepare.sh
deploy.sh
hooks/
before-activation.sh
after-activation.sh
flush-opcache.sh
set-file-permissions.sh
Bước 4: Kiểm tra file workflow trước khi dùng
Workflow mẫu hiện chạy khi có push vào dev và main. Bạn cần rà lại vài chỗ quan trọng:
PHP_VERSIONđang để8.3- job
deploy-devtrong file mẫu vẫn dùng đường dẫn placeholder/var/www/[domain_folder] - job
deploy-maindùng biếnDOMAIN_FOLDER
Điều này có nghĩa là bạn nên sửa file workflow trước khi dùng thật:
- thay placeholder của
deploy-devthành đường dẫn thực tế - hoặc chuẩn hóa cả
devvàmainđể cùng đọc từGitHub Variables
Ví dụ dễ hiểu:
- thư mục gốc của dự án trên server là
/var/www/ten-du-an - vậy
base_directoryphải là/var/www/ten-du-an - không được điền
/var/www/ten-du-an/current
prepare.sh có kiểm tra điều này và sẽ báo lỗi nếu bạn trỏ thẳng vào thư mục current.
Bước 5: Tạo tài khoản deploy trên server
Nên dùng một tài khoản riêng để GitHub đăng nhập vào server, ví dụ deploy, githubconnector hoặc tên tương tự. Không nên dùng root nếu không thật sự cần.
Tài khoản này cần:
- có quyền vào thư mục dự án
- có quyền chạy
php,composer,pnpm - thuộc cùng nhóm với user đang phục vụ web, thường là
www-datahoặcnginx
Ví dụ thêm user deploy vào nhóm web server:
sudo usermod -aG www-data deploy
Bước 6: Tạo SSH key để GitHub đăng nhập vào server
Bạn cần một cặp khóa:
private key: lưu ở GitHub Secretspublic key: lưu trong~/.ssh/authorized_keyscủa user deploy trên server
Ví dụ tạo khóa:
ssh-keygen -t ed25519 -C "github-actions-deploy"
Sau đó:
- Mở file private key và chép toàn bộ nội dung vào GitHub Secret
SSH_PRIVATE_KEY. - Mở file public key và thêm vào
~/.ssh/authorized_keyscủa user deploy trên server.
Lỗi rất hay gặp
Không dán public key vào SSH_PRIVATE_KEY. Script prepare.sh có kiểm tra và sẽ dừng nếu thấy khóa bạn nhập trông giống public key.
Bước 7: Tạo known hosts
known hosts là danh sách máy chủ mà GitHub được phép tin tưởng khi SSH vào. Nếu không có phần này, GitHub có thể từ chối kết nối hoặc kết nối mà không kiểm tra danh tính server.
Lấy giá trị này bằng lệnh:
ssh-keyscan -p 22 -H your-server.com
Nếu server dùng cổng khác, thay 22 bằng cổng thật. Toàn bộ kết quả trả về sẽ được dán vào GitHub Secret SSH_KNOWN_HOSTS.
Bước 8: Khai báo Secrets và Variables trên GitHub
Trong repository, vào Settings -> Secrets and variables -> Actions.
Tạo các Secrets sau:
REMOTE_USER: user deploy trên serverREMOTE_HOST: IP hoặc domain của serverREMOTE_PORT: cổng SSHSSH_PRIVATE_KEY: private key vừa tạoSSH_KNOWN_HOSTS: giá trị lấy bằngssh-keyscan
Tạo các Variables sau nếu bạn dùng workflow giống file mẫu:
DOMAIN_FOLDER: tên thư mục gốc của dự án trên server, ví dụten-du-an
Sau đó workflow sẽ ghép thành:
/var/www/${DOMAIN_FOLDER}
Bước 9: Chuẩn bị thư mục gốc trên server
Với cách deploy hiện tại, mỗi dự án nên có một thư mục gốc riêng, ví dụ:
/var/www/ten-du-an
Ngay từ đầu, bạn nên tạo các thành phần cơ bản:
sudo mkdir -p /var/www/ten-du-an/config
sudo mkdir -p /var/www/ten-du-an/storage
sudo chown -R deploy:www-data /var/www/ten-du-an
sudo chmod -R 2775 /var/www/ten-du-an
Sau lần deploy đầu tiên, cấu trúc sẽ dần có dạng:
/var/www/ten-du-an
.env
.env.admin
config/
setting.php
modules_statuses.json
storage/
releases/
1/
2/
current -> /var/www/ten-du-an/releases/2
Nếu server cũ của bạn đang dùng kiểu shared/storage và shared/.env giống Deployer, script hiện tại cũng tự nhận ra và dùng lại cấu trúc đó.
Bước 10: Tạo file .env trên server
File .env phải nằm ở thư mục gốc dự án và không được để trống. Nếu file rỗng, deploy.sh sẽ dừng ngay.
Ví dụ vị trí:
/var/www/ten-du-an/.env
Những nhóm giá trị bạn cần điền tối thiểu:
- thông tin ứng dụng:
APP_NAME,APP_ENV,APP_KEY,APP_URL,APP_DEBUG - domain và session:
APP_DOMAIN,ASSET_URL,SESSION_DOMAIN,SANCTUM_STATEFUL_DOMAINS - ngôn ngữ và múi giờ:
DEFAULT_LOCALE,TIMEZONE - database:
DB_CONNECTION,DB_HOST,DB_PORT,DB_DATABASE,DB_USERNAME,DB_PASSWORD - cache, queue, session:
CACHE_DRIVER,QUEUE_CONNECTION,SESSION_DRIVER,REDIS_* - xác thực nội bộ:
ISPA_API_AUTH_KEY,ISPA_ADMIN_AUTH_KEY - email:
MAIL_*nếu dự án có gửi thư - lưu trữ file:
AWS_*nếu dùng object storage
Các biến rất hay ảnh hưởng đến đăng nhập:
APP_URLSESSION_DOMAINSANCTUM_STATEFUL_DOMAINSISPA_ADMIN_AUTH_KEY
Nếu bạn dùng admin ở subdomain riêng, hãy điền các biến trên theo đúng domain thật. Điền sai ở đây thường gây lỗi đăng nhập, lỗi cookie hoặc lỗi gọi API.
Bước 11: Tạo file .env.admin trên server
File này dành riêng cho admin frontend và cũng không được để trống.
Ví dụ vị trí:
/var/www/ten-du-an/.env.admin
Các biến thường cần điền:
VITE_DOMAIN: domain của adminVITE_BASE_URL: địa chỉ API backend mà admin sẽ gọi tớiVITE_PROTOCOL: thường làhttpsVITE_NODE_ENV: môi trường chạyVITE_DEFAULT_LOCALE: ngôn ngữ mặc địnhVITE_APP_ADMIN_AUTH_KEY: phải khớp với khóa admin ở backendVITE_SECURE_COOKIE: bật khi dùng HTTPS
Hai biến cần hiểu đúng:
VITE_BUILD_VERSION: script deploy sẽ tự cập nhật theo thời gian build, bạn không cần gán tay cố địnhVITE_APP_ADMIN_AUTH_KEY: phải tương thích vớiISPA_ADMIN_AUTH_KEYở backend
Bước 12: Chuẩn bị config/setting.php
Nếu dự án có file config/setting.php dùng cho cấu hình riêng, hãy đặt file này tại:
/var/www/ten-du-an/config/setting.php
Nếu lần đầu deploy mà file này chưa có:
- script sẽ cố lấy từ bản release trước nếu có
- nếu không có release cũ, script sẽ dùng file đi kèm trong source code
Điều này giúp setting.php được giữ ổn định giữa các lần deploy.
Bước 13: Cấu hình phân quyền file và thư mục
Phần này rất quan trọng nếu bạn muốn upload ảnh, ghi log, tạo cache và chạy queue ổn định.
Theo hook deployment/build-script/deployment/hooks/set-file-permissions.sh, hệ thống mong đợi:
- user deploy và user web server thuộc cùng một group
- server có lệnh
setfacl - thư mục cần ghi có quyền
0775
Bạn nên kiểm tra:
sudo apt install acl
id deploy
id www-data
Nếu user deploy chưa cùng group với web server:
sudo usermod -aG www-data deploy
Ngoài ra, hook cũng kiểm tra config/filesystems.php. Hai disk local và public cần để quyền thư mục là 0775. Nếu để sai, script có thể dừng để tránh lỗi upload về sau.
Bước 14: Cấu hình web server
Bạn cần trỏ domain về đúng thư mục public của bản đang chạy:
/var/www/ten-du-an/current/public
Trong thư mục deployment hiện có nhiều file .conf mẫu cho nginx để bạn tham khảo cách:
- trỏ domain chính
- trỏ domain admin hoặc frontend riêng
- phục vụ file trong
/storage - bật HTTPS
Nếu bạn đang dùng nginx, điểm quan trọng nhất là luôn trỏ website PHP/Laravel vào current/public, không trỏ thẳng vào một thư mục release cụ thể.
Bước 15: Cấu hình queue và schedule
CMS muốn chạy ổn định thì gần như luôn cần tiến trình nền. Trong thư mục deployment đang có sẵn các file queue-*.conf và schedule-*.conf để làm mẫu.
Ý nghĩa của từng loại:
queue: xử lý việc chạy nền như gửi mail, đồng bộ dữ liệu, tác vụ nặngschedule: chạy các công việc theo lịch
Ví dụ trong file mẫu:
- queue chạy
artisan queue:work - schedule chạy
artisan schedule:work
Sau khi chép file .conf vào supervisor, bạn thường cần chạy:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status
Nếu dự án có queue riêng như gpt_caller, bạn cũng cần bật worker riêng cho queue đó giống file mẫu.
Bước 16: Push code để chạy deploy đầu tiên
Sau khi đã hoàn tất các phần trên:
- Commit các file
.github/workflows/ci-cd.ymlvà.github/deployment/*. - Push code lên nhánh
devhoặcmain. - Mở tab
Actionstrên GitHub để xem workflow chạy.
Nếu mọi thứ đúng, script sẽ tự làm các việc sau:
- chép artifact lên server
- tạo thư mục release mới
- nối
storage,.env,.env.admin,setting.php - cài
composer - chạy migration
- chạy migration cho module
- đồng bộ permission và translation của CMS
- build admin bằng
pnpm - chuyển
currentsang release mới - flush
OPCache - xóa các release cũ, chỉ giữ lại 5 bản gần nhất
Một chi tiết dễ gây hoang mang
Sau khi build admin xong, script hiện tại xóa thư mục admin khỏi release mới. Đây là hành vi bình thường của script mẫu. Nếu bạn vào thư mục release mà không thấy admin, không có nghĩa là deploy bị lỗi.
Bước 17: Kiểm tra sau khi deploy
Sau lần chạy đầu tiên, bạn nên kiểm tra ngay:
- Mở website ngoài xem có vào được không.
- Mở admin xem có đăng nhập được không.
- Tạo thử một bản ghi hoặc upload một ảnh để kiểm tra phân quyền ghi file.
- Kiểm tra trang
Dashboardvà các module chính. - Kiểm tra log trong
storage/logs. - Kiểm tra
supervisorctl statusđể chắc queue và schedule đang chạy.
Các lỗi thường gặp và cách hiểu nhanh
GitHub báo không SSH vào được server
Thường là một trong ba lỗi sau:
REMOTE_HOSThoặcREMOTE_PORTsaiSSH_PRIVATE_KEYkhông đúng private keySSH_KNOWN_HOSTSchưa đúng
Workflow báo .env hoặc .env.admin rỗng
Script deploy dừng nếu các file này có tồn tại nhưng không có nội dung. Hãy điền đủ cấu hình rồi chạy lại.
Workflow báo không tìm thấy Composer
Server chưa cài Composer, hoặc user deploy không thấy lệnh composer trong môi trường shell.
Workflow báo lỗi phân quyền
Thường do:
- chưa cài
acl - user deploy chưa cùng group với web server
- thư mục
storagehoặc thư mục dự án chưa có quyền ghi phù hợp
Workflow báo không kết nối được database
Hook before-activation.sh có bước chờ database sẵn sàng rồi mới migrate. Nếu nó thất bại, hãy kiểm tra lại DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD.
Workflow báo lỗi flush OPCache
Script này gọi theo APP_URL. Nếu APP_URL sai domain, sai protocol hoặc web server chưa trả về đúng site, bước flush OPCache có thể thất bại.
Gợi ý bàn giao cho người không chuyên kỹ thuật
Khi bàn giao hệ thống, bạn nên chuẩn bị sẵn một checklist ngắn:
- repository GitHub ở đâu
- ai có quyền xem
Actions - user nào dùng để SSH deploy
.envđang nằm ở đâu trên server.env.adminđang nằm ở đâu trên server- cách xem queue và schedule có đang chạy hay không
- cách kiểm tra bản deploy mới nhất trong thư mục
releases
Như vậy, kể cả người tiếp quản không rành code vẫn có thể lần theo đúng chỗ để kiểm tra.

