Cài Nginx, PHP, MariaDB trên Ubuntu 24.04 (LEMP) từng bước
Hướng dẫn cài nginx php mariadb trên Ubuntu 24.04 và Debian 12: tường lửa, PHP-FPM, server block, database, SSL Let's Encrypt và các lỗi bảo mật hay gặp.

Ý chính
- Ubuntu 24.04 có sẵn nginx 1.24, PHP 8.3 và MariaDB 10.11 trong kho chính thức.
- nginx chuyển file PHP cho PHP-FPM qua Unix socket /run/php/php8.3-fpm.sock.
- Mỗi website nên có user Linux và pool PHP-FPM riêng để một site bị hack không đọc được site khác.
- Luôn mở cổng SSH trong UFW trước khi bật tường lửa.
Để cài nginx, PHP và MariaDB (LEMP) trên Ubuntu 24.04, bạn chỉ cần kho gói chính thức: apt install nginx mariadb-server php8.3-fpm php8.3-mysql, chạy mariadb-secure-installation, rồi tạo server block nginx chuyển file .php tới socket /run/php/php8.3-fpm.sock. Toàn bộ quá trình mất khoảng 20 phút trên một VPS mới, kể cả cấp SSL miễn phí.
Bài viết đi qua từng bước với lệnh đã kiểm tra trên Ubuntu 24.04 (và ghi chú khác biệt cho Debian 12), giải thích vì sao mỗi bước tồn tại, và chỉ ra những chỗ mà hướng dẫn ngắn thường bỏ qua: tường lửa, quyền file, pool PHP riêng cho từng website. Cuối bài là phần so sánh khi nào nên tự cài và khi nào nên dùng control panel.
Cài nginx, PHP, MariaDB trên Ubuntu: LEMP là gì, vì sao chọn nginx?
LEMP gồm Linux, Engine-X (nginx), MariaDB (hoặc MySQL) và PHP. Khác với LAMP dùng Apache với mod_php, nginx không chạy PHP bên trong tiến trình web server. Nó phục vụ file tĩnh rất nhanh và chuyển request PHP cho PHP-FPM, một dịch vụ riêng quản lý các worker PHP.
Cách tách này có hai lợi ích thực tế: nginx dùng ít RAM khi có nhiều kết nối đồng thời, và mỗi website có thể chạy PHP dưới user Linux riêng. Nhược điểm: nginx không đọc .htaccess, nên quy tắc rewrite phải viết trong cấu hình nginx.
Ubuntu 24.04 và Debian 12 có sẵn phiên bản nào?
| Thành phần | Ubuntu 24.04 | Debian 12 |
|---|---|---|
| nginx | 1.24 | 1.22 |
| PHP | 8.3 | 8.2 |
| MariaDB | 10.11 | 10.11 |
Các nhánh phiên bản trên cố định trong suốt vòng đời bản phát hành; bản vá bảo mật được backport. Kiểm tra chính xác trên server bằng apt policy nginx mariadb-server php8.3-fpm. Nếu cần nhiều phiên bản PHP cùng lúc, bạn phải thêm kho ngoài (PPA của Ondřej Surý trên Ubuntu, packages.sury.org trên Debian); bài này chỉ dùng kho chính thức.
Trên Debian 12, thay mọi chỗ 8.3 trong bài bằng 8.2.
Bước 1: Cập nhật hệ thống và bật tường lửa
Đăng nhập VPS bằng user có sudo và chạy:
sudo apt update && sudo apt full-upgrade -y
Bật tường lửa UFW, mở SSH trước tiên:
sudo apt install ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
Nếu SSH của bạn chạy ở cổng khác 22, đổi số cho đúng. Bật UFW mà quên cổng SSH là cách nhanh nhất để tự khoá mình khỏi server; khi đó chỉ còn console của nhà cung cấp VPS cứu được. Với các bước bảo mật khác cho server mới, xem hướng dẫn bảo mật VPS Ubuntu.
Bước 2: Cài nginx
sudo apt install nginx
sudo systemctl enable --now nginx
curl -I http://localhost
Dòng HTTP/1.1 200 OK cho biết nginx đã chạy. Mở http://IP-của-VPS trên trình duyệt sẽ thấy trang chào mặc định.
Bước 3: Cài MariaDB và bảo mật ban đầu
sudo apt install mariadb-server
sudo mariadb-secure-installation
Trình hướng dẫn hỏi vài câu. Trên Ubuntu và Debian, user root của MariaDB mặc định xác thực bằng unix_socket, nghĩa là chỉ root của hệ điều hành (qua sudo mariadb) đăng nhập được, không cần mật khẩu. Đây là thiết lập an toàn, hãy giữ nguyên. Trả lời Y cho các câu xoá user ẩn danh, cấm root đăng nhập từ xa, xoá database test.
MariaDB mặc định chỉ lắng nghe trên 127.0.0.1. Đừng mở cổng 3306 ra internet; nếu cần kết nối từ xa, dùng SSH tunnel hoặc chỉ cho phép đúng IP của bạn.
Tạo database và user cho website (mỗi website một user riêng):
sudo mariadb -e "CREATE DATABASE example_wp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'example_wp'@'localhost' IDENTIFIED BY 'đổi-mật-khẩu-mạnh';
GRANT ALL PRIVILEGES ON example_wp.* TO 'example_wp'@'localhost';"
Bước 4: Cài PHP-FPM và extension cần thiết
sudo apt install php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd \
php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl
sudo systemctl status php8.3-fpm
Danh sách extension trên đủ cho WordPress và phần lớn ứng dụng PHP phổ biến. OPcache được cài sẵn cùng PHP-FPM. Đừng cài gói php8.3 không kèm hậu tố: trên một số hệ thống nó kéo theo Apache và libapache2-mod-php, khiến Apache tranh cổng 80 với nginx.
Chỉnh vài giá trị trong /etc/php/8.3/fpm/php.ini nếu ứng dụng cần:
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
Rồi sudo systemctl reload php8.3-fpm.
Bước 5: Tạo server block nginx cho website
Tạo thư mục website và file cấu hình:
sudo mkdir -p /var/www/example.com/public
sudo nano /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.(?!well-known) {
deny all;
}
}
snippets/fastcgi-php.conf có sẵn trong gói nginx của Ubuntu/Debian và lo phần tham số FastCGI. Khối cuối chặn file ẩn như .env, .git nhưng vẫn cho Let's Encrypt dùng .well-known.
Kích hoạt và kiểm tra:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Luôn chạy nginx -t trước khi reload. Một dấu chấm phẩy thiếu có thể làm nginx không khởi động lại được, kéo theo mọi website trên server. Tham khảo thêm tài liệu nginx.
Bước 6: Kiểm tra PHP chạy đúng
echo '<?php phpinfo();' | sudo tee /var/www/example.com/public/info.php
curl -s http://localhost/info.php -H 'Host: example.com' | grep -m1 'PHP Version'
sudo rm /var/www/example.com/public/info.php
Xoá info.php ngay sau khi kiểm tra: trang này để lộ cấu hình server cho bất kỳ ai.
Bước 7: Cài SSL miễn phí với Let's Encrypt
Trỏ bản ghi A của example.com và www.example.com về IP của VPS, rồi:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run
Certbot sửa server block để thêm HTTPS và chuyển hướng HTTP sang HTTPS, đồng thời tạo timer gia hạn tự động. Xem thêm hướng dẫn của Certbot và bài về SSL Let's Encrypt.
Bước 8: Tách quyền khi có nhiều website
Cấu hình mặc định ở trên chạy PHP của mọi website dưới cùng user www-data. Với một website thì ổn. Với nhiều website, đó là lỗ hổng lớn nhất của LEMP tự cài: một plugin bị hack trên site A đọc được wp-config.php của site B, vì cùng một user.
Cách khắc phục là mỗi website một user Linux và một pool PHP-FPM riêng:
sudo adduser --system --group --no-create-home --home /var/www/example.com example
sudo chown -R example:example /var/www/example.com/public
sudo cp /etc/php/8.3/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/example.conf
Trong example.conf, đổi [www] thành [example], user = example, group = example, listen = /run/php/php8.3-fpm-example.sock, giữ listen.owner = www-data và listen.group = www-data để nginx kết nối được. Sau đó trỏ fastcgi_pass của server block sang socket mới, reload PHP-FPM và nginx. Đặt quyền thư mục 750 và cân nhắc open_basedir cho từng pool.
Làm việc này cho mười website thì vẫn được. Làm cho một trăm website, cùng giới hạn CPU/RAM, quota đĩa, sao lưu và gia hạn SSL, thì đó chính là công việc của một control panel.
Tự cài LEMP hay dùng control panel?
| Tiêu chí | Tự cài LEMP | Control panel (ví dụ ZoPanel) |
|---|---|---|
| Hiểu sâu hệ thống | Rất tốt | Ít phải đụng tới |
| Thời gian thêm một website | 10–20 phút | Khoảng 1 phút |
| Cách ly giữa các website | Tự làm từng pool, từng user | Có sẵn cho mọi tài khoản |
| Nhiều phiên bản PHP | Tự thêm kho, tự quản lý | Chọn trong danh sách |
| Sao lưu, SSL, giám sát | Tự viết script, cron | Có sẵn trong giao diện |
| Phù hợp | 1–3 website, người thích tự kiểm soát | Agency, nhà cung cấp hosting, nhiều website |
ZoPanel cài chính bộ LEMP này: nginx, MariaDB, PHP từ kho của Ondřej Surý (PHP 7.4 đến 8.4), kèm UFW, Fail2ban và SFTP chroot. Bộ đệm InnoDB của MariaDB được đặt bằng 20% RAM. Mỗi tài khoản hosting là một user Linux riêng, với pool PHP-FPM riêng có open_basedir, và chạy trong slice systemd riêng có giới hạn CPU, RAM, số tiến trình lấy từ gói hosting. Pool của website không có truy cập tự ngủ để tiết kiệm RAM. Cài trên Ubuntu 22.04/24.04 hoặc Debian 12/13 bằng một lệnh:
curl -fsSL https://get.zopanel.net | sudo bash
Trình cài đặt yêu cầu server mới, chưa có web server hay panel khác, nên đừng chạy nó trên server bạn vừa tự cài LEMP. Xem hướng dẫn cài đặt, thành phần tuỳ chọn và cách tạo website và chọn phiên bản PHP.
Lỗi thường gặp khi cài LEMP
- 502 Bad Gateway: nginx không kết nối được PHP-FPM. Kiểm tra
fastcgi_passcó đúng tên socket không (ls /run/php/) và PHP-FPM có đang chạy. - Trình duyệt tải file .php về thay vì chạy: thiếu khối
location ~ \.php$hoặc chưa reload nginx. - 404 cho mọi trang trừ trang chủ (WordPress, Laravel): thiếu
try_files ... /index.php?$args. - Access denied for user: sai mật khẩu database hoặc user được tạo với host khác
localhost. - Apache chiếm cổng 80: đã lỡ cài gói
php8.3. Gỡ Apache bằngsudo apt purge apache2(kiểm tra trước là không có gì đang dùng nó). - Certbot báo lỗi xác thực: DNS chưa trỏ đúng, hoặc tường lửa của nhà cung cấp VPS chưa mở cổng 80.
Kết luận
Cài LEMP trên Ubuntu 24.04 không khó: kho chính thức đã có nginx 1.24, PHP 8.3 và MariaDB 10.11, đủ cho phần lớn ứng dụng PHP hiện nay. Phần đáng giá nhất của việc tự cài là hiểu cách nginx, PHP-FPM và MariaDB phối hợp với nhau. Phần tốn công nhất là giữ cho nhiều website cách ly, được sao lưu và luôn có SSL. Nếu bạn đến điểm đó, hãy thử gói Free của ZoPanel (3 tài khoản hosting, 10 website, 10 database, không giới hạn thời gian, chạy được nhiều phiên bản PHP) trên một VPS mới, và xem bảng giá khi cần nhiều hơn.
Câu hỏi thường gặp
Ubuntu 24.04 dùng PHP phiên bản mấy?
Kho chính thức của Ubuntu 24.04 có PHP 8.3, gói php8.3-fpm. Debian 12 có PHP 8.2. Nếu cần phiên bản khác, phải thêm kho ngoài như PPA của Ondřej Surý.
Nên dùng MariaDB hay MySQL cho LEMP?
Cả hai đều chạy tốt WordPress và phần lớn ứng dụng PHP. MariaDB có sẵn trong kho của Ubuntu và Debian và là lựa chọn mặc định của nhiều bản phân phối, nên cài và cập nhật đơn giản hơn. Chỉ chọn MySQL khi ứng dụng yêu cầu tính năng riêng của MySQL.
Vì sao nginx báo 502 Bad Gateway sau khi cài PHP?
Thường do fastcgi_pass trỏ sai socket hoặc PHP-FPM chưa chạy. Chạy ls /run/php/ để xem tên socket thật và systemctl status php8.3-fpm để kiểm tra dịch vụ, rồi sửa server block và reload nginx.
Có cần mở cổng 3306 của MariaDB không?
Không, nếu website và database nằm cùng server. Mở 3306 ra internet khiến database bị dò mật khẩu liên tục. Khi cần kết nối từ xa, dùng SSH tunnel hoặc chỉ cho phép đúng địa chỉ IP của bạn trong tường lửa.
Cài LEMP xong có cài thêm control panel được không?
Phần lớn control panel, gồm ZoPanel, yêu cầu server mới và từ chối cài khi đã có web server khác, vì sẽ xung đột cấu hình. Hãy cài panel trên VPS mới, rồi chuyển website sang.
Đọc tiếp

Chạy nhiều phiên bản PHP trên một server: hướng dẫn PHP-FPM
Cách chạy nhiều phiên bản PHP trên một server Ubuntu hoặc Debian với PHP-FPM: cài song song, gán phiên bản cho từng website, xử lý CLI, cron và lỗi thường gặp.

Cách trỏ tên miền về VPS: bản ghi A, nameserver và kiểm tra DNS
Hướng dẫn trỏ tên miền về VPS từng bước: tạo bản ghi A, AAAA, www, đổi nameserver, giữ email không gián đoạn, kiểm tra bằng dig và cài SSL ngay sau đó.

Deploy Laravel lên VPS: queue, scheduler và cập nhật không gián đoạn
Cách deploy Laravel lên VPS Ubuntu 24.04: PHP-FPM, nginx, .env, queue worker, scheduler và release không downtime, làm tay hoặc với ZoPanel.