Site logo
Tác giả
  • avatar Nguyễn Đức Xinh
    Name
    Nguyễn Đức Xinh
    Twitter
Ngày xuất bản
Ngày xuất bản

Triển khai LEMP Stack với Ansible: Hướng dẫn deploy NGINX + PHP-FPM + MySQL từ A-Z

🚀 Triển khai NGINX + PHP-FPM + MySQL bằng Ansible

Series: Ansible từ Zero đến Hero – Thực chiến Deploy Web Stack

Trong bài này, chúng ta sẽ triển khai một stack web phổ biến trên Linux server:

NGINX – Web server ✔ PHP-FPM – Xử lý PHP ✔ MySQL – Database

Bằng Ansible, chúng ta có thể tự động hóa toàn bộ quá trình.


🎯 Mục tiêu bài học

Sau bài này, bạn sẽ biết cách:

🔧 Cài đặt NGINX, PHP-FPM, MySQL bằng Ansible 📁 Cấu hình Virtual Host NGINX từ template Jinja2 💾 Tạo database và user trong MySQL ♻️ Restart service bằng Handlers 🏗 Viết một playbook triển khai hoàn chỉnh


🧱 Chuẩn bị

Inventory (hosts):

[web]
192.168.1.10

[db]
192.168.1.11

Thư mục playbook:

deploy-lamp/
 ├─ site.yml
 ├─ templates/
 │   └─ nginx.conf.j2
 └─ group_vars/
    ├─ web.yml
    └─ db.yml

⚙️ Biến theo môi trường

group_vars/web.yml

server_name: "example.local"
document_root: "/var/www/app/public"
php_packages:
  - php8.1
  - php8.1-fpm
  - php8.1-mysql

group_vars/db.yml

db_name: "appdb"
db_user: "appuser"
db_pass: "StrongPass123"

📝 Template NGINX (templates/nginx.conf.j2)

server {
    listen 80;
    server_name {{ server_name }};

    root {{ document_root }};
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

🧪 Playbook triển khai (site.yml)

---
- hosts: web
  become: yes
  tasks:

    - name: Cài NGINX  PHP
      apt:
        name: "{{ item }}"
        state: present
        update_cache: yes
      loop:
        - nginx
        - "{{ php_packages }}"

    - name: Tạo thư mục web
      file:
        path: "{{ document_root }}"
        state: directory
        owner: www-data
        group: www-data
        mode: "0755"

    - name: Copy cấu hình NGINX
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: Restart NGINX

  handlers:
    - name: Restart NGINX
      service:
        name: nginx
        state: restarted


- hosts: db
  become: yes
  tasks:

    - name: Cài MySQL Server
      apt:
        name: mysql-server
        state: present
        update_cache: yes

    - name: Tạo database
      mysql_db:
        name: "{{ db_name }}"
        state: present

    - name: Tạo user  phân quyền
      mysql_user:
        name: "{{ db_user }}"
        password: "{{ db_pass }}"
        priv: "{{ db_name }}.*:ALL"
        state: present

▶️ Thực thi

Chạy playbook:

ansible-playbook -i hosts site.yml

Nếu mọi thứ OK, bạn có thể upload code PHP vào thư mục:

/var/www/app/public

Ví dụ file index.php thử nghiệm:

<?php phpinfo(); ?>

Mở trình duyệt:

👉 http://example.local Nếu thấy trang phpinfo() → Deploy thành công 🎉


📌 Tổng kết kiến thức

Thành phần Mục tiêu
NGINX + PHP-FPM Serve web app PHP
MySQL Database cho ứng dụng
Template Jinja2 Sinh file cấu hình động
group_vars Quản lý biến theo nhóm server
Handlers Restart services khi config thay đổi

Bài này là nền tảng để:

  • 🚀 Deploy Laravel / WordPress
  • 🚀 Triển khai CI/CD tự động
  • 🚀 Xây dựng server production chuẩn

🎁 Bài tập thực hành

Hãy nâng cấp playbook để:

  • 🔹 Cài đặt UFW firewall và mở port 22, 80, 443
  • 🔹 Triển khai HTTPS với Certbot
  • 🔹 Tạo user deploy + SSH key