【 Linux / Apache 】コマンド1行で WP 構築& SSL 化!Apache + WP-CLI 自動化スクリプトの作成方法

はじめに
お久しぶりです!!
エンジニアのひよこ🐤と申します。
新米と名乗りながら、もう三年目になってしまいました....
そんなひよこですが、最近スクリプトを作るのに興味を持ち出しました。
ということで、
検証時に何気に毎回時間を取られてしまう挙動確認用の wordpress サイトを 1 コマンドで作れるスクリプトを作ってみました!!
スクリプトについて
概要
本スクリプトは、新規 WordPress サイトの構築から SSL 化までを一括完了させる自動化スクリプトです。
手動で行うと手間と時間がかかる Web サーバー構築作業を自動化し、簡単に Web サイトを立ち上げることができます。
■ 主な処理の流れ(実行内容)
|
※ 同じドメインに対して複数回スクリプトを実行した場合、設定済みの項目は自動的にスキップされ、
未設定または更新のある項目のみ処理が実行されます。
前提条件・環境
本スクリプトは、以下の検証環境を前提として設計されています。
| 項目 | 条件・環境 |
| OS | AlmaLinux 10.1 |
| DB | MySQL 8.4.8 |
| Web サーバー | Apache + PHP-FPM |
| 実行ユーザー | root |
| DNS設定 | 対象ドメインの A レコードが該当サーバーに向けられていること |
| 必要ツール | WP-CLI、Certbot、MySQL Client |
※ DNS未反映などの理由で証明書の取得(ステップ8)に失敗した場合でも、証明書取得の項目のみがスキップされ、 HTTP 環境としての設定反映・サイト構築自体は完了します。
( HTTPS の conf には、デフォルトのダミー証明書を適用することでエラーを防ぎます✨ )
その場合でも、DNS 設定・浸透後に同手順を再実行することで、証明書の取得・SSL 化のみを後から実施することができます!
ソースコード
こちらがスクリプトの内容になります!
といっても、、、長すぎて詳細な処理内容が分かりにくいかと思いますので、次で解説いたします。
#!/bin/bash
# ==================================================
# 個別設定(環境に合わせて変更してください)
# ==================================================
# --- DB 接続情報 ---
DB_HOST="DB のIP or localhost"
DB_ADMIN_USER="DB 管理用ユーザー"
DB_ADMIN_PW="DB 管理用パスワード"
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"
# --- 引数チェック(ドメイン名と DB パスワード) ---
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>
ServerName ${DOMAIN}
DocumentRoot "${DOC_ROOT}"
DirectoryIndex index.php index.html index.xml
<Directory "${DOC_ROOT}" >
Options +FollowSymLinks -Indexes
AllowOverride all
Require all granted
</Directory>
CustomLog "/var/log/httpd/${DOMAIN}-access_log" combined
ErrorLog "/var/log/httpd/${DOMAIN}-error_log"
<FilesMatch \.(php|phar|html)$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
EOF
else
cat <<EOF > "${TMP_FILE}"
<VirtualHost *:443>
ServerName ${DOMAIN}
DocumentRoot "${DOC_ROOT}"
DirectoryIndex index.php index.html index.xml
<Directory "${DOC_ROOT}" >
Options +FollowSymLinks -Indexes
AllowOverride all
Require all granted
</Directory>
CustomLog "/var/log/httpd/${DOMAIN}-access_ssl_log" combined
ErrorLog "/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)$>
SetHandler "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 設定ファイルの配置に失敗しました" "failed to mv ${CONF_PATH}"
fi
sudo chmod 644 "${CONF_PATH}"
# フラグ
if [ "$TYPE" == "HTTP" ]; then
RELOAD_APACHE=true
else
RESTART_APACHE=true
fi
}
# ==================================================
# 処理内容
# ==================================================
# --- 命名規則の適用 ---
# 1. ドメインのドットをアンダースコアに変換
N_DOMAIN="${DOMAIN//./_}"
# 2. データベース名 = wp_各ドメイン名
DB_NAME="wp_${N_DOMAIN}"
# 3. DBユーザー -= 各ドメイン名_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作成中(既に存在する場合はスキップします)...: ${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 "ディレクトリへの移動に失敗しました" "Cannot cd to ${DOC_ROOT}"
# 3 - WordPress のダウンロード
if [ -f "wp-load.php" ]; then
echo "[3/8] [SKIP] WordPress ファイルは既に存在します"
else
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" ]; then
echo "[4/8] [SKIP] wp-config.php は既に存在します"
else
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 - WordPress のインストール
if ${WP_CLI} core is-installed 2>/dev/null; then
echo "[5/8] [SKIP] WordPressは既にインストール済みです"
else
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 ]; then
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}" ]; then
echo "[8/8] [SKIP] 証明書は既に取得済みです: ${DOMAIN}"
else
# Dry-run の実行
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 ]; then
echo "!!!警告:Dry-run に失敗したため、証明書の取得をスキップします" "${certbot_out_test}"
else
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)
if [ $? -ne 0 ]; then
echo "!!!警告:エラーが発生しました!証明書の取得をスキップします" "${certbot_out}"
else
echo ">> 証明書の取得に成功しました"
fi
fi
fi
# 設定ファイルの証明書パスの置換( 証明書取得済み、かつ未置換の場合のみ実行 )
if [ -d "/etc/letsencrypt/live/${DOMAIN}" ]; then
if [ -f "${SSL_CONF}" ]; then
# 未置換の判定
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; then
echo ">> [SKIP] SSL設定ファイルのパスは既に正しいか、置換対象が見つかりませんでした"
sudo rm "${SSL_CONF}.bak"
else
echo ">> [SUCCESS] ${DOMAIN}_ssl.conf の証明書パスを更新しました"
RESTART_APACHE=true
sudo rm "${SSL_CONF}.bak"
fi
else
echo ">> [SKIP] SSL設定ファイルは既に置換済みです"
fi
else
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 "ディレクトリ権限の調整に失敗しました" "failed to find"
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. 設定項目
→ スクリプトを設置する前に、ご自身のサーバー環境に合わせて冒頭の変数を書き換えます!
| 設定項目 | 変数名 | 説明・指定内容 |
| DB管理者情報 | DB_HOST DB_ADMIN_USER DB_ADMIN_PW |
データベース作成権限( root など )を持つアカウントの接続情報を指定します。 |
| WP初期管理者 | WP_USER WP_PW WP_EMAIL |
WordPress 作成時に設定する初期管理者のログイン情報を指定します。 |
| Certbot / 証明書 | DEFAULT_CERT DEFAULT_KEY |
SSL初期作成時に使用する、サーバー内の仮証明書(オレオレ証明書等)のパスを指定します。 |
| WP-CLI コマンド | WP_CLI | WP-CLI の実行パス。--allow-root を含めることで root 実行を許可しています。 |
2. 各処理の実行内容
※ ドキュメントルートのパスやバーチャルホストの conf 等はご自身の環境に併せて適宜調整してください!
[1/8] DB・ユーザー作成
→ ドメイン名からDB名( wp_xxx )とユーザー名( xxx_user )を自動命名し、DB・ユーザーの作成と権限付与を実行
※ 例( --domain='example.com' の場合 )
DB名: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で設定した DB 接続情報を元に設定ファイルを自動生成
[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 x.xx.xx 」のように、WP-CLI のバージョンが出力されることを確認
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='パスワード'
→ --domain=作成対象のドメイン名、--pass= DB 個別パスワードを指定し、実行してください。
☑「 すべての処理が完了いたしました! 」というメッセージが出力されることを確認
■ 実際の検証時の結果
=== 新規サイトの作成 / SSL化を開始いたします === -------------------------------------------------- 処理中: example.com [1/8] DB作成中(既に存在する場合はスキップします)...: wp_example_com / ユーザー: example_com_user [2/8] ドキュメントルートの作成中... [3/8] WordPress のダウンロードを実行中... [4/8] wp-config.php 作成中... [5/8] WordPress インストール処理を実行中... [6/8] Apache の HTTP 設定を確認中... >> [NEW] Apache HTTP 設定ファイルを作成しました >> HTTP設定の変更を確認。Apache をリロードします... Syntax OK [7/8] SSL 設定ファイル作成中... >> [NEW] Apache SSL 設定ファイルを作成しました [8/8] Let's Encrypt 証明書を新規取得します... >> 証明書未取得のため、テスト実行いたします... >> Let's Encrypt 証明書を取得中... >> 証明書の取得に成功しました >> 設定ファイルのパスを置換中... >> [SUCCESS] example.com_ssl.conf の証明書パスを更新しました -------------------------------------------------- 設定の更新を検知しましたので、再起動を実施いたします Syntax OK すべての処理が完了いたしました!
さいごに
少し説明が長くなってしまいましたが、いかがでしたでしょうか?
個人で作成したものなので、処理の指定方法等がきれいでないところもありますがその点はご容赦くださいませ.....
今回は基本的な設定での一括作成スクリプトをご紹介しましたが、
こちらのスクリプトを応用することで csv 形式での複数サイト一括作成等も可能ですのでぜひ目的に沿った形で改良してみてください!
今後も、あったら嬉しい・ちょっと普段の業務が楽になるようなスクリプトを作っていきたいと思います🐤
最後まで読んでいただきありがとうございました‼
