Tự động cài đặt WordPress với wp-cli

Hướng dẫn sau giúp bạn cài đặt WordPress chỉ bằng một dòng lệnh với wp-cli.

wp-cli là giao diện dòng lệnh của WordPress giúp thực hiện các tác vụ thường gặp và cả những tác vụ không thể tìm thấy trên giao diện quản trị của WordPress. Xem thêm hướng dẫn cài đặt wp-cli.

Các bước cài đặt WordPress bằng wp-cli

Trước khi thực hiện cài đặt, hãy đảm bảo bạn đã setup Domain, cài đặt chứng chỉ SSL và VirtualHost đầy đủ.

Tạo tài khoản truy cập database

Ở đây tôi sẽ tự sinh tên database; user name & password truy cập database; và table prefix dựa trên domain của website vì dù sao những thông tin này cũng chỉ dùng một lần và cần bảo mật tốt.

WP_DOMAIN="example.com"

DB_HOST="localhost"
DB_NAME="$(echo ${WP_DOMAIN} | sed 's/\./_/g')_db"
DB_USER="$(echo ${WP_DOMAIN} | sed 's/\./_/g')"
DB_PASSWORD="$(LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 16)"
DB_PREFIX="$(IFS=.;echo ${WP_DOMAIN}|sed -e 's/$/ /' -e 's/\([^ ]\)[^ ]* /\1/g' -e 's/^ *//')_"

# DB_NAME=example_com_db
# DB_USER=example_com
# DB_PASSWORD=<random generated 16-character password>
# DB_PREFIX=ec_

Tạo user trên MySQL/MariaDB với username và password vừa được tạo và cấp quyền truy cập vào database.

mysql -u root -p -e \
"DROP USER IF EXISTS '${DB_USER}'@'${DB_HOST}';
DROP DATABASE IF EXISTS ${DB_NAME};
CREATE USER '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'${DB_HOST}' WITH GRANT OPTION;"

Tải mã nguồn WordPress

Tải mã nguồn WordPress về web root, ví dụ ~/public_html.

cd ~/public_html
wp core download

Tạo file cấu hình wp-config.php

Tạo file wp-config.php với các thông tin về database ở trên cùng một số thiết lập bổ sung nếu muốn.

wp config create \
    --dbname="${DB_NAME}" \
    --dbuser="${DB_USER}" \
    --dbpass="${DB_PASSWORD}" \
    --dbprefix="${DB_PREFIX}" \
    --extra-php <<PHP
define( 'WP_ALLOW_MULTISITE', true );
define( 'WP_DEBUG', true );
define( 'DISALLOW_FILE_EDIT', true );
// ...other settings
PHP
chmod 644 wp-config.php

Tạo database từ wp-config.php

Tạo database từ các cấu hình vừa thiết lập trong wp-config.php ở bước trên.

wp db create

Cài đặt WordPress

Sau khi có database và file wp-config.php, ta bắt đầu tiến hành cài đặt WordPress. Các thông tin cần có ở đây bao gồm:

  • Địa chỉ URL của website. (ví dụ ‘https://example.com‘)
  • User name của Administrator. (ví dụ ‘admin’)
  • Password của Admin. (Tôi sẽ tự sinh ra mật khẩu này)
  • Email của Admin. (ví dụ ‘webmaster@example.com‘)
  • Tiêu đề của website. (ví dụ ‘iCreativ’)
WP_SITE_NAME="iCreativ"
WP_SITE_URL="https://${WP_DOMAIN}"
WP_ADMIN_USERNAME="admin"
WP_ADMIN_PASSWORD="$(LC_CTYPE=C tr -dc A-Za-z0-9 < /dev/urandom | head -c 16)"
WP_ADMIN_EMAIL="webmaster@example.com"

wp core install \
    --url="${WP_SITE_URL}" \
    --title="${WP_SITE_NAME}" \
    --admin_user="${WP_ADMIN_USERNAME}" \
    --admin_password="${WP_ADMIN_PASSWORD}" \
    --admin_email="${WP_ADMIN_EMAIL}" \
    --skip-email

Các cấu hình sau cài đặt

Ban đầu có lẽ chúng ta nên ngăn chặn search engine duyệt trang này.

wp option update blog_public 0

Thiết lập đường dẫn tĩnh, điều này rất quan trọng nếu bạn làm SEO.

wp rewrite structure '/%category%/%postname%.html' --hard
wp rewrite flush --hard

Xóa các plugin mặc định của WordPress là AkismetHello Dolly.

wp plugin delete akismet
wp plugin delete hello

Cài đặt một số plugin từ WordPress Plugins. Chú ý tên plugin chính là slug của trang plugin. Ví dụ Contact Form 7 có URL là https://wordpress.org/plugins/contact-form-7/ thì tham số truyền vào lệnh sẽ là contact-form-7.

Để kích hoạt plugin sau khi cài, ta thêm tham số --activate.

wp plugin install wordpress-seo --activate
wp plugin install contact-form-7 --activate
wp plugin install wp-mail-smtp --activate
wp plugin install kk-star-ratings
...

Xong! Vậy là việc cài đặt WordPress bằng dòng lệnh đã hoàn thành. Script hoàn chỉnh của việc cài đặt này như sau.

/usr/local/bin/wp-install.sh

#!/bin/bash

WP_SITE_NAME="WordPress"
WP_ADMIN_USERNAME="icreativ"
WP_ADMIN_EMAIL="webmaster@icreativ.pro"
WP_ADMIN_PASSWORD="$(LC_CTYPE=C tr -dc A-Za-z0-9 < /dev/urandom | head -c 16)"
WP_WEB_ROOT="$(pwd)"

DB_ROOT_USER="root"
DB_ROOT_PASSWORD="{ugly-password}"

usage()
{
    echo "Usage: $(basename $0) [OPTIONS] DOMAIN"
    echo
    echo "Available OPTIONS:"
    echo "  -t TITLE    : Website title (default: ${WP_SITE_NAME})."
    echo "  -u USERNAME : Admin user name (default: ${WP_ADMIN_USERNAME})"
    echo "  -m EMAIL    : Admin email (default: ${WP_ADMIN_EMAIL})"
    echo "  -w WEBROOT  : Web Root (default: current directory)"
    echo "  -l URL      : Site URL (default: https://{DOMAIN})"
    echo
}

# Whether or not ${1} is a valid domain
is_domain()
{
    [[ ${1} =~ ^([a-zA-Z0-9_-]+\.)*[a-zA-Z0-9][a-zA-Z0-9_-]+\.[a-zA-Z]{2,11}?$ ]]
}

# Terminate the script if any error occurs
exit_on_error()
{
    eval "${@@Q}"
    local exit_code=$?
    [ ${exit_code} -ne 0 ] && exit ${exit_code}
}

while getopts ":t:u:m:w:l:" o; do
    case "${o}" in
        t )
            WP_SITE_NAME="${OPTARG}"
            ;;
        u )
            WP_ADMIN_USERNAME="${OPTARG}"
            ;;
        m )
            WP_ADMIN_EMAIL="${OPTARG}"
            ;;
        w )
            WP_WEB_ROOT="${OPTARG}"
            ;;
        l )
            WP_SITE_URL="${OPTARG}"
            ;;
        h )
            usage; exit 0
            ;;
        \? )
            echo "Invalid Option: -${OPTARG}." 1>&2
            usage; exit 1
            ;;
        : )
            echo "Invalid Option: -${OPTARG} requires an argument." 1>&2
            usage; exit 1
            ;;
    esac
done
shift $((OPTIND-1))

WP_DOMAIN="$1"
if ! is_domain "${WP_DOMAIN}"; then
    echo "Invalid domain '${WP_DOMAIN}'" 1>&2
    exit 1
fi

if [ ! -d "${WP_WEB_ROOT}" ]; then
    echo "The directory '${WP_WEB_ROOT}' not found!" 1>&2
    exit 1
fi
if [ ! -w "${WP_WEB_ROOT}" ]; then
    echo "The directory '${WP_WEB_ROOT}' is not writable!" 1>&2
    exit 1
fi

[ -z "${WP_SITE_URL}" ] && WP_SITE_URL="https://${WP_DOMAIN}"

DB_HOST="localhost"
DB_NAME="$(echo ${WP_DOMAIN} | sed 's/\./_/g')_db"
DB_USER="$(echo ${WP_DOMAIN} | sed 's/\./_/g')"
DB_PASSWORD="$(LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 16)"
DB_PREFIX="$(IFS=.;echo ${WP_DOMAIN}|sed -e 's/$/ /' -e 's/\([^ ]\)[^ ]* /\1/g' -e 's/^ *//')_"

echo "========================================="
echo "Database:"
echo " Host         : ${DB_HOST}"
echo " Name         : ${DB_NAME}"
echo " User         : ${DB_USER}"
echo " Password     : ${DB_PASSWORD}"
echo " Table Prefix : ${DB_PREFIX}"

echo "========================================="
echo "WordPress:"
echo " Web root     : ${WP_WEB_ROOT}"
echo " Domain       : ${WP_DOMAIN}"
echo " Site URL     : ${WP_SITE_URL}"
echo " Site name    : ${WP_SITE_NAME}"
echo " User name    : ${WP_ADMIN_USERNAME}"
echo " Password     : ${WP_ADMIN_PASSWORD}"
echo " Email        : ${WP_ADMIN_EMAIL}"
echo "========================================="
echo

read -n1 -rsp "Press 'c' to continue..." key
echo
if [ "${key}" != 'c' ]; then
    echo "Opertation was cancelled!"
    exit 0
fi

cd "${WP_WEB_ROOT}"

exit_on_error mysql -u${DB_ROOT_USER} -p${DB_ROOT_PASSWORD} -e \
"DROP USER IF EXISTS '${DB_USER}'@'${DB_HOST}';
DROP DATABASE IF EXISTS ${DB_NAME};
CREATE USER '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'${DB_HOST}' WITH GRANT OPTION;"

# Download WordPress source code
exit_on_error wp core download

# Create the wp-config.php
exit_on_error wp config create \
    --dbname="${DB_NAME}" \
    --dbuser="${DB_USER}" \
    --dbpass="${DB_PASSWORD}" \
    --dbprefix="${DB_PREFIX}" \
    --extra-php <<PHP
define( 'WP_ALLOW_MULTISITE', true );
define( 'WP_DEBUG', true );
define( 'DISALLOW_FILE_EDIT', true );
// ...more settings go here
PHP

# Create the database
exit_on_error wp db create

# Install WordPress data
exit_on_error wp core install \
    --url="${WP_SITE_URL}" \
    --title="${WP_SITE_NAME}" \
    --admin_user="${WP_ADMIN_USERNAME}" \
    --admin_password="${WP_ADMIN_PASSWORD}" \
    --admin_email="${WP_ADMIN_EMAIL}" \
    --skip-email

# Discourage search engines
exit_on_error wp option update blog_public 0

# Set pretty urls
exit_on_error wp rewrite structure '/%category%/%postname%.html' --hard
exit_on_error wp rewrite flush --hard

# Delete akismet and hello dolly
exit_on_error wp plugin delete akismet
exit_on_error wp plugin delete hello

# Install essential plugins
exit_on_error wp plugin install wordpress-seo --activate
exit_on_error wp plugin install contact-form-7 --activate
exit_on_error wp plugin install wp-mail-smtp --activate
exit_on_error wp plugin install zero-spam --activate
exit_on_error wp plugin install enable-media-replace --activate
exit_on_error wp plugin install kk-star-ratings

echo
echo "==================================================="
echo "Login information"
echo " URL ...........: ${WP_SITE_URL}/wp-admin"
echo " Username ......: ${WP_ADMIN_USERNAME}"
echo " Password ......: ${WP_ADMIN_PASSWORD}"
echo "==================================================="

Sử dụng lệnh này như sau (Lưu ý, không chạy bằng tài khoản root, lệnh wp-cli cũng sẽ đưa ra cảnh báo về điều này)

wp-install.sh -t "My Website" \
        -u johndoe \
        -m john.doe@example.com \
        -w /home/john/public_html \
        -l http://example.com

Lệnh trên sẽ cài đặt WordPress vào thư mục /home/john/public_html với tài khoản admin là johndoe. Mật khẩu sẽ được hiển thị trong lúc cài đặt.