Setting up WordPress on Raspberry Pi 3 with Raspbian Stretch Lite, nginx, MariaDB and PHP 7 as the LEMP stack

Raspbian Stretch was released on 17th August 2017 and this will mean that we will be able to get a variant of Debian 9 on our Raspberry Pi. With Raspbian Stretch, we will be able to run WordPress or any PHP framework with PHP 7.0 which Zend had indicated a performance boost of up to two folds as compared to PHP 5.6.

Before porting my blog over to PHP 7, it will make sense for me to perform a little proof of concept on my Raspberry Pi 3 first. With Raspbian Stretch Lite, I can see for myself that my blog runs well with PHP 7.0 before spawning a new Digital Ocean instance for Techcoil.

This post documents how I setup an instance of WordPress on Raspberry Pi 3 with Raspbian Stretch Lite, nginx, MariaDB and PHP 7 as the LEMP stack.

Hardware List to build my Raspberry Pi 3 LEMP server

I used the following hardware for my Raspberry Pi 3 LEMP server:

Prerequisite hardware to install operating system onto the microSD

Raspberry Pi 3 board will load an operating system from a microSD card. Hence, we will need to have a computer with a SD card reader. If your computer does not come with a SD card reader, you have to get one.

If you have the standard SD card reader on your computer but do not have a SD card adapter, you may want to get the Kingston Digital 32 GB microSDHC Class 10 UHS-1 Memory Card 30MB/s with Adapter (SDC10/32GB) instead.

Getting a copy of Raspbian Stretch Lite

Once I had the hardware list in place, I proceeded to download a copy of Raspbian Stretch Lite. As of this writing, the one that was available was dated 7th September 2017:

Raspbian Stretch download page 20170907

I clicked on the Download Zip button for Raspbian Stretch Lite and saved the zip file onto my file system.

Installing Raspbian Stretch Lite onto my microSD card

Once my browser had completed the download for the .zip file, I extracted the .img file from the .zip file. The .img file was the operating system image that I used for installing Raspbian Stretch Lite onto my microSD card.

I used Etcher on my MacBook Pro to install the operating system image onto the microSD card.

If you are using a windows machine, you can use Win32DiskImager to install the operating system for your Raspberry Pi 3.

If you are using a Linux desktop, you should be able to Etcher to install the operating system for your Raspberry Pi 3.

Enabling SSH server on Raspbian Stretch Lite first boot

With an SSH server running on Raspbian Stretch Lite, I do not have to find a spare keyboard and monitor in order to configure Raspbian Stretch Lite after it had booted up for the first time. To ensure that I had the SSH server running after the first boot, I created a file named "ssh” in the boot partition of the microSD card:

Raspbian Stretch Lite 20170816 boot with ssh file

Assembling the hardware for the Raspberry Pi LEMP Server

Next, I removed my microSD card from my SD card reader and inserted it to the microSD card slot on the Raspberry Pi 3 board. After that, I went ahead to assemble the Raspberry Pi 3 board to the Official Raspberry Pi case.

Starting the Raspbian Stretch Lite operating system

With the assembly of my Raspberry Pi 3 board and Official Raspberry Pi case, I connected one end of the RJ45 cable to the RJ45 port on my Raspberry Pi 3 board and the other end of the cable to one of the switch port of my home router. After that, I connected my micro USB cable and supply power to my Raspberry Pi 3 board.

Finding the IP address of my Raspberry Pi 3

When Raspbian Stretch Lite boots up, it requested an IP address from my router. This IP address was needed for me to SSH into my Raspberry Pi 3. I went to my router's address allocation table and find an entry with the name raspberrypi. In my case, the router allocated 192.168.1.109 to my Raspbian Stretch Lite.

Getting into the Raspbian Stretch Lite operating system via SSH

The default credentials to log into Raspberry Pi Stretch Lite is as follows:
Username: pi
Password: raspberry

With that the default credentials and the IP address that my router had given to my Raspbian Stretch Lite, I then used SSH to get into the operating system:

ssh pi@192.168.1.109

I then entered raspberry when the Raspbian Stretch Lite prompted for password. With that, my Raspbian Stretch Lite greeted me with the following output:

Linux raspberrypi 4.9.41-v7+ #1023 SMP Tue Aug 8 16:00:15 BST 2017 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

Changing the default password

Since the Raspbian Stretch suggested that using the default password for the 'pi' user is a security risk, the next thing that I did was to change the default password. To do so, I entered the following command:

passwd

For the three prompts that followed the command, I entered raspberry and my favourite password twice.

Configuring the locale settings

The next thing that I did was to configure the locale settings for my Raspbian Stretch Lite. To do so, I first opened up the Raspberry Pi Software Configuration Tool:

sudo raspi-config

I then followed through the following screens to generate the "en_US.UTF-8" locale and set it as the default locale for the system environment:

raspi-config Raspbian Stretch Lite with localisation options selected

raspi-config Raspbian Stretch Lite with localisation-options change locale selected

raspi-config Raspbian Stretch Lite screen for generating en-us utf-8 locale

raspi-config Raspbian Stretch Lite setting en-us utf-8 as default locale for system environment

After doing so, I opened up /etc/default/locale with nano:

sudo nano /etc/default/locale

And updated the contents to look like the following:

LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
LANGUAGE=en_US.UTF-8

This would ensure that the locale settings for my WordPress server persist through system reboots.

Installing nginx on Raspbian Stretch Lite

After configuring the locale settings, I proceeded to install nginx on my Raspbian Stretch Lite. To do so, I entered the following command:

sudo apt-get install nginx -y

After the installation had completed, I ran the following command to verify that the installation was successful:

systemctl status nginx.service

The command returned me with the following output to tell me that nginx was installed successfully on my Raspbian Stretch Lite:

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2017-09-23 07:25:05 UTC; 7min ago
     Docs: man:nginx(8)
  Process: 15356 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 15353 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS
 Main PID: 15357 (nginx)
   CGroup: /system.slice/nginx.service
           ├─15357 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           ├─15358 nginx: worker process
           ├─15359 nginx: worker process
           ├─15360 nginx: worker process
           └─15361 nginx: worker process

Sep 23 07:25:05 raspberrypi systemd[1]: Starting A high performance web server and a reverse proxy server...
Sep 23 07:25:05 raspberrypi systemd[1]: Started A high performance web server and a reverse proxy server.

Installing MariaDB database server and command line client on my Raspbian Stretch Lite

After I had gotten nginx on my Raspbian Stretch Lite, I then proceeded on to install the MariaDB database server and the command line client on my Raspbian Stretch Lite. To do so, I ran the following command:

sudo apt-get install mariadb-server mariadb-client -y

Unlike my previous experience with installing mysql servers, this installation of mariadb-server did not prompt me for a root password. This was because the root user was by default set to use the unix_socket plugin, which allows the user to use operating system credentials when connecting to MariaDB via Unix socket.

Since the pi user of my Raspbian Stretch installation was configured to use sudo without password prompt, I could get into my mariadb-server through the following command without supplying any password:

sudo mariadb 

I did not like this way of getting into MariaDB server.

Making MariaDB on Raspbian Stretch Lite prompt for root password when being accessed by the command line client

Since I prefer to have mariadb prompt me for a password, I first got into the mariadb interactive shell with the following command:

sudo mariadb 

Inside the mariadb shell, I then ran the following SQL statements:

use mysql;
update user set password=PASSWORD("new_password"), plugin = '' where User='root';
flush privileges;

With that, my MariaDB server would require me to key in my root password whenever I try to access it via the command line client.

Installing PHP 7 on my Raspbian Stretch Lite

Next item on the list was to install the components needed to run WordPress. For that, I needed PHP7, PHP7 Fast CGI Process Manager and PHP7 MySQL bridge to be installed. To install these three items, I ran the following command:

sudo apt-get install php7.0 php7.0-fpm php7.0-mysql -y

After the installation had completed, I entered the following command to check the status:

systemctl status php7.0-fpm.service

Seeing the following output assured me that my PHP Fast CGI Manager had started successfully:

● php7.0-fpm.service - The PHP 7.0 FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php7.0-fpm.service; enabled; vendor prese
   Active: active (running) since Sat 2017-09-23 07:59:21 UTC; 1min 54s ago
     Docs: man:php-fpm7.0(8)
 Main PID: 12314 (php-fpm7.0)
   Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/se
   CGroup: /system.slice/php7.0-fpm.service
           ├─12314 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
           ├─12315 php-fpm: pool www
           └─12316 php-fpm: pool www

Getting a copy of WordPress

Once I had completed installation of the required components to run WordPress on Raspbian Stretch Lite, I proceeded to get a copy of WordPress.

To do so, I ran the following command:

cd /var/www
sudo wget https://wordpress.org/latest.tar.gz
sudo tar xvfz latest.tar.gz
sudo rm latest.tar.gz
sudo mv wordpress my_new_wordpress_site

Doing so would leave a my_new_wordpress_site folder inside the /var/www folder. The my_new_wordpress_site folder will contain the codes necessary to run WordPress.

Configuring nginx to proxy HTTP requests to the PHP 7 Fast CGI Manager

Next, I went on to configure nginx to serve as a reverse proxy server for my WordPress site. Referencing the informative guide provided by WordPress on configuring nginx, I created /etc/nginx/sites-enabled/anewwebsite.com.conf:

# WordPress single site rules.
# Designed to be included in any server {} block.
# Upstream to abstract backend connection(s) for php
upstream php {
        server unix:/run/php/php7.0-fpm.sock;
}

server {
        listen   80;
        ## Your website name goes here.
        server_name anewwebsite.com www.anewwebsite.com;
        ## Your only path reference.
        root /var/www/my_new_wordpress_site;
        ## This should be in your http block and if it is, it's not needed here.
        index index.php;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location / {
                # This is cool because no php is touched for static content.
                # include the "?$args" part so non-default permalinks doesn't break when using query string
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include fastcgi.conf;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
                fastcgi_buffers 16 16k;
                fastcgi_buffer_size 32k;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

Creating a MariaDB user and a database instance for the WordPress site

Next up was to create the necessary items for WordPress to use the MariaDB database. It is good practice to create a separate database user for the WordPress site to interact with the database. As such, the next step that I did was to create a Maria DB user that only have the privileges to interact with a particular database instance.

To do so, I first got into the mariadb-server using mariadb with the root user:

sudo mariadb -u root -p

After keying in my password for that root user, I first ran the following command to create a new database instance:

CREATE DATABASE newWordPressDb;

With that database instance created successfully, I then created the MariaDB user with the relevant privileges for accessing that database instance:

CREATE USER 'anewuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON newWordPressDb.* TO 'anewuser'@'localhost';

With that, I would have a MariaDB user for my WordPress site to use a MariaDB database instance.

Setting cgi.fix_pathinfo = 0 in php.ini of PHP 7 Fast CGI Manager

Since WordPress suggested that we should have "cgi.fix_pathinfo = 0;" in php.ini, the next step that I did was to do that.

The php.ini file for PHP 7 Fast CGI Manager is found in the /etc/php/7.0/fpm folder. With that, I used nano to open up /etc/php/7.0/fpm/php.ini and replaced:

;cgi.fix_pathinfo = 1;


with:


cgi.fix_pathinfo = 0;

I then restarted the PHP 7 Fast CGI Manager with the following command:

sudo systemctl restart php7.0-fpm.service

Creating the WordPress configurations to use the database instance

With the MariaDB user and database instance in place, the next thing that I did was to create the WordPress configurations for WordPress to use the database instance.

To do so, I first renamed /var/www/my_new_wordpress_site/wp-config-sample.php to /var/www/my_new_wordpress_site/wp-config.php:

sudo mv /var/www/my_new_wordpress_site/wp-config-sample.php /var/www/my_new_wordpress_site/wp-config.php

I then used my browser to access https://api.wordpress.org/secret-key/1.1/salt/ to generate some key and salt values for my /var/www/my_new_wordpress_site/wp-config.php.

With that, I opened up /var/www/my_new_wordpress_site/wp-config.php with nano and updated some sections of the file to look like the following:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'newWordPressDb');

/** MySQL database username */
define('DB_USER', 'anewuser');

/** MySQL database password */
define('DB_PASSWORD', 'password');

/** MySQL hostname */
define('DB_HOST', 'localhost');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         '3nGgSDEQkxEnCPDi,l/v?=bx@9KN`OmB?/g=:Adj+Nn<sR+6iH_Q2Ch&-=An.tU!');
define('SECURE_AUTH_KEY',  'l]iOF-zG.%p+A|C3}?2-f<vCu*ar|dA:_[/h&<X~1os=}S:[$.]z[2m#Yto>g:T=');
define('LOGGED_IN_KEY',    'du-Xi](g:HvJ;yl$I-nj+)B)$lCWI@,[vorWnj,7^g_N|6CCeE=_js%m[.80:+O@');
define('NONCE_KEY',        'T<:<9+%}L1^|1O+hoP{!vRgy-7Z90XJoO(|s =HMYxf;D+@Q|En-3.8c.[fEt%*d');
define('AUTH_SALT',        'OxlI/I4eq_9dQ{C|fm<sN~E=~-2iX}4%A3+1EF$2kV2N6v8V%zU^|31$8@-G^gNf');
define('SECURE_AUTH_SALT', '=+Oo8d*Y(@wqleOK[9sq3Yg*7x}i&0J!k;J#i>8d|YUioee~($Cb2_CL*aeEJLzm');
define('LOGGED_IN_SALT',   '$lr:;X8HG3$o<4s%>gM:0SfZ+1cME _VcQv[%.{UK!:E`7EI[:-^aT:sjYZ5h>&x');
define('NONCE_SALT',       'oVm~a@[$7kb?xxv`_tx?MbOlv:~NV7;{FX/NfvCnb}V|u+9ozG&iJ<=rW+{#qY,{');
/**#@-*/

Editing the hosts file to access my WordPress site from my work computer

After putting in the configurations that are necessary for WordPress to function, the next thing that I did was to get my computer to resolve the domains anewwebsite.com and www.anewwebsite.com with the IP Address of my Raspberry Pi 3: 192.168.1.109. To do so, I opened up /etc/hosts on my Mac and add in the following entries:

192.168.1.109 anewwebsite.com
192.168.1.109 www.anewwebsite.com

Running the WordPress installation script

Once I had added the necessary hosts entries, I then accessed www.anewwebsite.com with my browser.

Once the installation page appeared, I then keyed in the necessary input:

WordPress installation page 1 running from Raspbian Stretch Lite

And clicked the Install WordPress button:

WordPress installation successful message from Raspbian Stretch Lite

With that, I had WordPress running on Raspberry Pi 3 with Raspbian Stretch Lite, nginx, MariaDB and PHP 7 as the LEMP stack.

Buying the Raspberry Pi 3 hardware to build your own LEMP server to run WordPress

If you do not have the Raspberry Pi 3 hardware mentioned in this post yet, you may want to purchase them from Amazon. Simply click on the button below to add the Raspberry Pi 3 hardware to your cart. You may remove anything that you already have or replace some of the hardware with other hardware.


Advertisements

About Clivant

Clivant a.k.a Chai Heng enjoys composing software and building systems to serve people. He owns techcoil.com and hopes that whatever he had written and built so far had benefited people.

Advertisements
Advertisements