Setting Up WordPress with Cloud-Init

WordPress is the most used open-source content management system – and it’s totally free. More than 40% of the websites on the internet are powered by WordPress*, both small blogs and large websites. WordPress is extremely customizable and beginner-friendly, but is also suitable for large and complex websites.

Automate the Setup Process with Cloud-Init

Setting up new WordPress instances is easy, but in order for WordPress to run you need a webserver and a MySQL database. Setting all of this up can take a lot of time, especially if you’re doing it on a large scale.

However, if you want to add WordPress to your existing server, head over to this guide on setting up WordPress manually.

Cloud-Init can be used to automate the installation and setup process of your server by following a specific set of instructions you define. So in this guide, we will take a look at how the installation process looks and create a Cloud-Init config for it, so it can be automated.

Benefits of using Cloud-Init

The true power of Cloud-Init is not only automating the initial installation, but replicating it on multiple machines – automatically. This is a huge time-saver in case of a disaster, where you need a new server running and configured as fast as possible. For more details about Cloud-Init itself, we’ve written a whole article about the benefits and how to use it.

WordPress Requirements

Before we can get into the installation process, we need to know what we actually need to install. WordPress recommends

  • servers running version 7.4 or greater of PHP,
  • MySQL version 5.7 OR MariaDB version 10.3 or greater,
  • either Apache or Nginx as the most robust options for running WordPress, but neither is required.

So basically WordPress is using the LAMP stack (with possible variations), which stands for Linux, Apache, MySQL / MariaDB and PHP. We’ll install MariaDB version 10.3 and PHP 8.1, since this is the latest stable release of PHP (as of October 2022).

You can use either a VPS, VDS, or a dedicated server, depending on the scale of your needs. Same for the operating system, you can use any Linux distribution. A common choice is a VPS M with NVMe storage and Debian 11.

LAMP Stack Setup

We’ve already created a guide on how to set up LAMP stack with Cloud-Init, so we’ll use this as a starting point for our new Cloud-Init config:

#cloud-config
package_update: true
package_upgrade: true
packages:
  - software-properties-common
  - wget
  - curl
  - apache2
runcmd:
  - curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x
  - sudo apt-get install php8.1 php8.1-cli php8.1-common php8.1-curl php8.1-gd php8.1-intl php8.1-mbstring php8.1-mysql php8.1-opcache php8.1-readline php8.1-xml php8.1-xsl php8.1-zip php8.1-bz2 libapache2-mod-php8.1 -y
  - service apache2 restart
  - apt install mariadb-server mariadb-client -y
  - pw=$(openssl rand -base64 18); mysqladmin -u root -h localhost password "$pw"; echo "mysql_password=$pw" >> /home/mysql_access.txt
  - mysqladmin reload

This installs Apache2 with PHP 8.1 and MariaDB. The password for our MariaDB database is stored in this file:

/home/mysql_access.txt

WordPress Installation

Database Creation

This step is pretty easy, all we need to do is execute one SQL command to create a new, empty database:

CREATE DATABASE wordpress;

So let’s add this to our config:

# Create database
- sudo mysql -e “CREATE DATABASE wordpress;”

WordPress CLI

WordPress is well-known for its ease of installation, and that also applies to headless installations (without opening the visual installer in the browser). The WordPress CLI provides a very easy way to install and configure a WordPress installation. So first, let’s install the CLI:

  # Install WordPress CLI
  - cd ~ 
  - sudo curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
  - sudo chmod +x wp-cli.phar
  - sudo mv wp-cli.phar /usr/local/bin/wp

This will download the CLI file to the home directory, make it executable and move it to the bin directory so the “wp” command is globally available.

WordPress Setup

With the CLI installed, the actual setup is done in a few easy steps:

  1. Navigate to the web server’s root directory (/var/www/html)
  2. Download the latest WordPress release
  3. Configure the database connection
  4. Install WordPress

Note: We will execute the commands as “www-data” user since that’s the user that’s executing the PHP scripts. If we create the files and folders as root user, the www-data user won’t have enough permissions to make changes to the directories (e.g. upload files, install plugins/themes, …).

Prepare the html directory (set the correct permissions):

  # Set up WordPress
  - cd /var/www/
  - sudo chown -R www-data:www-data html
  - sudo chmod 755 html
  - cd html

Also, delete the default html file that was created during the Apache2 installation. By default, Apache2 is configured to check for an index.html file first (before index.php), which means even with WordPress installed you will still see the default html file from Apache2:

  - sudo rm index.html

Download the WordPress core:

- sudo -u www-data wp core download

Configure the MySQL database with the credentials and DB name as set before:

- sudo -u www-data wp core config --dbname='wordpress' --dbuser='root' --dbpass="$pw" --dbhost='localhost' --dbprefix='wp_'

Make sure WordPress can access the “wp-content” directory (themes / plugins / file-uploads / …):

 - sudo chmod -R 755 /var/www/html/wp-content

Now WordPress is downloaded and connected to the MySQL database. However, to complete the installation, we need to create the admin user and provide some details about the website.

If you prefer to complete that step in a visual interface in the browser, you can skip the next command. Once the server is ready, open the server’s IP in the browser and the WordPress installer shows up for this last step.

To complete the installation automatically with cloud-init, use this command:

- sudo -u www-data wp core install --url='http://your-wordpress-website.com' --title='My WordPress Website' --admin_user='admin' --admin_password='secure' --admin_email='[email protected]'

Make sure to replace the options with your real information.

One final command: WordPress itself and many plugins are using .htaccess files to do things like

  • custom permalinks,
  • prevent access to specific files and folders,
  • enable caching,

and much more. To allow .htaccess files, create a new file in the Apache2 config folder that sets “AllowOverride” to All (for the directory /var/www/html), enable the rewrite module, and restart Apache2:

- sudo echo -e "<Directory /var/www/html>\n    AllowOverride All\n</Directory>" >> /etc/apache2/sites-enabled/allow-htaccess.conf
  - sudo a2enmod rewrite
  - sudo service apache2 restart

Final Cloud-Init Config

All the steps combined, that’s how the final Cloud-Init configuration file looks like:

#cloud-config
package_update: true
package_upgrade: true
packages:
  - software-properties-common
  - wget
  - curl
  - apache2
runcmd:
  - curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x
  - sudo apt-get install php8.1 php8.1-cli php8.1-common php8.1-curl php8.1-gd php8.1-intl php8.1-mbstring php8.1-mysql php8.1-opcache php8.1-readline php8.1-xml php8.1-xsl php8.1-zip php8.1-bz2 libapache2-mod-php8.1 -y
  - service apache2 restart
  - apt install mariadb-server mariadb-client -y
  - pw=$(openssl rand -base64 18); mysqladmin -u root -h localhost password "$pw"; echo "mysql_password=$pw" >> /home/mysql_access.txt
  - mysqladmin reload

  # Create database
  - sudo mysql -e "CREATE DATABASE wordpress;"

  # Install WordPress CLI
  - cd ~ 
  - sudo curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
  - sudo chmod +x wp-cli.phar
  - sudo mv wp-cli.phar /usr/local/bin/wp

  # Set up WordPress
  - cd /var/www/
  - sudo chown -R www-data:www-data html
  - sudo chmod 755 html
  - cd html
  - sudo rm index.html
  - sudo -u www-data wp core download
  - sudo -u www-data wp core config --dbname='wordpress' --dbuser='root' --dbpass=”$pw” --dbhost='localhost' --dbprefix='wp_'
  - sudo chmod -R 755 /var/www/html/wp-content

  # Install WordPress
  - sudo -u www-data wp core install --url='http://your-wordpress-website.com' --title='My WordPress Website' --admin_user='admin' --admin_password='secure' --admin_email='[email protected]'

  # Allow .htaccess files
  - sudo echo -e "<Directory /var/www/html>\n    AllowOverride All\n</Directory>" >> /etc/apache2/sites-enabled/allow-htaccess.conf
  - sudo a2enmod rewrite
  - sudo service apache2 restart

(*) According to the official WordPress website and W3Techs.