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.
The standard folder scheme for Nginx’s http/https handling is to place them into the
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 a /html folder for it’s site data. 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:
sudo nano /etc/nginx/sites-available/example.com
Within our new server blocks, we need to concentrate on three 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;
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. 1
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:
to its new location:
Lastly, we need to add our servers to the mix as opposed to the “_” it has in place now. 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 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…
Adding some robot permissions:
sudo chown -R www-data: .
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 can name your database anything you want, however, I usually keep a scheme to mine. For our site example.com we’ll create one called
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.
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):
GRANT ALL PRIVILEGES ON example_com.* TO 'username'@'localhost';
Make those privileges a real thing via:
FLUSH PRIVILEGES; 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 internally 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 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.
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. On to the last part…
1 As noted on a DigitalOcean tutorial.