/ Raspberry Pi

Multi-Site Raspberry Pi WordPress Server, Part III

Thus far we've gotten our little "toy" computer (I'm rolling my eyes at my wife's comment to the same) ready to take on the monumental task of running a world-class WordPress site that can handle moderate traffic (add some caching to the mix and you're set!). We're now moving on to the folder setup and installation of WordPress, one install per site. Theoretically, we can install as many sites as we want. However, the Raspberry Pi isn't really equipped to handle several sites- especially if you several using the same resources at the same time. Even if the traffic is nominal, every little bit adds up. For me, I've actually got three set up, however, one of them is an internal site my daughter uses to lean WordPress. I only run two outward facing sites and those have an average of about 300 daily visits.

Folder Setup

The standard folder scheme for Nginx's http/https handling is to place them into the
/var/www/html
which is great if you're running a single site. But we're trying to do more than one so there is s specific way to do this as Nginx will always look to an /html folder for it's site data (technically speaking you can put it anywhere... but we're going to try and follow the Nginx path). Let's create two new folders that we can place our WordPress data:

sudo mkdir -p /var/www/example.com/html
sudo mkdir -p /var/www/test.com/html

Now we have our two directories, one for example.com and the other for test.com. Next, we need to assign some ownership to the folders:

sudo chown -R $USER:$USER /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/test.com/html

And we'll follow that up with the proper permissions:

sudo chmod -R 755 /var/www

Next, we need to set up individual server blocks for each of the sites. As it stands now there is only one server block and it goes by the boring name of default which we'll use to our advantage and do a copy/paste for our new sites:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/test.com

Now we need to do some edits on these two new files (server blocks):

sudo nano /etc/nginx/sites-available/example.com

Within our new server blocks, we need to concentrate on four specific areas (these are the defaults within):

listen 80 default_server;
listen [::]:80 default_server;

root /var/www/html;

index index.html index.htm index.nginx-debian.html;

server_name _;

First, we need to look at the listen directives. Only one of our server blocks on the server can have the default_server option enabled. This specifies which block should serve a request if the server_name requested does not match any of the available server blocks. This shouldn't happen very frequently in real-world scenarios since visitors will be accessing your site through your domain name.

You can choose to designate one of your sites as the "default" by including the default_server option in the listen directive, or you can leave the default server block enabled, which will serve the content of the /var/www/html directory if the requested host cannot be found. [^note]

Next is the

root folder

You'll recall we just made two new ones, one each for example.com and test.com. This will need to change from:

root /var/www/html;

to its new location:

root /var/www/example.com/html

Lastly, we need to add our servers to the mix as opposed to the underscore you start with. Easy enough:

server example.com www.example.com;

And that's it for this one. Now, you'll need to repeat these steps for each of the follow-on sites you plan on adding. In the end, your edits should look something like this:

listen 80;
listen [::]:80;

root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;

server_name example.com www.example.com;

Save what we got.

To enable these newly created server blocks, input:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/test.com /etc/nginx/sites-enabled/

Some people have issues with what's called a hash bucket memory problem when all of this is implemented. So, to avoid this we need to make another edit. Open:

sudo nano /etc/nginx/nginx.conf

And locate the server_names_hash_bucket_size and uncomment it (remove the #) and ensure it's at 64.

We'll test Nginx to ensure nothing weird has happened, and then restart it:

sudo nginx -t
sudo systemctl restart nginx

If all is set up properly the last step in this arena is to delete the original default file we copied ours from:

sudo rm -r /etc/nginx/sites-available/default

You need to do this to remove the potential for conflicts when your sites try to load. It never fails, I forget to delete this file and then nothing works.

Now that all of this is done you need to be aware that the only way to test it out is to actually port forward (port 80) to this machine and ensure your DSN records are pointing to your router (I'll get into that in a bit).

Install WordPress (finally)

All this word has led to the install of WordPress, perhaps the second easiest part. Follow along:

cd /var/www/example.com/html/
sudo rm index.*
sudo wget http://wordpress.org/latest.tar.gz

We've downloaded it to our example.com/html folder, but you'll have to do the same thing for the test.com folder too. Continue with:

sudo tar xzf latest.tar.gz
sudo mv wordpress/* .
sudo rm -rf wordpress latest.tar.gz

You now have the core files installed for WordPress (4.8 at the time of this writing, but it'll work for all as of now). Remember, you have to follow these steps for each individual site you plan on running.

To ensure search engine crawlers don't go snooping where they shouldn't be going we're going to create a robots.txt file:

sudo nano robots.txt

And add the following:

User-agent: *
Disallow: /wp-admin/
Disallow: /wp-includes/
Disallow: /wp-content/plugins/
Disallow: /wp-content/themes/
Disallow: /admin/

Control + X, Y, Enter. Moving on...

Update some permissions:

sudo chown -R www-data: . (Yes, include that period.)

Database Creation

Before we open up WordPress, we need to make some databases for WordPress to use. Good thing we already installed MariaDB.

Using the root password you created earlier, let's log in and make a database, or two (or three, four, five...):

sudo mysql -u root -p (you'll be prompted for you password)

You can name your database anything you want, however, I usually keep a scheme for mine. For our site, example.com, we'll create one called

example_com

MariaDB [(none)]> CREATE DATABASE example_com;

When working in SQL don't forget to end your commands with ";". Now, let's create a user to own your newly created database. Technically speaking you could use "root," but good security dictates you should do otherwise.

MariaDB [(none)]> CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';

Be sure to change username and password to what you'd want to use. For my WordPress passwords, I generally use wordpress. Now we need to give our new user the proper privileges to the newly created database(s):

MariaDB [(none)]> GRANT ALL PRIVILEGES ON example_com.* TO 'username'@'localhost';

Make those privileges a real thing and then exit via:

MariaDB [(none)]> FLUSH PRIVILEGES;

MariaDB [(none)]> exit;

Starting WordPress (on a multi-site server)

Here's where this gets a little tricky. Not hard, just different. Normally, when one is running a single site on their server they can just go to their internal address (mine would be the 192.168.1.177) and WordPress would walk you through the set-up of the databases and first login. However, we're not running a single site, thus it's a little trickier. (I use option two below.)

Option One
I wasn't planning on getting into the how-to of port forwarding (but you can visit this site for an overview of almost any router). If you've gotten this far I'm pretty sure you can figure out how to do that. I will tell you that I use Cloudflare and they make forwarding your domain to your RPi location really easy. Essentially I get my home IP (or where you're physically going to have your RPI) via the command curl https://dynamicdns.park-your-domain.com/getip or just Google what's my IP and forward it from there to my house where my router port forwards it via port 80 to my RPI where my Nginx server blocks figure out which of my two external sites to send it to.

Option Two
Once you're set to start setting up your site we need to update your host file (because, as noted above, you can just go to your internal IP with more than one site going). To edit (this in on your computer, not your RPi server; and this only works on the computer in which you update your host file.) on my Mac I use:

sudo nano /etc/hosts

And after entering the password for my Mac I get this:

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost
fe80::1%lo0     localhost

We're going to add one line. For my site, ryanerickson.com, I want to visit it from this computer on my server at 192.168.1.177 so I'll add:

192.168.1.177 ryanerickson.com www.ryanerickson.com

It'll look like this when we're done:

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost
fe80::1%lo0     localhost
192.168.1.177 ryanerickson.com www.ryanerickson.com

Type Control + X, Y (for yes) and Enter to save.

You can now go to your domain just like you would if you messed with all the port forwarding. This is a good way to work a site before you put it out to the world (however, you may have issues if you're dealing with SSL). When you're done and ready to show the world be sure to comment out (add #) or delete that last line you put in.

And that's it. My next part I'll pick up after you've figured out how to send your domain name to your house/location and starting up WordPress for the first time. Remember the user name, password, and database you created earlier, you'll need that to input into the setup page.

Part 0 | Part I | Part II | Part III | Part IV: Soon


[^note] As noted on a DigitalOcean tutorial.

Multi-Site Raspberry Pi WordPress Server, Part III
Share this