[Linux / Apache] 使用单条命令行构建 WordPress 网站并启用 SSL!如何使用 Apache + WP-CLI 创建自动化脚本

介绍
好久不见!
个女生🐤,也是一名工程师。虽然我
自称是新手,但其实已经工作三年了……
总之,我最近对编写脚本产生了兴趣。
所以,
我写了一个脚本,只需一条命令就能创建一个用于测试的 WordPress 网站,而这在验证过程中总是会耗费大量时间!
关于剧本
概述
这个脚本一个自动化脚本,可以一次性完成从搭建新的 WordPress 网站到启用 SSL 的所有操作。
它自动完成了耗时费力的网络服务器设置过程,使网站上线变得轻松便捷。
■ 主要处理流程(执行细节)
|
* 如果对同一域多次运行脚本,则已配置的项目将自动跳过,并且
只会处理未配置或已更新的项目。
先决条件/环境
此脚本是基于以下测试环境设计的:
| 物品 | 条件/环境 |
| 操作系统 | AlmaLinux 10.1 |
| 数据库 | MySQL 8.4.8 |
| Web服务器 | Apache + PHP-FPM |
| 执行用户 | 根 |
| DNS 设置 | 目标域的 A 记录必须指向相关的服务器。 |
| 所需工具 | WP-CLI、Certbot、MySQL 客户端 |
即使由于 DNS 未传播等原因导致证书获取(步骤 8)失败,也只会跳过证书获取步骤,并 应用 HTTP 环境设置,然后构建网站本身。
(通过在 HTTPS 配置中应用默认虚拟证书来防止错误✨)
在这种情况下,您仍然可以在 DNS 设置和传播完成后重新运行相同的流程,以执行证书获取和 SSL 实现!
源代码
脚本在此!
不过,它比较长,而且详细的处理过程可能难以理解,所以我会在下一节中进行解释。
#!/bin/bash # =================================================== # 个性化设置(请根据您的环境进行更改) # =================================================== # --- 数据库连接信息 --- DB_HOST="数据库 IP 地址或 localhost" DB_ADMIN_USER="数据库管理员用户名" DB_ADMIN_PW="数据库管理员密码" DB_ADMIN_DB="数据库名称" # --- WordPress 管理界面通用设置 --- WP_USER="管理员用户名" WP_PW="管理员密码" WP_EMAIL="管理员邮箱地址" # --- Certbot 设置 --- CERTBOT_BIN="/usr/bin/certbot" CERT_BASE_DIR="/etc/letsencrypt/live" # 默认证书路径 DEFAULT_CERT="/etc/pki/tls/certs/localhost.crt" DEFAULT_KEY="/etc/pki/tls/private/localhost.key" # --- WP-CLI --- WP_CLI="php -d memory_limit=512M /usr/local/bin/wp --allow-root" # --- 参数检查(域名和数据库密码) --- for arg in "$@"; do case $arg in --domain=*) DOMAIN="${arg#*=}" ;; --pass=*) DB_INDIVIDUAL_PW="${arg#*=}" ;; esac done # --- 验证 --- if [ -z "${DOMAIN}" ] || [ -z "${DB_INDIVIDUAL_PW}" ]; then echo "错误:缺少参数。" echo "使用方法:sudo /usr/local/TOOLS/bin/wordpress.sh --domain='xxxxxx' --pass='xxxxxxxx'" exit 1 fi echo "=== 创建新站点 / 启动 SSL 实现 ===" # 标志 RELOAD_APACHE=false RESTART_APACHE=false # ==================================================== # 函数定义 # ==================================================== # 错误处理函数 error_exit() { echo "--------------------------------------------------" echo "!!! 发生错误,处理已中断 !!!" echo "[错误位置]: $1" echo "[错误详情]: $2" echo "--------------------------------------------------" exit 1 } # 创建 Apache 配置文件的函数 generate_conf() { local TYPE=$1 local CONF_PATH=$2 local TMP_FILE=$(mktemp /tmp/${DOMAIN}_tmp_${TYPE}.conf.XXXXXX) if [ "$TYPE" == "HTTP" ]; then cat <<EOF > "${TMP_FILE}"<VirtualHost *:80>服务器名称 ${DOMAIN} 文档根目录 "${DOC_ROOT}" 目录索引 index.php index.html index.xml<Directory "${DOC_ROOT}" > Options +FollowSymLinks -Indexes AllowOverride all Require all granted</Directory>自定义日志“/var/log/httpd/${DOMAIN}-access_log” 合并错误日志“/var/log/httpd/${DOMAIN}-error_log”<FilesMatch \.(php|phar|html)$>设置处理程序“proxy:unix:/run/php-fpm/www.sock|fcgi://localhost”</FilesMatch></VirtualHost> EOF 否则 cat <<EOF > "${TMP_FILE}"<VirtualHost *:443>服务器名称 ${DOMAIN} 文档根目录 "${DOC_ROOT}" 目录索引 index.php index.html index.xml<Directory "${DOC_ROOT}" > Options +FollowSymLinks -Indexes AllowOverride all Require all granted</Directory>自定义日志“/var/log/httpd/${DOMAIN}-access_ssl_log” 合并错误日志“/var/log/httpd/${DOMAIN}-error_ssl_log” SSLEngine on SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite HIGH:!aNULL:!eNULL:!MD5:!3DES:!RC4:!DES SSLHonorCipherOrder on SSLCertificateFile ${DEFAULT_CERT} SSLCertificateKeyFile ${DEFAULT_KEY}<FilesMatch \.(php|phar|html)$>设置处理程序“proxy:unix:/run/php-fpm/www.sock|fcgi://localhost”</FilesMatch></VirtualHost> EOF fi # 检查配置文件是否存在以及是否存在差异 if [ -f "${CONF_PATH}" ]; then if diff -q "${CONF_PATH}" "${TMP_FILE}" > /dev/null; then echo ">> [SKIP] Apache ${TYPE} 配置文件已存在且其内容未更改" rm "${TMP_FILE}" return else echo ">> [UPDATE] Apache ${TYPE} 配置文件的内容已更新" fi else echo ">> [NEW] Apache ${TYPE} 配置文件已创建" fi sudo mv "${TMP_FILE}" "${CONF_PATH}" if [ $? -ne 0 ]; then error_exit "放置 Apache 配置文件失败" "移动 ${CONF_PATH} 失败" fi sudo chmod 644 "${CONF_PATH}" # 标志 if [ "$TYPE" == "HTTP" ];然后 RELOAD_APACHE=true 否则 RESTART_APACHE=true fi } # ==================================================== # 处理详情 # ==================================================== # --- 应用命名约定 --- # 1. 将域名中的点号转换为下划线 N_DOMAIN="${DOMAIN//./_}" # 2. 数据库名称 = wp_each_domain_name DB_NAME="wp_${N_DOMAIN}" # 3. 数据库用户 = each_domain_name_user DB_USER="${N_DOMAIN}_user" # 4. 虚拟主机的文档根目录DOC_ROOT="/var/www/vhosts/${DOMAIN}/public_html" # 5. WordPress 管理面板中的站点标题 SITE_TITLE="${DOMAIN}" # 6. Apache 配置文件 (HTTP) HTTP_CONF="/etc/httpd/conf.d/${DOMAIN}_http.conf" # 7. Apache 配置文件 (HTTPS) SSL_CONF="/etc/httpd/conf.d/${DOMAIN}_ssl.conf" # 8. 用于权限调整 PARENT_DIR=$(dirname "${DOC_ROOT}") echo "--------------------------------------------------" echo "正在处理:${DOMAIN}" # 1 - 为 WordPress 创建数据库和用户 echo "[1/8] 创建数据库(如果已存在则跳过)...: ${DB_NAME} / 用户: ${DB_USER}" DB_ERR=$(mysql -h "${DB_HOST}" -P 3306 -u "${DB_ADMIN_USER}" -p"${DB_ADMIN_PW}" -D "${DB_ADMIN_DB}" 2>&1 < <EOF CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS '${DB_USER}'@'%' IDENTIFIED BY '${DB_INDIVIDUAL_PW}'; GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'%'; FLUSH PRIVILEGES; EOF ) if [ $? -ne 0 ]; then error_exit "データベース・ユーザー作成処理に失敗しました" "${DB_ERR}" fi # 2 - ドキュメントルートの作成 if [ -d "${DOC_ROOT}" ]; then echo "[2/8] [SKIP] ドキュメントルートは既に存在します: ${DOC_ROOT}" else echo "[2/8] ドキュメントルートの作成中..." MKDIR_ERR=$(sudo mkdir -p "${DOC_ROOT}" 2> &&1) if [ $? -ne 0 ]; then error_exit "创建文档根目录失败" "${MKDIR_ERR}" fi fi CHOWN_ERR=$(sudo chown -R apache:apache "${PARENT_DIR}" 2>&1) [ $? -ne 0 ] && error_exit "更改所有者失败" "${CHOWN_ERR}" CHMOD_ERR=$(sudo chmod -R 2775 "${PARENT_DIR}" 2>&1) [ $? -ne 0 ] && error_exit "更改权限失败" "${CHMOD_ERR}" cd "${DOC_ROOT}" || error_exit "移动到目录失败" "无法切换到 ${DOC_ROOT}" # 3 - 下载 WordPress if [ -f "wp-load.php" ];然后 echo ''3/8] [SKIP] WordPress 文件已存在' 否则 echo ''3/8] 正在下载 WordPress...' WP_DL_ERR=$(${WP_CLI} core download --locale=ja 2>&1) [ $? -ne 0 ] && error_exit "WordPress 下载失败" "${WP_DL_ERR}" fi # 4 - 创建 wp-config.php if [ -f "wp-config.php" ];然后 echo ''4/8] [SKIP] wp-config.php 已存在'" 否则 echo ''4/8] 正在创建 wp-config.php..." WP_CFG_ERR=$(${WP_CLI} config create \ --dbname="${DB_NAME}" \ --dbuser="${DB_USER}" \ --dbpass="${DB_INDIVIDUAL_PW}" \ --dbhost="${DB_HOST}" \ --dbcharset="utf8mb4" \ --dbcollate="utf8mb4_unicode_ci" 2>&1) [ $? -ne 0 ] && error_exit "创建 wp-config.php 失败" "${WP_CFG_ERR}" fi # 5 - 如果 ${WP_CLI} core 已安装,则安装 WordPress 2>/dev/null;然后 echo "[5/8] [SKIP] WordPress 已安装" 否则 echo "[5/8] WordPress 安装过程正在进行中..." WP_INST_ERR=$(${WP_CLI} core install \ --url="https://${DOMAIN}" \ --title="${SITE_TITLE}" \ --admin_user="${WP_USER}" \ --admin_password="${WP_PW}" \ --admin_email="${WP_EMAIL}" \ --skip-email 2>&1) if [ $? -ne 0 ];然后 error_exit "WordPress 安装失败" "${WP_INST_ERR}" fi fi # 6 - Apache HTTP 配置 echo ">"6/8] 正在检查 Apache HTTP 配置..." generate_conf "HTTP" "${HTTP_CONF}" # 仅当配置为新配置或已更新时才重新加载 if [ "$RELOAD_APACHE" = true ]; then echo ">> 正在检查 HTTP 配置更改。正在重新加载 Apache..." if sudo httpd -t; then sudo systemctl reload httpd RELOAD_APACHE=false else error_exit "Apache 语法错误" "使用 'sudo httpd -t' 查看详细信息" fi fi # 7 - Apache SSL 配置 echo ">"7/8] 正在创建 SSL 配置文件..." generate_conf "SSL" "${SSL_CONF}" # 8 - Certbot 获取证书 if [ -d "${CERT_BASE_DIR}/${DOMAIN}" ];然后 echo "8/8] [SKIP] 已获得证书:${DOMAIN}" 否则 # 运行试运行 echo "8/8] 正在获取新的 Let's Encrypt 证书..." echo ">> 正在运行测试,因为尚未获得证书..." certbot_out_test=$(sudo "${CERTBOT_BIN}" certonly --webroot -w "${DOC_ROOT}" \ -d "${DOMAIN}" \ --non-interactive \ --agree-tos \ --register-unsafely-without-email \ --dry-run 2>&1) if [ $? -ne 0 ];然后 echo "!!! 警告:试运行失败,跳过证书获取" "${certbot_out_test}" 否则 echo ">> 正在获取 Let's Encrypt 证书..." certbot_out=$(sudo "${CERTBOT_BIN}" certonly --webroot -w "${DOC_ROOT}" \ -d "${DOMAIN}" \ --non-interactive \ --agree-tos \ --register-unsafely-without-email 2>&1) 如果 [ $? -ne 0 ]; 则 echo "!!!警告:发生错误!跳过证书获取" "${certbot_out}" 否则 echo ">> 证书获取成功" fi fi fi # 替换配置文件中的证书路径(仅当证书已获取且未被替换时执行) 如果 [ -d "/etc/letsencrypt/live/${DOMAIN}" ]; 则 如果 [ -f "${SSL_CONF}" ];然后 # 检查是否已被替换 if grep -q "${DEFAULT_CERT}" "${SSL_CONF}"; then echo ">> 正在替换配置文件路径..." # 备份 sudo cp -p "${SSL_CONF}" "${SSL_CONF}.bak" # 替换 sudo sed -i "s|${DEFAULT_CERT}|${CERT_BASE_DIR}/${DOMAIN}/fullchain.pem|g" "${SSL_CONF}" sudo sed -i "s|${DEFAULT_KEY}|${CERT_BASE_DIR}/${DOMAIN}/privkey.pem|g" "${SSL_CONF}" # 检查差异 if sudo diff "${SSL_CONF}.bak" "${SSL_CONF}" > /dev/null;然后 echo ">> [SKIP] SSL 配置文件路径已正确或未找到要替换的文件" sudo rm "${SSL_CONF}.bak" 否则 echo ">> [SUCCESS] ${DOMAIN}_ssl.conf 证书路径已更新。RESTART_APACHE=true sudo rm "${SSL_CONF}.bak" fi 否则 echo ">> [SKIP] SSL 配置文件已被替换。" fi 否则 echo "!!!警告:未找到 SSL 配置文件 (${SSL_CONF})" fi fi # 最终权限调整 sudo find "${PARENT_DIR}" -type d -exec chmod 2775 {} + sudo find "${PARENT_DIR}" -type f -exec chmod 664 {} + if [ $? -ne 0 ]; then error_exit "调整目录权限失败。" "找不到" fi # 应用设置 if [ "$RESTART_APACHE" = true ]; then echo "--------------------------------------------------" echo "检测到配置更新,将执行重启。" if sudo httpd -t; then sudo systemctl restart httpd echo "所有进程已完成!" else echo "!!!警告:Apache 配置存在错误。重启已中止!!!" exit 1 fi else echo "--------------------------------------------------" echo "无需进行任何配置更改,因此进程将结束。" fi
评论
此脚本需要您根据您的环境指定一些设置!
我将简要解释“预配置中需要指定的参数”以及“将要执行的全部 8 个步骤的处理细节”。
1. 设置项目
→ 安装脚本之前,请先修改脚本开头的变量,使其与您的服务器环境相匹配!
| 设置项目 | 变量名 | 描述/规格 |
| 数据库管理员信息 | 数据库主机名 数据库管理员用户 名 数据库管理员密码 |
指定具有数据库创建权限(例如 root)的帐户的连接信息。 |
| WP初始管理员 | WP_USER WP_PW WP_EMAIL |
指定创建 WordPress 站点时要设置的初始管理员的登录信息。 |
| Certbot / 证书 | 默认证书 默认 密钥 |
指定服务器上临时证书(例如自签名证书)的路径,该证书将在初始创建 SSL 证书时使用。 |
| WP-CLI 命令 | WP_CLI | WP-CLI 的执行路径。--allow-root 参数 允许以 root 用户身份执行。 |
2. 各流程的执行详情
* 请根据您的环境需要调整文档根路径、虚拟主机配置等!
[1/8] 数据库/用户创建
→ 根据域名自动生成数据库名称 (wp_xxx) 和用户名 (xxx_user),然后创建数据库和用户并授予权限。
*示例(如果 --domain='example.com'):
数据库名称:wp_example_com,用户名:example_com_user
[2/8] 创建文档根目录
→ 创建 /var/www/vhosts/域名/public_html
[3/8] 下载 WordPress
→ 使用 WP-CLI 下载 WordPress 核心文件。
[4/8] wp-config.php 创建
→ 根据步骤 1 中设置的数据库连接信息自动生成配置文件。
[5/8] WordPress 安装
→ 注册网站标题、初始管理员帐户和网站 URL (https),然后继续安装。
[6/8] Apache HTTP 配置(端口 80)
→ 生成 VirtualHost 配置文件。
与现有文件进行比较,仅当发现更改时才 执行语法检查和 Apache 重新加载
[7/8] Apache SSL 配置(端口 443)
→ 为了缓解 DNS 尚未传播时出现的错误,请生成一个 VirtualHost 配置文件,指定临时证书的路径。
[8/8] 获取 Let's Encrypt 证书并更新路径
→ 在通过 Certbot 的 Dry-run(测试)确认连接后,如果成功获取生产证书
,则将配置文件中的路径替换 fullchain.pem 并重新启动 Apache。
安装步骤
1. 安装 certbot
dnf install certbot
2.下载
WP-CLI 安装程序:
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
行为检查:
php wp-cli.phar --info
☑ 确认 WP-CLI 和当前环境信息显示在列表中。
授予执行权限:
chmod 755 wp-cli.phar
移动到 /usr/local/bin/:
mv wp-cli.phar /usr/local/bin/wp
测试wp命令的运行情况:
wp --version --allow-root
☑ 确认是否显示了 WP-CLI 版本,例如“WP-CLI x.xx.xx”。
3. 创建一个用于放置脚本的目录。
mkdir -p /usr/local/TOOLS/bin/
4. 安装脚本
vi /usr/local/TOOLS/bin/wordpress.sh
→ 将准备好的源代码复制粘贴到“wordpress.sh”文件中并保存。
授予执行权限:
chmod 755 /usr/local/TOOLS/bin/wordpress.sh
5. 执行
/usr/local/TOOLS/bin/wordpress.sh --domain='域名' --pass='密码'
→ 指定要创建的域名和数据库密码,然后执行。☑
确认显示“所有处理完成!”消息。
■ 实际测试结果
=== 创建新站点 / 开始 SSL 部署 === -------------------------------------------------- 正在处理:example.com [1/8] 创建数据库(如果已存在则跳过)...: wp_example_com / 用户:example_com_user [2/8] 创建文档根目录... [3/8] 下载 WordPress... [4/8] 创建 wp-config.php... [5/8] 执行 WordPress 安装... [6/8] 检查 Apache HTTP 设置... >> [新建] Apache HTTP 配置文件已创建 >> 确认 HTTP 设置更改。正在重新加载 Apache... 语法正确 [7/8] 创建 SSL 配置文件... >> [新建] Apache SSL 配置文件已创建 [8/8] 获取新的 Let's Encrypt 证书... >> 测试运行,因为尚未获取证书... >> 获取 Let's Encrypt 证书... >> 证书获取成功 >> 替换配置文件路径... >> [成功] example.com_ssl.conf 中的证书路径已更新 -------------------------------------------------- 检测到配置更新,将重启 语法正确 所有进程已完成!
最后
很抱歉解释得这么长。
由于这是个人制作的,处理方面可能存在一些瑕疵,请您谅解。
这次我们介绍了一个基础的批处理文件创建脚本,但
通过修改这个脚本,你也可以创建多个站点的 CSV 格式批处理文件等等,所以请尝试根据你的需求进行改进!
未来,我希望能够创建更多实用的脚本,让日常工作更轻松一些🐤
感谢您阅读到最后!
