LEMP là bộ Linux, Nginx (đọc là "engine-x"), MariaDB hoặc MySQL và PHP. Đây là nền tảng phổ biến để chạy WordPress trên VPS. Bài này hướng dẫn bạn cài đặt toàn bộ trên Ubuntu 24.04, tạo database riêng cho WordPress và cấu hình Nginx đúng cách. Cuối bài là các lỗi thường gặp như 502 Bad Gateway, 403 Forbidden và cách sửa.

Bạn cần chuẩn bị:

  • VPS Ubuntu 24.04 đã bảo mật cơ bản, có user sudo (ví dụ deploy).
  • Tối thiểu 1 GB RAM. Nếu ít RAM, nên tạo swap trước.
  • Tên miền example.com đã trỏ bản ghi A về 203.0.113.10.
  • UFW đã mở cổng 80 và 443.

Bước 1: Cài Nginx

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx

Mở trình duyệt vào http://203.0.113.10. Nếu thấy trang "Welcome to nginx!" là đã chạy. Nếu không vào được, kiểm tra tường lửa:

sudo ufw allow 'Nginx Full'
sudo ufw status

Bước 2: Cài MariaDB và bảo mật

sudo apt install -y mariadb-server
sudo systemctl enable --now mariadb
sudo mariadb-secure-installation

Script bảo mật sẽ hỏi một loạt câu. Gợi ý trả lời:

  • Enter current password for root: nhấn Enter (chưa có mật khẩu).
  • Switch to unix_socket authentication: n (root đã dùng unix_socket sẵn).
  • Change the root password: n nếu bạn chỉ đăng nhập root qua sudo mariadb.
  • Remove anonymous users, Disallow root login remotely, Remove test database, Reload privilege tables: Y.

Bước 3: Tạo database và user cho WordPress

Mỗi website nên có database và user riêng. Nếu một site bị xâm nhập, kẻ tấn công không đọc được dữ liệu site khác.

sudo mariadb
CREATE DATABASE wp_example CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'MatKhauRatManh_2026';
GRANT ALL PRIVILEGES ON wp_example.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Thay mật khẩu mẫu bằng chuỗi ngẫu nhiên. Bạn có thể tạo bằng openssl rand -base64 24.

Bước 4: Cài PHP-FPM và các extension WordPress cần

Trên Ubuntu 24.04, gói php-fpm sẽ cài PHP 8.3. Danh sách extension dưới đây đáp ứng yêu cầu của WordPress và các plugin phổ biến.

sudo apt install -y php-fpm php-mysql php-curl php-gd php-intl php-mbstring php-xml php-zip php-imagick php-bcmath
php -v
systemctl status php8.3-fpm

Tăng giới hạn upload và bộ nhớ để cài theme, plugin không bị lỗi. Tạo file cấu hình riêng thay vì sửa php.ini gốc:

sudo nano /etc/php/8.3/fpm/conf.d/99-wordpress.ini
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 120
sudo systemctl restart php8.3-fpm

Bước 5: Tải WordPress

sudo mkdir -p /var/www/example.com
cd /tmp
curl -O https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
sudo cp -a /tmp/wordpress/. /var/www/example.com/
sudo chown -R www-data:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;

Bước 6: Cấu hình server block Nginx

Server block tương đương virtual host bên Apache. Tạo file mới:

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;
    index index.php index.html;

    client_max_body_size 64M;

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

    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 ~* \.(css|js|jpg|jpeg|png|gif|webp|svg|ico|woff2?)$ {
        expires 30d;
        access_log off;
    }

    location ~ /\.(?!well-known) {
        deny all;
    }

    location = /xmlrpc.php {
        deny all;
    }
}

Dòng try_files thay cho quy tắc rewrite trong .htaccess, giúp permalink đẹp hoạt động. Khối /\.(?!well-known) chặn truy cập file ẩn như .git, .env nhưng vẫn cho phép thư mục .well-known mà Certbot cần. Nếu bạn dùng ứng dụng di động hoặc Jetpack cần XML-RPC, hãy bỏ khối xmlrpc.php.

Kích hoạt site và tắt site mặc định:

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

Bước 7: Hoàn tất cài WordPress

Truy cập http://example.com. Trình cài đặt sẽ hỏi thông tin database:

TrườngGiá trị
Database Namewp_example
Usernamewp_user
PasswordMật khẩu ở bước 3
Database Hostlocalhost
Table Prefixwp_ hoặc tiền tố tùy chọn

Sau khi cài xong, thêm dòng sau vào wp-config.php (trên dòng "That's all, stop editing!") để WordPress ghi file trực tiếp, không hỏi FTP:

define( 'FS_METHOD', 'direct' );

Bước 8: Chạy WP-Cron bằng cron hệ thống

Mặc định WordPress chạy tác vụ định kỳ (đăng bài hẹn giờ, gửi email, dọn dữ liệu) mỗi khi có người truy cập. Site ít khách thì tác vụ bị trễ, site đông khách thì tốn tài nguyên vô ích. Cách ổn định hơn là tắt cơ chế này và để cron của hệ thống gọi định kỳ. Thêm vào wp-config.php:

define( 'DISABLE_WP_CRON', true );

Sau đó mở crontab của user www-data:

sudo crontab -u www-data -e

Thêm dòng sau để chạy mỗi 5 phút bằng PHP CLI, không đi qua Nginx:

*/5 * * * * cd /var/www/example.com && /usr/bin/php wp-cron.php >/dev/null 2>&1

OPcache đã được bật sẵn trong gói PHP-FPM của Ubuntu. Bạn có thể kiểm tra bằng php -i | grep opcache.enable (kết quả của CLI) hoặc xem trong Site Health của WordPress.

Bước tiếp theo là cài SSL Let's Encrypt để chạy HTTPS.

Kiểm tra lại

  • sudo nginx -t báo syntax is ok và test is successful.
  • systemctl is-active nginx php8.3-fpm mariadb trả về ba dòng active.
  • Vào Settings, Permalinks, chọn "Post name". Mở một bài viết. Nếu không lỗi 404 thì try_files đúng.
  • Thử truy cập http://example.com/.htaccess hoặc /.git/config: phải trả về 403.
  • Vào Tools, Site Health để xem WordPress có báo thiếu extension PHP nào không.

Lỗi thường gặp và cách xử lý

502 Bad Gateway

Nginx không kết nối được PHP-FPM. Kiểm tra PHP-FPM có chạy không và đường dẫn socket trong fastcgi_pass có khớp không:

systemctl status php8.3-fpm
ls -l /run/php/
sudo tail -n 30 /var/log/nginx/example.com.error.log

Nếu log có dòng connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory), socket sai tên hoặc PHP-FPM chưa chạy.

Trình duyệt tải file PHP về thay vì chạy

Khối location ~ \.php$ bị thiếu hoặc sai. Kiểm tra lại server block, chạy sudo nginx -t rồi reload. Xóa cache trình duyệt trước khi thử lại.

403 Forbidden ở trang chủ

Thường do thiếu index.php trong chỉ thị index, hoặc quyền thư mục sai. Kiểm tra bằng namei -l /var/www/example.com/index.php để xem từng cấp thư mục có quyền đọc không.

Error establishing a database connection

Thông tin trong wp-config.php sai, hoặc MariaDB không chạy. Thử đăng nhập trực tiếp: mariadb -u wp_user -p wp_example. Nếu đăng nhập được thì lỗi nằm ở file cấu hình.

413 Request Entity Too Large khi upload

Tăng client_max_body_size trong Nginx và upload_max_filesize, post_max_size trong PHP cho bằng nhau, rồi reload cả hai dịch vụ.