Automate LNMP Deployment with Ansible Playbooks: Step‑by‑Step Guide
This tutorial walks through installing Ansible on CentOS, preparing inventory and SSH keys, creating variable files, and writing a comprehensive Ansible playbook that automates the installation and configuration of Nginx, MySQL, and PHP on multiple hosts, complete with service setup and verification.
Install Ansible
Configure the Alibaba yum repository, install the EPEL release package, and then install Ansible on a CentOS 8 system.
/etc/yum.repos.d# rm -rf *
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
yum install -y https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
sed -i 's|^#baseurl=https://download.example/pub|baseurl=https://mirrors.aliyun.com|' /etc/yum.repos.d/epel*
sed -i 's|^metalink|#metalink|' /etc/yum.repos.d/epel*
cd / && dnf -y install platform-python
dnf -y install centos-release-ansible
dnf -y install ansible --nobest
ansible --versionPrepare Basic Environment with Ansible
Create an inventory file, map host IPs to groups, generate SSH keys, copy the public key to each managed host, and verify connectivity. Also disable firewalld and SELinux on the control node.
# vim /etc/hosts
127.0.0.1 localhost
192.168.222.137 nginx
192.168.222.138 mysql
192.168.222.139 php
mkdir playdemo && cd playdemo
cp /etc/ansible/ansible.cfg .
vim ansible.cfg # set inventory = /etc/ansible/hosts
vim inventory # define groups and hosts
ansible all --list-hosts
ssh-keygen -t rsa
ssh-copy-id 192.168.222.137
ssh-copy-id 192.168.222.138
ssh-copy-id 192.168.222.139
ansible all -m ping
systemctl stop firewalld.service
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
setenforce 0
systemctl disable --now firewalld.serviceWrite Playbook
Create a playbook directory, add lnmp.yml, and define tasks to stop firewalld, disable SELinux, install and configure Nginx, MySQL, and PHP, copy service files, set PATH variables, and start the services.
# mkdir playbook && cd playbook
vim lnmp.yml
---
- name: nginx mysql php stop firewalld and selinux
hosts: all
tasks:
- name: stop firewalld
service:
name: firewalld.service
state: stopped
enabled: no
- name: Ensure SELinux is disabled
lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: SELINUX=disabled
- name: install nginx
vars_files:
- ../var/dir.yml
- ../var/hos.yml
- ../var/package.yml
hosts: "{{ host_ip['nginx'] }}"
tasks:
- name: create nginx user
user:
name: nginx
system: yes
shell: /sbin/nologin
create_home: no
state: present
- name: copy nginx tarball
copy:
src: "{{ url_dir }}{{ package['nginx'] }}.tar.gz"
dest: "{{ dow_dir }}"
- name: unarchive nginx
unarchive:
src: "{{ dow_dir }}{{ package['nginx'] }}.tar.gz"
dest: "{{ una_dir }}"
remote_src: yes
- name: install build dependencies
yum:
name: pcre-devel,openssl,openssl-devel,gd-devel,make,gcc,gcc-c++,wget
state: present
- name: configure nginx
shell: |
cd {{ una_dir }}{{ package['nginx'] }} && \
./configure --prefix={{ ins_dir['nginx'] }} \
--user=nginx --group=nginx --with-debug \
--with-http_ssl_module --with-http_realip_module \
--with-http_image_filter_module --with-http_gunzip_module \
--with-http_gzip_static_module --with-http_stub_status_module
- name: make and install nginx
shell: |
cd {{ una_dir }}{{ package['nginx'] }} && \
make -j $(grep -c processor /proc/cpuinfo) && \
make install
- name: set nginx PATH
copy:
dest: /etc/profile.d/nginx.sh
content: "export PATH=$PATH:{{ ins_dir['nginx'] }}/sbin"
- name: create nginx service file
copy:
dest: /usr/lib/systemd/system/nginx.service
content: |
[Unit]
Description=nginx server daemon
After=network.target
[Service]
Type=forking
ExecStart={{ ins_dir['nginx'] }}/sbin/nginx
ExecStop={{ ins_dir['nginx'] }}/sbin/nginx -s stop
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
- name: modify nginx configuration
copy:
dest: "{{ ins_dir['nginx'] }}/conf/nginx.conf"
content: |
user nginx;
worker_processes 1;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / { root html; index index.php; }
error_page 500 502 503 504 /50x.html;
location = /50x.html { root html; }
location ~ \.php$ {
root /var/www;
fastcgi_pass {{ host_ip['php'] }}:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
- name: create index.php
file:
path: "{{ ins_dir['nginx'] }}/html/index.php"
state: touch
- name: start nginx
service:
name: nginx.service
state: restarted
enabled: yes
# (Similar blocks for MySQL and PHP are defined below, using the same variable files and host groups.)Use Variables
Define three variable files ( dir.yml, hos.yml, package.yml) that store directory paths, host IP mappings, and package names, then reference them in the playbook with Jinja2 syntax.
# dir.yml
url_dir: ../package/
dow_dir: /usr/local/src/
una_dir: /usr/src/
ins_dir:
nginx: /usr/local/nginx
mysql: /usr/local/mysql
php: /usr/local/php
# hos.yml
host_ip:
nginx: 192.168.222.137
mysql: 192.168.222.138
php: 192.168.222.139
# package.yml
package:
nginx: nginx-1.22.0
mysql: mysql-5.7.38-linux-glibc2.12-x86_64
php: php-8.1.11After running ansible-playbook playbook/lnmp.yml -vv, the playbook reports successful execution on all three hosts, with tasks marked as ok and changed, confirming that Nginx, MySQL, and PHP are installed, configured, and running.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
