使用Ansible自动化部署WordPress
本文详解如何使用Ansible自动化部署WordPress,包括Playbook编写、角色管理和多环境配置。
为什么使用Ansible
| 方式 | 问题 | Ansible优势 |
|---|---|---|
| 手动部署 | 易出错、不可复现 | 幂等性、可重复执行 |
| Shell脚本 | 无状态管理、难回滚 | 状态感知、支持回滚 |
| Docker | 学习曲线陡 | 贴近原生、易调试 |
环境准备
安装Ansible
# Ubuntu/Debian
sudo apt update
sudo apt install -y ansible
# CentOS/RHEL
sudo yum install -y epel-release
sudo yum install -y ansible
# 验证安装
ansible --version
配置Inventory
# hosts.ini
[webservers]
192.168.1.10 ansible_user=deployer
192.168.1.11 ansible_user=deployer
[dbservers]
192.168.1.20 ansible_user=deployer
[staging]
staging.example.com ansible_user=deployer
[production]
prod1.example.com ansible_user=deployer
prod2.example.com ansible_user=deployer
[all:vars]
ansible_python_interpreter=/usr/bin/python3
基础Playbook结构
目录结构
wordpress-ansible/
├── ansible.cfg
├── hosts.ini
├── site.yml
├── group_vars/
│ ├── all.yml
│ ├── staging.yml
│ └── production.yml
├── host_vars/
│ └── prod1.example.com.yml
└── roles/
├── common/
├── nginx/
├── php/
├── mysql/
└── wordpress/
ansible.cfg配置
[defaults]
inventory = hosts.ini
remote_user = deployer
host_key_checking = False
retry_files_enabled = False
stdout_callback = yaml
[privilege_escalation]
become = True
become_method = sudo
become_user = root
编写Roles
Common角色(基础环境)
# roles/common/tasks/main.yml
---
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Install basic packages
package:
name:
- vim
- curl
- git
- unzip
- python3
- python3-pip
state: present
- name: Set timezone to Asia/Shanghai
timezone:
name: Asia/Shanghai
- name: Configure NTP
service:
name: ntp
state: started
enabled: yes
Nginx角色
# roles/nginx/tasks/main.yml
---
- name: Add Nginx repository (CentOS)
yum_repository:
name: nginx
description: Nginx repo
baseurl: http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck: no
when: ansible_os_family == "RedHat"
- name: Install Nginx
package:
name: nginx
state: present
- name: Configure Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx
- name: Remove default site
file:
path: /etc/nginx/sites-enabled/default
state: absent
when: ansible_os_family == "Debian"
- name: Start and enable Nginx
service:
name: nginx
state: started
enabled: yes
{# roles/nginx/templates/nginx.conf.j2 #}
user {{ nginx_user }};
worker_processes {{ ansible_processor_vcpus }};
events {
worker_connections 1024;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
{# 这里留空,由具体的站点配置填充 #}
server {
listen 80 default_server;
server_name _;
return 444;
}
}
PHP角色
# roles/php/tasks/main.yml
---
- name: Add PHP PPA (Ubuntu)
apt_repository:
repo: ppa:ondrej/php
when: ansible_distribution == "Ubuntu"
- name: Install PHP and extensions
package:
name:
- php{{ php_version }}
- php{{ php_version }}-fpm
- php{{ php_version }}-mysql
- php{{ php_version }}-curl
- php{{ php_version }}-gd
- php{{ php_version }}-mbstring
- php{{ php_version }}-xml
- php{{ php_version }}-zip
- php{{ php_version }}-opcache
state: present
- name: Configure PHP-FPM pool
template:
src: www.conf.j2
dest: "/etc/php/{{ php_version }}/fpm/pool.d/www.conf"
notify: Restart PHP-FPM
- name: Start and enable PHP-FPM
service:
name: "php{{ php_version }}-fpm"
state: started
enabled: yes
MySQL角色
# roles/mysql/tasks/main.yml
---
- name: Install MySQL
package:
name:
- mysql-server
- python3-pymysql
state: present
- name: Start MySQL
service:
name: mysql
state: started
enabled: yes
- name: Create WordPress database
mysql_db:
name: "{{ wp_db_name }}"
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: Create WordPress user
mysql_user:
name: "{{ wp_db_user }}"
password: "{{ wp_db_password }}"
priv: "{{ wp_db_name }}.*:ALL"
host: localhost
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
WordPress角色
# roles/wordpress/tasks/main.yml
---
- name: Download WordPress
get_url:
url: https://wordpress.org/latest.tar.gz
dest: /tmp/wordpress.tar.gz
mode: 0644
- name: Extract WordPress
unarchive:
src: /tmp/wordpress.tar.gz
dest: /tmp/
remote_src: yes
- name: Create web root
file:
path: "{{ wp_root }}"
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}"
mode: 0755
- name: Copy WordPress files
copy:
src: /tmp/wordpress/
dest: "{{ wp_root }}"
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}"
remote_src: yes
- name: Configure wp-config.php
template:
src: wp-config.php.j2
dest: "{{ wp_root }}/wp-config.php"
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}"
mode: 0640
- name: Configure Nginx site for WordPress
template:
src: wordpress-site.conf.j2
dest: "/etc/nginx/sites-available/{{ wp_site_name }}.conf"
notify: Restart Nginx
- name: Enable Nginx site
file:
src: "/etc/nginx/sites-available/{{ wp_site_name }}.conf"
dest: "/etc/nginx/sites-enabled/{{ wp_site_name }}.conf"
state: link
notify: Restart Nginx
主Playbook
# site.yml
---
- name: Deploy WordPress to web servers
hosts: webservers
become: yes
roles:
- common
- nginx
- php
- wordpress
- name: Configure database
hosts: dbservers
become: yes
roles:
- common
- mysql
变量管理
group_vars/all.yml
---
nginx_user: www-data
php_version: "8.2"
wp_root: /var/www/html
wp_site_name: wordpress
group_vars/production.yml
---
wp_db_name: wp_production
wp_db_user: wp_user
wp_db_password: "{{ vault_wp_db_password }}" # 存在Ansible Vault里
wp_site_url: https://www.example.com
执行部署
测试连通性
ansible all -m ping
执行部署(Staging)
ansible-playbook site.yml -l staging -e env=staging --check # 干跑测试
ansible-playbook site.yml -l staging -e env=staging # 实际执行
执行部署(Production)
ansible-playbook site.yml -l production -e env=production
使用Ansible Vault加密敏感数据
# 创建加密文件
ansible-vault create group_vars/production.yml
# 编辑加密文件
ansible-vault edit group_vars/production.yml
# 执行时指定vault密码文件
ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt
回滚方案
# roles/wordpress/tasks/rollback.yml
---
- name: List available backups
find:
paths: "{{ wp_root }}/../backups"
patterns: "wp-backup-*.tar.gz"
file_type: file
register: backups
- name: Restore from latest backup
unarchive:
src: "{{ (backups.files | sort(attribute='mtime') | last).path }}"
dest: "{{ wp_root }}/../"
remote_src: yes
when: backups.matched > 0
notify: Restart Nginx
常用调试命令
# 测试特定task
ansible-playbook site.yml --start-at-task="Install Nginx"
# 限制执行主机
ansible-playbook site.yml -l "192.168.1.10"
# 使用详细输出
ansible-playbook site.yml -vvv
# 检查语法
ansible-playbook site.yml --syntax-check
最佳实践
- 使用Roles组织代码:便于复用和分享
- 敏感数据用Vault加密:密码、API Key不能明文
- 多环境配置分离:staging/production用不同的group_vars
- 先--check再执行:干跑测试避免意外
- 版本控制Playbook:用Git管理,配合CI/CD
目录结构最终版
wordpress-ansible/
├── ansible.cfg
├── hosts.ini
├── site.yml
├── requirements.yml # Galaxy依赖
├── group_vars/
│ ├── all.yml
│ ├── staging.yml
│ └── production.yml
├── host_vars/
│ └── prod1.example.com.yml
├── roles/
│ ├── common/
│ ├── nginx/
│ ├── php/
│ ├── mysql/
│ └── wordpress/
└── vault.yml.gpg # GPG加密的vault文件
通过Ansible自动化部署,可以将部署时间从2小时缩短到10分钟,同时大幅降低人为错误。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)