Raspberry Pi Apache, MariaDB, PHP & WordPress Server

The purpose of this tutorial is to walk you through the process of using a Raspberry Pi as a web server.

This tutorial assumes:

  1. You already know how to flash a microSD card with Raspbian.
  2. You are already somewhat familiar with setting up and using a Raspberry Pi.
  3. You have already followed my previous tutorial titled Raspbian Stretch Lite Secure Baseline Setup.

Before We Begin

The way I have outlined this tutorial is to

  1. Walk you through the steps of getting the Raspberry Pi setup as a fully functional web server.
  2. Once everything is fully setup we will move the Raspberry Pi web server onto the Internet.

Sure, we could do everything live. However, I prefer this method so the system is secure before I move it into production. Once we do move things online, there will be a couple of adjustments that we have to make so all of the links on the site will work properly.

Please keep in mind that the instructions I am providing to you are what allowed me to make this work. There are probably (most likely) better instructions out there. I try my hardest to be as secure in my setups as possible. I have a background in Information Technology and currently hold a CompTIA Security+ certification. With that being said, I make zero claims of being an expert! I wish I were! Ultimately, use these instructions at your own risk!

Now that all of the disclaimers are out of the way, let’s have some fun!

Install Apache, MariaDB, PHP, & phpMyAdmin

Once you have your Raspberry Pi running with your baseline image of Raspian Lite and are logged in with an account that has super user (sudo) privileges, it is time to get to work installing all of the components of your Raspberry Pi Web Server. The following command will install Apache 2 (web server), MariaDB (Maria Database Server, which is a fork of MySQL), PHP 7.0 (a scripting language that WordPress relies on), and a few other necessary components to make everything work.

span class=”st0″>’USERNAME’@‘localhost’‘PASSWORD’;
span class=”st0″>’USERNAME’@‘localhost’


Once you have entered the above commands you can exit out of the MariaDB console by typing exit and pressing Enter.

Listen 80

# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request’s Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName www.irgos.com

ServerAdmin webmaster@irgos.com
DocumentRoot /var/www/html/irgos.com/public_html

# Available loglevels: trace8, …, trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog /var/www/html/irgos.com/logs/error.log
CustomLog /var/www/html/irgos.com/logs/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet


We now need to activate the site that we just created and restart Apache2.

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */‘DB_NAME’, ‘your_database’);

/** MySQL database username */‘DB_USER’, ‘your_database_user’);

/** MySQL database password */‘DB_PASSWORD’, ‘your_database_password’);

/** MySQL hostname */‘DB_HOST’, ‘localhost’);

/** Database Charset to use in creating database tables. */‘DB_CHARSET’, ‘utf8’);

/** The Database Collate type. Don’t change this if in doubt. */‘DB_COLLATE’, );


Navigate to the WordPress unique phrase generator website. Copy the newly generated phrases over what is already in the configuration file.

Save the wp-config.php file.

Re-connect to your server using an FTP client. Use the site credentials. I’ll be using FileZilla.

Navigate to the /home/irgos/htdocs/public_html folder.

Upload all of the WordPress files.

Navigate to http://IPADDRESS (replace IPADDRESS with the IP address of your Pi).

You should now be greeted with the WordPress installer screen. Follow the instructions on the screen to configure your web site.

Must Have Plugins

SMTP Mailer Plugin

If you are going to use your installation of WordPress offline in an Intranet environment, the SMTP Mailer plugin is crucial to allow WordPress to send email messages. In the server’s current configuration no email messages will be sent. Using this plugin will allow you to connect your WordPress installation to an SMTP server to allow outgoing messages from WordPress. If you are using Gmail or gSuite (formerly Google Apps, Google Apps for Domains) you will have to enable the option in your settings that allows for less secure applications to connect to the SMTP server (as a security conscious person, this makes me cringe). This will not work if you have two-factor authentication enabled. A more secure option would be to use the Gmail SMTP plugin. If you would prefer to use that option, after we get our server moved online we can setup that plugin.

To enable the “Allow less secure apps” option (again I cringe), login to your Google account. Go to the “My Account” page. Click on the link for “Sign-in & security” then scroll down to the section titled “Apps with account access” and turn on the “Allow less secure apps” option.

Because this is a less secure option, I would highly encourage that if you have any sensitive information in the account you were planning to use, that you create another account. Perhaps create a “no-reply” account as you have undoubtedly seen utilized on thousands of websites.

Download the SMTP Mailer plugin and extract the ZIP file.

Upload the extracted files to /home/username/htdocs/public_html/wp-content/plugins

While logged into your WordPress installation, click on the Plugins link.

Activate the SMTP Mailer plugin. Click on the Settings button.

For Gmail or gSuite, use the following settings:

SMTP Host: smtp.gmail.com
SMTP Authentication: True
SMTP Username: Your Gmail address or your gSuite address.
Type of Encryption: TLS
SMTP Port: 587
From Email Address: Your Gmail address or your gSuite address.
From Name: Use what you would like your recipients to see.

You should now be able to click on the Test Email tab and send a test email message. Another way to test this would be to logout of WordPress and select the “Lost your password?” option. Enter your username. You should receive an email in your mailbox with a link to reset your password.


Next, we need to setup a method for backing up the WordPress database. My recommendation is the WP-DBManager plugin.

Download the plugin and extract the ZIP file.

Connect to your Pi via sFTP and navigate to /home/irgos/htdocs/public_html/wp-content and create a directory named “backup-db”

Open the newly created directory.

From the contents of the extracted plugin (wp-dbmanager.2.79\wp-dbmanager), upload the htaccess.txt file then rename the file to .htaccess

Go back up one level. Right click on the newly created directory and select File permissions.

Enter 777 into the Numeric value field.

Select the “Recurse into subdirectories” and “Apply to all files and directories” options.

Upload the extracted plugin files (the wp-dbmanager folder within the wp-dbmanager.2.79 folder) to /home/irgos/htdocs/public_html/wp-content/plugins

While logged into your WordPress installation, click on the Plugins link.

Activate the WP-DBManager plugin.

From the sidebar, click on the Database option.

Select the “DB Options” option. This is where you definitely want to make some changes. You will want to setup automatic backups. Select a schedule that reflects how often you plan to make changes to your WordPress site. I do recommend using the Gzip option. It is a good idea to run automatic database optimization and repair at least once per month. At the bottom you configure the backups to be emailed to your preferred email inbox.

Other options you may find useful:

The Database option will show you local server information and the tables from your WordPress database that will be backed up.

Click on the Backup DB option. This is where you can confirm that all of your settings are good to go. Additionally, at the bottom, there is an option to GZIP the database backup file. The default is set to “No” but I generally change this to “Yes.”

The Manage Backup DB option will allow you to select a specific database backup and either email, download, restore, or delete it.

The Optimize DB option will allow you to run a database optimization on your tables.

The Repair DB option will allow you to repair your database tables.

The Empty/Drop Tables option is dangerous. Be careful with it. This one allows you to empty the contents or delete a database table.

If you’d rather not connect to the MariaDB console or access phpMyAdmin, you can run SQL queries from the Run SQL Query option.

Akismet Anti-Spam

While I do not plan to go into the details of how to setup Akismet, I will say if your website is publicly accessible, definitely set it up.

For internal Intranet sites I don’t think it is necessary unless you think internal users will abuse the comments.

Backup Site Files

In the plugins section I wrote about backing up the WordPress database. Now we need to also backup the actual website files. We also need a way to get them off of the Pi’s microSD card in case it becomes corrupted. I personally think offloading these files to Dropbox is the best solution.

Once again we need to switch into the site user’s account.




You will notice that I changed the name of the file. The reason for this is because the only thing contained within this file is the token we will generate shortly.

Save and exit the file.

The script will need execute permissions in order to run. Unfortunately, we will once again need to switch users. We’ll switch to themaster account and then exit it so that we are back at the command line for the site user account.

span class=”st0″>"%d-%m-%Y_%H%M""/home/irgos/temp/irgos_site_files_backup_$DATE.tar""/home/irgos/htdocs /home/irgos/scripts /etc/apache2/sites-available/irgos.com.conf""$BKP_FILE""$BKP_FILE"

$DROPBOX_UPLOADER -f /home/irgos/scripts/.dropbox_token upload "$BKP_FILE.gz""$BKP_FILE".gz

Save and exit the file.

We need to make this script executable as well. By now you know the drill. Switch to an account with sudo privileges and execute the following command.

m h dom mon dow /home/irgos/scripts/irgos_site_files_backup.sh

m = minute
h = hour
dom = date of month (1 – 31)
mon = month (1 – 12)
dow = day of week [0 – 6, 6 is Saturday], [0 – 7, 7 is Sunday], or [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, or Saturday]

Additionally, instead of specifying the date/time as described above, you could use one of the following options:

@reboot (runs once at system startup)
@daily (runs at midnight)
@midnight (same as @daily)
@monthly (once a month)
@hourly (every hour)


@midnight /home/irgos/scripts/irgos_site_files_backup.sh

Move to the Internet

Dynamic DNS

Unless your ISP provides you with a static IP address, you will need to subscribe to a service that captures your router/modem’s public IP address and reports that back to their DNS servers as it changes.

No-IP Setup

Because I already pay for NO-IP services, this is the dynamic DNS service that I will write instructions for in this article. There are other dynamic DNS services out there. You may prefer one of those better based on pricing, options, etc.

Create an account at noip.com then configure a new host.

Login to the site account on your Pi via SSH and run the following commands from the root of that user’s home directory (i.e. /home/siteuser:

NOTE: The following instructions were taken from No-IP’s knowledge base with slight modifications.

mkdir noip

Open the noip directory.

cd noip

Next you will use wget to download the No-IP Dynamic Update Client (DUC).

wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz

Issue the following command to untar (extract) the DUC.

tar vzxf noip-duc-linux.tar.gz

Open the newly created directory.

cd noip-2.1.9-1

Next you will run the commands to make and run the installer.

sudo make
sudo make install

You will enter your login credentials for No-IP.com, select the hostname to update, and the interval at which to update the hostname. I generally set mine to the default 30 minutes.

Next you will need to configure the No-IP DUC to launch when the Pi starts. stuffaboutcode.com has great instructions for doing this. If that link ever quits working, here is a copy of their instructions in PDF format.

Next, we will reboot the Pi so we can confirm that the noip2 process is running.

Once the Pi has rebooted, enter the following command:

sudo noip2 -S

You should see the following: “1 noip2 process active”

Another way to verify is to enter the command top and scroll through the list of running processes using the up/down arrow keys on your keyboard looking for noip2.

A Matter of Security

At the beginning of this article I suggested that if you had not, you should follow my previous blog article, Setting up the Raspberry Pi Zero, Zero W, or Pi 3 with Raspbian Stretch Lite. If you haven’t, I highly recommend going through it. You will learn how to configure user accounts, two factor (certificate based) authentication, a firewall, and additional ways that you can and should enhance the security of your Raspberry Pi before you place your project onto the Internet.

Move Pi to the DMZ

At this point you should be good to move your Pi into the DMZ. This will place your Pi directly onto the Internet. That is, if your ISP does not block web server traffic. Once you do have your Pi in the DMZ, start attempting to access the web site by entering your public IP address (if web server traffic is not blocked) or your No-IP hostname into your browser’s address bar. You may want to try it from an external network (mobile/cell network) if you are not having any luck. If you do get connected, you will then want to work on getting your domain name forwarded to your No-IP hostname.

Unfortunately, because almost everyone reading these instructions has a different router, it would be impossible for me to tell you how to put your Pi into the DMZ. What I can do is show you how I do have done it with my Century Link Actiontec C1000A. It will be pretty similar on most other routers.

Login to the web based admin.

Go into the Advanced Setup options.

Under the Security options, select DMZ Hosting.

Enter the IP address of your Pi and click on Apply.

If your current public IP address has had enough time to propagate through the Internet then you should be able to access your NO-IP hostname from ANOTHER network (cell/mobile phone).

In order to access your NO-IP hostname from within your own network, you’re going to have to fake it. What I mean is you will have to go to the DNS Host Mapping settings and link your NO-IP hostname to your Pi’s local IP address.

Fixing WordPress URLs

If you are successful in accessing your web server remotely you may notice that some of the URLs try to go to your Pi’s local IP address. This is because when we installed WordPress we installed it locally. Yes, we could have waited until we got everything else setup, but I wanted to have WordPress fully functional before putting the server online. This is easy to correct.

Navigate to http://IPADDRESS/phpmyadmin (you can also use http://NOIPHOSTNAME if you have made the DNS Mapping change to your router) and login using your site account’s WordPress database.

If it isn’t already, expand the database in the left sidebar.

Click on wp_options.

Under option_name you will see siteurl and home. Use the Edit button to update these values to your NOIP hostname.

Setting up the Gmail SMTP Plugin

Earlier in this post I provided instructions for setting up a WordPress plugin called SMTP Mailer. We installed this plugin because without it WordPress would not be able to send out email messages in the server’s current configuration. Unfortunately, if we use this plugin to connect to a Google account, we must enable an option that downgrades our security. The instructions in this section are for the Gmail SMTP Plugin, which allows us to take advantage of the full security offerings of a Google account. Now that we have the server online, this plugin will work.

Note that I was unable to get this plugin to work while having 2-factor authentication enabled. Which is unfortunate.

The plugin developer does have instructions on their site. However, the instructions are a bit out of date. So I will walk you through the steps of getting this setup.

I was unable to get this to work using one of my gSuite accounts. It appears as though the free version of gSuite does not allow its users to take advantage of the Google Developer Console. I started using Google Apps for Domains (what is now known as gSuite) many, many years ago when it was in beta and free. I believe for me to utilize one of those accounts I would have to upgrade my gSuite account to a paid account. At the moment I would rather not have to pay for yet another service. The good news is that you can utilize the Google Developer Console from a free Gmail account.

Download the Gmail SMTP plugin and extract the ZIP file.

Upload the extracted files to /home/username/htdocs/public_html/wp-content/plugins

While logged into your WordPress installation, click on the Plugins link.

Activate the Gmail SMTP plugin. Click on the Settings button.

In a separate tab, login to your Google account and navigate to the Google Developer Console website.

Click on the Create Project button.

Give your project a name then click on Create.

Currently, the Gmail API is listed as a popular API. Click on the Gmail API icon in the list of popular APIs.

Click on Enable

We will now create credentials that the Gmail SMTP plugin will use to access your Gmail account.

Click on the Create Credentials button.

We will leave the option Which API are you using? set to Gmail API.

In the Where will you be calling the API from? options we will select Web server.

Under What data will you be accessing? select User data. Click on the What credentials do I need? button.

You will now be presented with the form to create an OAuth 2.0 client ID. Provide a name for the client ID.

In the Authorized JavaScript origins you will need to place your website URL.

In the Authorized redirect URIs field, you will need to copy this address from the Gmail SMTP settings panel within WordPress.

If you do not click on anything the values that you enter will automatically appear above the form field. This would allow you to enter additional URL or URIs.

Click on Create client ID.

On the next screen you will need to create a Product name. Click on Continue.

You will be presented with the Client ID. Copy this to the Client ID field in the Gmail SMTP plugin settings page.

On the Google Developer Console page you will also be presented with an option to download the credential information in JSON format. Download the file. Open the file in Notepad. You will have to get the “client_secret” code to paste into the Gmail SMTP settings. You will want everything between the parenthesis. Do not include the parenthesis.

Sidenote: While writing these instructions I ran through this process multiple times. After having deleting the credentials and re-creating them I would occasionally get a pop-up with the Client ID and Client Secret. Which is much simpler than downloading the JSON file. However, either option will work.

Complete the rest of the fields in the Gmail SMPT settings in WordPress.

Click on the Save Changes button.

Once the page reloads, click on the Grant Permission button.

You will be prompted to login to your Google account. Login to the account we are setting up authentication for.

You will be taken to a screen that states This app isn’t verified. Click on the Advanced link and choose the Go to URLHERE unsafe option.

Grant the permission for your application to use your Gmail account by clicking on Allow.

You should be taken back to your Gmail SMTP settings panel. The SMTP Status should now be green with a checkmark.

You can test the connection by clicking on the Test Email tab and composing an email to yourself. It would also be a good idea to logout of WordPress and pretend you forgot your password to ensure you receive an email from the site. Also, it would be a good idea to confirm your database backups still get delivered to you.

If you are like me and need to switch your email address in WordPress from a gSuite address to a free Gmail account. You can do this in WordPress by clicking on the Settings button. Then click on the General button. Then change the email address in the Email Address field. Click on Save Changes at the bottom.

One Final Backup

After you have completed all of the above steps, it would be a shame if the microSD card became corrupted. I highly recommend that at this time you make another backup of your microSD card so that you will be even further along should you need to flash another microSD card.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.