In my local test environment, I work with a custom setup based on Homebrew with nginx, MySQL and PHP. For creating a new WordPress website, I’ve created a script to automate it.

This script asks for a site title and whether I want to install a multisite. It then creates a new site in /Users/matze/Sites with the format wp-<site>.test, where <site> is the site title in lowercase with only letters, numbers and dashes.

It creates a database automatically with the name wp_<site> and installs WordPress in it (here: with locale de_DE), adds some debugging flags to the wp-config.php and removes the default plugins Akismet and Hello Dolly.

If enabled, it also activates the network capability for the multisite and adds the necessary entry in the /etc/hosts file to wp-<site>.test to make it work.

Last but not least, it also creates a new entry in my ~/.wp-cli/config.local.yml to make updates possible with the wp @all command (or other commands via wp @local_<site>).

This is how the script looks like:



echo "Site Title:"

echo "Multisite? (y/N)"
IS_MULTISITE=$(echo "${IS_MULTISITE}" | tr '[:upper:]' '[:lower:]')

URI=$(echo "${SITE_TITLE//([^A-Za-z0-9])/-}" | tr '[:upper:]' '[:lower:]')

if [ -d "${HTDOCS}/wp-${URI}" ]; then
	echo "Directory already exists."
	exit 1

echo "Create database ${DATABASE}"
mysql -u root -proot -e "CREATE DATABASE ${DATABASE}"

mkdir ${HTDOCS}/wp-${URI}
cd ${HTDOCS}/wp-${URI}

wp core download --locale=de_DE
wp config create --dbname=${DATABASE} --dbuser=root --dbpass=root
wp config set WP_DISABLE_FATAL_ERROR_HANDLER true --raw
wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set WP_DEBUG_DISPLAY true --raw
wp config set SCRIPT_DEBUG true --raw
wp config set EPIPHYT_DEBUG true --raw
wp config set DISABLE_WP_CRON false --raw
wp config set QM_DARK_MODE true --raw
wp config set FORCE_SSL_ADMIN false --raw
wp config set FORCE_SSL_LOGIN false --raw
wp config set WP_POST_REVISIONS 10 --raw
wp config set MEDIA_TRASH true --raw
wp config set EMPTY_TRASH_DAYS 10 --raw
wp config set WP_AUTO_UPDATE_CORE false --raw
wp config set DISALLOW_FILE_EDIT true --raw
wp config set CORE_UPGRADE_SKIP_NEW_BUNDLED true --raw
wp config set WP_ENVIRONMENT_TYPE local
wp config set WP_DEVELOPMENT_MODE all
wp core install --url="wp-${URI}.test" --title="${SITE_TITLE}" --admin_name=root --admin_password=root
wp plugin delete akismet
wp plugin delete hello.php

if [ "${IS_MULTISITE}" = "y" ]; then
	wp core multisite-install --base="/" --skip-email --title="${SITE_TITLE} Sites" --admin_user=root

if [ $? -ne 0 ]; then
	echo "An error occurred. Rollback."
	rm -r ${HTDOCS}/wp-${URI}
	mysql -u root -proot -e "DROP DATABASE ${DATABASE}"
	exit 1

cp ${NGINX_CONFIG_DIR}/servers/wp-test.test ${NGINX_CONFIG_DIR}/servers/wp-${URI}.test

sed -i "" "s|wp-test|wp-${URI}|" ${NGINX_CONFIG_DIR}/servers/wp-${URI}.test
echo "Restart nginx"
sudo brew services restart nginx

sed -i "" "s|### CONF|@local_${URI//([^A-Za-z0-9])/_}:\n\tpath: ${HTDOCS}/wp-${URI}\n\n### CONF|" ~/.wp-cli/config.local.yml

echo "	wp-${URI}.test" | sudo tee -a /etc/hosts

echo "WordPress site created: http://wp-${URI}.test/wp-admin/"
echo "Username: root"
echo "Password: root"

Code language: Bash (bash)

If you want to use it, you can adapt the variable HTDOCS in line 3 to the path of your sites and NGINX_CONFIG_DIR to the path of your nginx configuration directory. If you’ve also using Homebrew and are on an Apple Silicon chip, the path should be the same. If you use an Intel chip, the correct path would be /usr/local/etc/nginx.

For each site, the file in ${NGINX_CONFIG_DIR}/servers/wp-test.test will be copied. It looks like this:

server {
	listen 80;
	server_name wp-test.test;

	root /Users/matze/Sites/wp-test;
	index  index.html index.htm index.php;

	location / {
		autoindex on;
		try_files $uri $uri/ /index.php?$args;

		proxy_buffer_size 128k;
		proxy_buffers 4 256k;
		proxy_busy_buffers_size 256k;

	location ~ \.php$ {
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;

	if (!-e $request_filename) {
		rewrite /wp-admin$ $scheme://$host$uri/ permanent;
		rewrite ^(/[^/]+)?(/wp-.*) $2 last;
		rewrite ^(/[^/]+)?(/.*\.php)$ $2 last;
Code language: Nginx (nginx)

If you set another HTDOCS, make sure to also adjust the root in line 5 accordingly. Leave the rest as is, as wp-test will be replaced with wp-<site>.

This way, I can quickly create new testing sites for my or my client’s WordPress projects.

Leave a Reply

Your email address will not be published. Required fields are marked *