【运维进阶】LNMP + WordPress 自动化部署实验
LNMP + WordPress 自动化部署实验
一、实验目标
通过 Ansible 自动化工具,在目标服务器(lnmp
主机组)上搭建 LNMP 架构(Linux 系统 + Nginx 网页服务器 + MariaDB 数据库 + PHP 脚本语言),并部署 WordPress 博客系统,最终实现通过浏览器访问博客。
二、前置知识说明
术语 / 工具 | 作用说明 |
---|---|
Ansible | 自动化运维 “管家”,靠 YAML 剧本批量干活,目标机无需装客户端,轻量又方便。 |
LNMP | Web 架构 “铁三角”:Nginx 接请求、PHP 算动态、MariaDB 存数据,撑起网站运行。 |
MariaDB | 开源数据库 “备胎转正”(MySQL 分支),专门存 WordPress 的文章、用户等数据。 |
Nginx | 轻量网页 “门卫”,负责接请求、秀静态页面,还能把动态活儿转给 PHP 处理。 |
PHP-FPM | PHP 的 “包工头”,管理进程处理 Nginx 转来的动态请求,让代码跑起来。 |
WordPress | 博客建站 “神器”,搭好 LNMP 就能用,小白也能轻松发文章、做网站。 |
Ansible Vault | Ansible 的 “密码保险箱”,给数据库密码等敏感信息加密,防止泄露。 |
三、实验环境准备
角色 | 主机名 | 系统 | 核心软件 | IP 地址(示例) |
---|---|---|---|---|
控制节点(执行命令) | controller | CentOS 7 | Ansible、LNMP 配置文件 | 10.1.8.10 |
目标节点(部署服务) | node1(属于 lnmp 组) | CentOS 7 | 无(Ansible 自动安装软件) | 10.1.8.11 |
客户端(访问博客) | 个人电脑 | Windows 10/11 | 浏览器 | - |
四、详细部署流程
1. 初始化控制节点工作目录(存放配置文件)
# 把原有 web 目录复制一份,命名为 lnmp,作为本次实验的 “工作目录”(所有配置文件都放在这里,不影响其他文件)。
[lth@controller ~ 22:00:38]$ cp -r web lnmp# 进入 lnmp 工作目录,后续所有命令都在这个目录下执行。
[lth@controller ~ 22:00:45]$ cd lnmp/# 删除 lnmp 目录里所有原文件,避免旧文件干扰本次实验,保证环境 “干净”。
[lth@controller lnmp 22:01:02]$ rm -rf *# 从上级目录web拷贝两个关键文件到当前lnmp目录
[lth@controller lnmp 22:01:21]$ cp ../web/ansible.cfg .
[lth@controller lnmp 22:01:26]$ cp ../web/inventory .
2. 准备变量文件
# 创建变量目录
[lth@controller lnmp 22:01:34]$ mkdir host_vars
[lth@controller lnmp 22:01:36]$ mkdir host_vars/lnmp# 编写敏感变量文件
[lth@controller lnmp 22:01:52]$ vim host_vars/lnmp/vaults.yml
[lth@controller lnmp 22:02:16]$ cat host_vars/lnmp/vaults.ymlmysql_root_password: 123app_user: wordpressapp_password: 123app_host: '%'app_priv: '*.*:ALL'
每个配置项是什么意思?
配置项 | 含义 | 作用 |
---|---|---|
mysql_root_password: 123 | MariaDB 数据库的 root 密码(最高权限密码) | 用于初始化数据库、创建用户和库 |
app_user: wordpress | 给 WordPress 用的数据库用户名 | WordPress 只能用这个用户操作数据库,避免用 root 提权风险 |
app_password: 123 | WordPress 数据库用户的密码 | 验证 WordPress 对数据库的访问权限 |
app_host: ‘%’ | 允许该用户从 “任意主机” 连接数据库 | 这里是本地部署,% 表示目标机自身可以访问 |
app_priv: ‘.:ALL’ | 该用户拥有 “所有数据库、所有权限” | 让 WordPress 能创建表、插入数据(实际生产可缩小权限,实验简化用 ALL) |
这些是敏感信息(密码),后续要加密保护,不能明文暴露。
# 编写普通变量文件
[lth@controller lnmp 22:02:29]$ vim host_vars/lnmp/vars.yml
[lth@controller lnmp 22:02:31]$ cat host_vars/lnmp/vars.yml
db_name: webapp
# db_name: webapp 表示给 WordPress 专门创建的数据库名是 webapp。# 加密敏感变量文件
[lth@controller lnmp 22:02:46]$ ansible-vault encrypt host_vars/lnmp/vaults.ymlNew Vault password: '123'Confirm New Vault password: '123'Encryption successful# 创建解密密码文件
[lth@controller lnmp 22:14:21]$ echo 123 > secret.txt# 验证加密文件能否正常解密
[lth@controller lnmp 22:14:26]$ ansible-vault view host_vars/lnmp/vaults.yml
3. 准备核心配置文件(Ansible 剧本、Nginx/PHP 配置)
# 编写 Ansible 主配置文件
[lth@controller lnmp 22:16:12]$ vim ansible.cfg
[lth@controller lnmp 22:16:14]$ cat ansible.cfg
[defaults]
remote_user = lth
inventory = ./inventory
#gathering = explicit
vault_password_file=./secret.txt
#roles_path = ./roles
#collections_paths = ./collections[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
# 关键注意点:目标节点必须配置 lth 用户的 sudo 免密(否则 Ansible 执行安装命 令会失败),配置方法:在目标机 node1 上执行 visudo,添加 lth ALL=(ALL) NOPASSWD: ALL。# 编写 PHP 配置文件(让 Nginx 能处理 PHP 请求)
[lth@controller lnmp 22:16:25]$ vim php.conf
[lth@controller lnmp 22:16:27]$ cat php.conf
location ~ \.php$ {try_files $uri =404;fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;
}# 编写 WordPress 虚拟主机模板(让 Nginx 识别博客域名)
[lth@controller lnmp 22:21:55]$ vim vhost-wordpress.conf.j2
[lth@controller lnmp 22:21:59]$ cat vhost-wordpress.conf.j2
server {listen 80;server_name {{ blog_vhost }};root /usr/share/nginx/html/{{ blog_vhost }}/wordpress;index index.php;# Load configuration files for the default server block.include /etc/nginx/default.d/*.conf;# log fileaccess_log /var/log/nginx/access-{{ blog_vhost }}.log;error_log /var/log/nginx/error-{{ blog_vhost }}.log;
}# 本地安装 Nginx
[lth@controller lnmp 22:22:51]$ sudo yum install -y nginx
4. 编写 Ansible 核心剧本
# 创建并编辑部署剧本
[lth@controller lnmp 22:25:44]$ vim deploy_lnmp.yml
内容如下:
--
- name: deploy mariadbhosts: lnmptasks:# 安装数据库- name: install mariadb-serveryum:name: - mariadb-server- python2-PyMySQLstate: present# 启动服务- name: enable and start mariadbservice:name: mariadbenabled: yesstate: started# 设置 root 密码- name: set root@localhost passwordshell: mysqladmin password {{ mysql_root_password }}ignore_errors: yes- name: set root passwordmysql_user:name: rootpassword: "{{ mysql_root_password }}"host: "{{ item }}"state: presentlogin_user: rootlogin_password: "{{ mysql_root_password }}"with_items:- "{{ ansible_fqdn }}"- 127.0.0.1- ::1# 删除匿名用户- name: delete user anonymousmysql_user:name: ""host_all: yesstate: absentlogin_user: rootlogin_password: "{{ mysql_root_password }}"#login_unix_socket: /var/lib/mysql/mysql.sock# 删除测试数据库- name: delete database testmysql_db:name: teststate: absentlogin_user: rootlogin_password: "{{ mysql_root_password }}"- name: prepare db for webapphosts: lnmptasks:# 创建新用户- name: create user {{ user }}mysql_user:name: "{{ app_user }}"password: "{{ app_password }}"host: "{{ app_host }}"priv: "{{ app_priv }}"state: presentlogin_user: rootlogin_password: "{{ mysql_root_password }}"# 创建新库- name: create database db_namemysql_db:name: "{{ db_name }}"state: presentlogin_user: rootlogin_password: "{{ mysql_root_password }}"- name: deploy web serverhosts: lnmptasks:- name: install nginxyum:name: nginxstate: present# 启动服务- name: enable and start nginxservice:name: nginxenabled: yesstate: started- name: prepare test file for web servercopy:content: hello world from nginxdest: /usr/share/nginx/html/index.html- name: phphosts: lnmptasks:- name: install phpyum:name: php,php-fpm,php-mysqlndstate: present- name: modify running user for phplineinfile:path: /etc/php-fpm.d/www.confregexp: "{{ item}} = "line: "{{ item }} = nginx"loop:- user- group# 启动服务- name: enable and start php-fpm.serviceservice:name: php-fpmenabled: yesstate: restarted- name: config php for nginxcopy:src: php.confdest: /etc/nginx/default.d/php.conf- name: restart nginxservice:name: nginxstate: restarted- name: deploy web apphosts: lnmpvars:blog_vhost: blog.xiexin.cloudtasks:- name: prepare vhost for wordpresstemplate:src: vhost-wordpress.conf.j2dest: /etc/nginx/conf.d/vhost-wordpress.conf- name: create /usr/share/nginx/html/{{ blog_vhost }}file:path: /usr/share/nginx/html/{{ blog_vhost }}state: directory- name: Unarchive a wordpress file unarchive:src: wordpress-4.9.4-zh_CN.zipdest: /usr/share/nginx/html/{{ blog_vhost }}/owner: nginxgroup: nginx- name: restart nginxservice:name: nginxstate: restarted
剧本关键注意点:
-
必须提前下载 wordpress-4.9.4-zh_CN.zip 到控制节点的 lnmp 目录(下载地址:https://wordpress.org/wordpress-4.9.4-zh_CN.zip);
-
剧本按 “数据库→Web 服务器→PHP→博客” 顺序执行,不能乱序(比如先装 PHP 再装数据库,PHP 连接数据库会失败)。
5. 执行自动化部署
# 执行剧本
[lth@controller lnmp 22:30:15]$ ansible-playbook deploy_lnmp.yml
PLAY [deploy mariadb] ***************************************************************************TASK [Gathering Facts] **************************************************************************
ok: [lnmp]TASK [install mariadb-server] *******************************************************************
ok: [lnmp]TASK [enable and start mariadb] *****************************************************************
ok: [lnmp]
........# 关闭目标机冲突服务(避免端口被占)
[root@node1 ~ 22:30:24]# systemctl disable httpd --now
6. 验证部署结果(确保每个组件都正常)
# 在node1上执行,查看WordPress文件是否存在
[root@node1 ~ 22:30:29]$ ls /usr/share/nginx/html/blog.xiexin.cloud/wordpress/index.php wp-admin wp-content wp-load.php wp-signup.phplicense.txt wp-blog-header.php wp-cron.php wp-login.php wp-trackback.phpreadme.html wp-comments-post.php wp-includes wp-mail.php xmlrpc.phpwp-activate.php wp-config-sample.php wp-links-opml.php wp-settings.php# 如果失败:检查 Ansible 剧本中 “解压 WordPress” 的任务是否成功,或压缩包是否在控制节点的 `lnmp` 目录。# 继续在node1上执行,查看文件权限(确保所有者是nginx)[root@node1 ~ 22:30:38]$ ll /usr/share/nginx/html/blog.xiexin.cloud/wordpress/
# 验证 MariaDB 数据库是否正常(目标节点 node1)
# 在node1上执行,用WordPress专用用户登录数据库
[root@node1 ~ 22:36:50]# mysql -uwordpress -p123
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 5.5.68-MariaDB MariaDB ServerCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [(none)]> # 登录后执行,查看数据库列表
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| webapp |
+--------------------+
4 rows in set (0.01 sec)
# 如果没有 webapp 库:检查 Ansible 剧本中 “创建数据库” 的任务是否成功。# 退出数据库
MariaDB [(none)]> exit
Bye
7. 浏览器访问博客(完成 WordPress 安装)
1. 配置 Windows 客户端 Hosts(让浏览器识别博客域名)
-
打开 Windows 文件管理器,进入路径:C:\Windows\System32\drivers\etc;
-
找到 hosts 文件,右键用 “记事本” 打开(需管理员权限,否则无法保存);
-
在文件末尾添加一行:10.1.8.11 blog.xiexin.cloud;
-
保存并关闭文件。
2. 访问 WordPress 并完成安装
-
打开浏览器(Chrome、Edge 等),在地址栏输入 blog.xiexin.cloud,按回车;
-
进入 WordPress 安装向导,选择 “中文”,点击 “继续”;
-
点击 “现在就开始!”,填写数据库信息(和vaults.yml、vars.yml一致):
-
数据库名:webapp
-
用户名:wordpress
-
密码:123
-
数据库主机:localhost(本地数据库,不用改)
-
表前缀:默认 wp_(不用改)
-
点击 “提交”,再点击 “运行安装程序”;
-
填写博客信息(自定义):
-
站点标题:blog
-
用户名:xiexin
-
密码:123
-
电子邮件:xiexin@123.com
-
点击 “安装 WordPress”,安装完成后用刚才的用户名密码登录;
-
登录后进入博客后台,或点击 “访问站点” 查看博客首页,至此实验完成!
结果截图:
五、常见问题排查
问题现象 | 可能原因 | 解决方法 |
---|---|---|
执行剧本时 “yum 安装软件失败” | 目标节点网络不通,或 yum 源有问题 | 1. 在 node1 上 ping 百度(ping baidu.com)确认网络; 2. 更换 yum 源为阿里云(yum install -y wget && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo) |
浏览器访问 blog.xiexin.cloud 显示 “无法访问” | 1. 目标节点 Nginx 没启动; 2. 客户端 Hosts 配置错误; 3. 防火墙拦截 80 端口 | 1. 在 node1 上执行 systemctl status nginx 确认 Nginx 已启动; 2. 检查 Windows Hosts 配置的 IP 和域名是否正确; 3. 在 node1 上关闭防火墙(systemctl stop firewalld && systemctl disable firewalld) |
WordPress 安装时 “无法连接数据库” | 1. 数据库密码输错; 2. MariaDB 没启动; 3. 数据库用户权限不够 | 1. 确认密码和 vaults.yml 一致; 2. 在 node1 上执行 systemctl status mariadb 确认数据库已启动; 3. 检查剧本中 app_priv 是否为 .:ALL |
访问 PHP 文件显示 “下载文件” 而非执行 | Nginx 的 PHP 配置没生效,或 PHP-FPM 没启动 | 1. 在 node1 上执行 systemctl status php-fpm 确认 PHP-FPM 已启动; 2. 检查 /etc/nginx/default.d/php.conf 文件是否存在且内容正确 |
六、总结
这个实验就像请了个叫 Ansible 的 “全能管家”,把搭建博客的活儿全承包了!先给它搭好 “工作台”(控制节点和目标节点),藏好数据库密码这些 “私房钱”(敏感信息加密),再写好 “工作指南”(配置文件和剧本)。
接着管家就按流程开工:先装数据库 MariaDB 当 “储物间”,再摆上 Nginx 这扇 “大门”,请来 PHP-FPM 当 “计算器” 处理动态请求,最后把 WordPress 这 “博客家具” 搬进去摆好。
完事还得检查检查:门有没有锁好(服务状态)、地址标没标对(客户端 Hosts),确认无误后,就能舒舒服服在浏览器里给新博客 “剪彩” 啦 —— 全程不用自己动手拧一颗螺丝,这自动化部署可太省心了!