What you are reading now is hosted by a headless Raspberry Pi web server. It is a cheap card-sized computer run on a 5V 2.5A power supply located in the cold depths of my tool shed close to the arctic circle. Used as a web server the average power consumption is probably less than 10 Watts.
Yes, this will be yet another instruction for deploying a LAMP (Linux, Apache, MySQL, PHP) stack and installing a WordPress site with internet access through the WAN (wide area network) in order to allow for global exposure and not only through the LAN (local area network).
The reason I chose to base my site on a Raspberry Pi is because building a WordPress site based on wordpress.com servers for sure is easier, but also more expensive in the long run – which isn’t strange since someone has to pay the electrical bills and report to investors. Also I noticed a greater variety of plug-ins was readily available with the downloaded version of WP on the Raspberry Pi, like SEO (search engine optimization) tools. For example in order to get SEO tools on the web-based version a plan that costs 25€/month needs to be obtained first. To sum it up; it is simply cheaper (and more fun) to make your own Raspberry Pi web server.
Be warned though, this will expose your device to external hacker attacks so being rigorous with the safety measures is a good idea.
Building a LAMP Raspberry Pi web server according to raspberrypi.org
I am by no means an IT-guy so I learned how to do this by scraping the web for solving a variety of problems in order for me to get this far. I started off in the eminent site of raspberrypi.org and found the tutorial Build a LAMP Web Server with WordPress which explains how to set up a LAMP stack and turning the raspberry pi into a web server with a WordPress site. Here are the condensed steps:
Install “Apache” (a web server application ), “PHP” (a preprocessor that works out what needs to be shown on the page), “Maria DB” (data base engine) and “MySQL”:
$ sudo apt-get install apache2 php mariadb-server php-mysql
Then restart Apache
$ sudo service apache2 restart
Move to and remove all files from /var/www/html/:
$ cd /var/www/html/
$ sudo rm *
Download WordPress, extract contents, move files to current directory and remove unnecessary files:
$ sudo wget http://wordpress.org/latest.tar.gz
$ sudo tar xzf latest.tar.gz
$ sudo mv wordpress/* .
$ sudo rm -rf wordpress latest.tar.gz
Change ownership to user:
$ sudo chown -R www-data: .
Set up MySQL/MariaDB
$ sudo mysql_secure_installation
- Enter the sudo password
“Set the password for WordPress” –Y (remember it since this password will be the one used to log in to the wp-admin endpoint.
“Remove anonymous users” –Y
“Disallow root login remotely” – Y
“Remove test database and access to it” –Y
“Reload privilege tables now” –Y
Create the WordPress database
$ sudo mysql -uroot -p
In the Maria DB monitor, type in the following (semi-colons included)
create database wordpress;
GRANT ALL PRIVILEGES ON wordpress.* TO ‘root’@’localhost’ IDENTIFIED BY ‘YOURPASSWORD‘;
Exit MariaDB with Ctrl+D and reboot your Pi:
$ sudo reboot
Wait a few minutes for the Raspberry Pi to reboot and open a web browser on your computer and dial in the Pi’s LAN address in the browser like ‘192.168.1.54’ (this assumes that you have both your computer and your Raspberry Pi hooked up in your local network. If everything went as it should the following page should present itself
Fill out the following form after pressing “Let’s go!”:
- Database Name: wordpress
- User Name: root
- Password: <YOUR WORDPRESS PASSWORD>
- Database Host: localhost
- Table Prefix: wp_
From here on out creativity starts – the design and shipping of the website is managed. In order to log in to the admin page henceforward use the endpoint /wp-admin on the sites address. At this point the Raspberry Pi web server is officially online in the LAN domain. Further steps to make the Raspberry Pi web server available from the WAN network are needed.
Obtain the Public IP (WAN) address
The wide area network (WAN) is the public IP address of the LAN network. This address is usually found in your routers admin-page or checking “what is my public ip“.
Port forwarding is necessary in order to convey requests from clients to the server machine. For the Raspberry Pi web server which should be running in the LAN it means that requests to port 80 (HTTP) and port 443 (HTTPS) must be forwarded. If SSH access to the Raspberry Pi web server from outside the LAN network is desired also requests to port 22 must be forwarded.
For security reasons it is a good idea to install Fail2ban which protects against brute force attacks and constitutes a second line of defense in case plug-ins like Wordfence is installed in your WordPress site already.
In your routers admin page there should be a port-forwarding setting similar to this picture (example from an ASUS RT-AC68U).
Obtain a Domain Name
This is a prerequisite in order to obtain a SSL certificate in the next step necessary to have a secure web site (HTTPS instead of HTTP, the latter is frowned upon in search engines).
There are a-dime-a-dozen more or less expensive ways to get a DNS. In my case and surely in most other DNS providers there should be a setting to point (type of pointing = “A”) the DNS to a server machine, which would be your public IP address which in turn is forwarding requests to your Raspberry Pi web server.
A free option is No-Ip which is also suitable in case a static IP address isn’t acquired.
Obtain free SSL certificate with Certbot
The SSL certificate is usually not free if provided by a DNS supplier and comes with a monthly payment plan. Unless you want to pay for that a free option is Certbot which is a open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS. In order to install Certbot a DNS must already be acquired as described in the previous step.
Firewall rules – Iptables
Iptables monitors traffic on the Raspberry Pi web server (and Linux machines in general). It contains rules (chains) that will filter incoming and outgoing data packets. By default Iptables has an empty ruleset. If fail2ban is installed it will add or remove its own rules in the iptables and leave everything else untouched. In order to view the rulesets:
$ sudo iptables -L
A decent IPv4 ruleset for a Raspberry Pi web server can be set up by creating a temporary file in the /tmp folder:
$ sudo nano /tmp/ipv4
Copy the following python script into the ipv4 file and save it (ctr-x).
*filter # Allow all loopback (lo0) traffic and reject traffic # to localhost that does not originate from lo0. -A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT # Allow ping. -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT # Allow SSH connections. -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT # Allow HTTP and HTTPS connections from anywhere # (the normal ports for web servers). -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT # Allow inbound traffic from established connections. # This includes ICMP error returns. -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Reject all other inbound. -A INPUT -j REJECT # Reject all traffic forwarding. -A FORWARD -j REJECT COMMIT
Load the rules
$ sudo iptables-restore < /tmp/ipv4
In order to make the rules persistent even after reboot
$ sudo apt-get install iptables-persistent
Roll-out the Raspberry Pi web site
At this point the Raspberry Pi web site can go live, in order to make the WordPress site load without errors when entering the DNS address in a web browser the following changes must be made to the URL links in Settings – General:
If everything has worked as it should the browser displays the padlock on the address field
Expand max upload size
- In some cases (like it was for me) the WAN address displayed on the router admin-page was something mysterious and did not point to my router for reasons unknown so port forwarding did route to my Raspberry Pi, I had to contact my internet-service provider (ISP) in order for them to give me a proper WAN IP address. Once this was done typing https://<WAN-adress> piped me to the pi web server (the same way that typing the Pi’s LAN address would have done).
- Certain ISP’s don’t allow port forwarding in order use their own web site services for a monetary plan. I hope this isn’t your issue.
- If somehow you would find yourself locked out of the wp-admin page it might be because something strange has happened in the URL links. In order to change the URL using SSH navigate to
$ cd /var/www/html/wp-content/themes/<your theme>
and add the following lines in the very end of the functions.php file:
update_option( ‘siteurl’, ‘https://example.com‘ );
update_option( ‘home’, ‘https://example.com‘ );
Change the red text to e.g. http://<LAN adress> to make sure you are able to log in again and circle back to SSL part in order to sort out the DNS URL.