【运维进阶】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. 初始化控制节点工作目录(存放配置文件)
bash 复制代码
# 把原有 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. 准备变量文件
bash 复制代码
# 创建变量目录
[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.yml
 mysql_root_password: 123
 app_user: wordpress
 app_password: 123
 app_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)

这些是敏感信息(密码),后续要加密保护,不能明文暴露。

bash 复制代码
# 编写普通变量文件
[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.yml
 New 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 配置)
bash 复制代码
# 编写 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 file
    access_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 核心剧本
bash 复制代码
# 创建并编辑部署剧本
[lth@controller lnmp 22:25:44]$ vim deploy_lnmp.yml

内容如下:

yaml 复制代码
--
- name: deploy mariadb
  hosts: lnmp
  tasks:
    # 安装数据库
    - name: install mariadb-server
      yum:
        name: 
          - mariadb-server
          - python2-PyMySQL
        state: present

    # 启动服务
    - name: enable and start mariadb
      service:
       name: mariadb
       enabled: yes
       state: started

    # 设置 root 密码
    - name: set root@localhost password
      shell: mysqladmin password {{ mysql_root_password }}
      ignore_errors: yes

    - name: set root password
      mysql_user:
        name: root
        password: "{{ mysql_root_password }}"
        host: "{{ item }}"
        state: present
        login_user: root
        login_password: "{{ mysql_root_password }}"
      with_items:
        - "{{ ansible_fqdn }}"
        - 127.0.0.1
        - ::1
    
  # 删除匿名用户
    - name: delete user anonymous
      mysql_user:
        name: ""
        host_all: yes
        state: absent
        login_user: root
        login_password: "{{ mysql_root_password }}"
        #login_unix_socket: /var/lib/mysql/mysql.sock


    # 删除测试数据库
    - name: delete database test
      mysql_db:
        name: test
        state: absent
        login_user: root
        login_password: "{{ mysql_root_password }}"


- name: prepare db for webapp
  hosts: lnmp
  tasks:
    # 创建新用户
    - name: create user {{ user }}
      mysql_user:
        name: "{{ app_user }}"
        password: "{{ app_password }}"
        host: "{{ app_host }}"
        priv: "{{ app_priv }}"
        state: present
        login_user: root
        login_password: "{{ mysql_root_password }}"

    # 创建新库
    - name: create database db_name
      mysql_db:
        name: "{{ db_name }}"
        state: present
        login_user: root
        login_password: "{{ mysql_root_password }}"

- name: deploy web server
  hosts: lnmp
  tasks:
    - name: install nginx
      yum:
        name: nginx
        state: present
    # 启动服务
    - name: enable and start nginx
      service:
       name: nginx
       enabled: yes
       state: started
    - name: prepare test file for web server
      copy:
        content: hello world from nginx
        dest: /usr/share/nginx/html/index.html

- name: php
  hosts: lnmp
  tasks:
    - name: install php
      yum:
        name: php,php-fpm,php-mysqlnd
        state: present
    - name: modify running user for php
      lineinfile:
        path: /etc/php-fpm.d/www.conf
        regexp: "{{ item}} = "
        line: "{{ item }} = nginx"
      loop:
        - user
        - group
    # 启动服务
    - name: enable and start php-fpm.service
      service:
       name: php-fpm
       enabled: yes
       state: restarted
    - name: config php for nginx
      copy:
        src: php.conf
        dest: /etc/nginx/default.d/php.conf
    - name: restart nginx
      service:
       name: nginx
       state: restarted

- name: deploy web app
  hosts: lnmp
  vars:
    blog_vhost: blog.xiexin.cloud
  tasks:
    - name: prepare vhost for wordpress
      template:
        src: vhost-wordpress.conf.j2
        dest: /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.zip
        dest: /usr/share/nginx/html/{{ blog_vhost }}/
        owner: nginx
        group: nginx
    - name: restart nginx
      service:
       name: nginx
       state: restarted

剧本关键注意点:

  • 必须提前下载 wordpress-4.9.4-zh_CN.zip 到控制节点的 lnmp 目录(下载地址:https://wordpress.org/wordpress-4.9.4-zh_CN.zip);

  • 剧本按 "数据库→Web 服务器→PHP→博客" 顺序执行,不能乱序(比如先装 PHP 再装数据库,PHP 连接数据库会失败)。

5. 执行自动化部署
bash 复制代码
# 执行剧本
[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. 验证部署结果(确保每个组件都正常)
bash 复制代码
# 在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.php
 license.txt      wp-blog-header.php    wp-cron.php        wp-login.php     wp-trackback.php
 readme.html      wp-comments-post.php  wp-includes        wp-mail.php      xmlrpc.php
 wp-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/
bash 复制代码
# 验证 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 Server

Copyright (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(让浏览器识别博客域名)
  1. 打开 Windows 文件管理器,进入路径:C:\Windows\System32\drivers\etc;

  2. 找到 hosts 文件,右键用 "记事本" 打开(需管理员权限,否则无法保存);

  3. 在文件末尾添加一行:10.1.8.11 blog.xiexin.cloud;

  4. 保存并关闭文件。

2. 访问 WordPress 并完成安装
  1. 打开浏览器(Chrome、Edge 等),在地址栏输入 blog.xiexin.cloud,按回车;

  2. 进入 WordPress 安装向导,选择 "中文",点击 "继续";

  3. 点击 "现在就开始!",填写数据库信息(和vaults.yml、vars.yml一致):

  4. 数据库名:webapp

  5. 用户名:wordpress

  6. 密码:123

  7. 数据库主机:localhost(本地数据库,不用改)

  8. 表前缀:默认 wp_(不用改)

  9. 点击 "提交",再点击 "运行安装程序";

  10. 填写博客信息(自定义):

  11. 站点标题:blog

  12. 用户名:xiexin

  13. 密码:123

  14. 电子邮件:xiexin@123.com

  15. 点击 "安装 WordPress",安装完成后用刚才的用户名密码登录;

  16. 登录后进入博客后台,或点击 "访问站点" 查看博客首页,至此实验完成!

结果截图:

五、常见问题排查

问题现象 可能原因 解决方法
执行剧本时 "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),确认无误后,就能舒舒服服在浏览器里给新博客 "剪彩" 啦 ------ 全程不用自己动手拧一颗螺丝,这自动化部署可太省心了!

相关推荐
许泽宇的技术分享5 分钟前
Windows桌面自动化的革命性突破:深度解析Windows-MCP.Net Desktop模块的技术奥秘
windows·自动化·.net
正在努力的小河1 小时前
Linux设备树简介
linux·运维·服务器
荣光波比1 小时前
Linux(十一)——LVM磁盘配额整理
linux·运维·云计算
未来之窗软件服务1 小时前
蔬菜批发小程序:生产商的数字化转型利器——仙盟创梦IDE
小程序·自动化·仙盟创梦ide·东方仙盟·蔬菜批发·批发系统
小晶晶京京1 小时前
day35-负载均衡
运维·网络·网络协议·学习·负载均衡
LLLLYYYRRRRRTT1 小时前
WordPress (LNMP 架构) 一键部署 Playbook
linux·架构·ansible·mariadb
大路谈数字化3 小时前
Centos中内存CPU硬盘的查询
linux·运维·centos
小小码农一只4 小时前
Python 爬虫实战:玩转 Playwright 跨浏览器自动化(Chromium/Firefox/WebKit 全支持)
爬虫·python·自动化
赏点剩饭7785 小时前
linux中的hostpath卷、nfs卷以及静态持久卷的区别
linux·运维·服务器