Select Page

How to Set Up a Raspberry Pi Development Server

How to Set Up a Raspberry Pi Development Server

Starting with a fresh install of Raspian:

sudo apt update

sudo apt upgrade

sudo apt install apache2

sudo apt install php

sudo apt install mysql-server php-mysql (mariadb-10.0)

sudo apt-get install certbot python-certbot-apache
sudo certbot --apache

Next, you just set up your MariaDB database and install WordPress.

cd /var/www/html

sudo rm *

sudo wget

sudo tar xzf latest.tar.gz

sudo mv wordpress/* .

sudo rm -rf wordpress latest.tar.gz

Give Apache access to the WordPress folders and files:

sudo chown -R www-data: .

Set up MySQL/MariaDB:

sudo mysql_secure_installation

You will be asked to Enter current password for root (enter for none): Since we’re only setting this server up for testing and development purposes on a local network, I’ll go ahead and enter my root password. In a production environment, you’ll definitely want a strong DB password, different than the root password.

Next, you’ll see something like, you've alredy set a root password, so there's no need to update it (but you can still update it here if you like) press enter.

Remove anonymous users : y

Disallow root login remotely : y

Remove test database and access to it : y

Reload privilege tables now : y

You should see: All done! Thanks for using MariaDB!

Create a WordPress Database

sudo mysql -uroot -p then enter your root password (or DB password if you set it up differently in the mysql_secure_installation command.)

Next you’ll see the Maria DB shell. Your prompt will look like MariaDB [(none)]>. Create a new database named wordpress

create database wordpress;

Mind the semicolon- it’s required.

If this was successful, you’ll see Query OK, 1 row affected (0.00 sec)

No you can grant DB privileges to root. Replace PASSWORDGOESHERE with your password.



Exit with CTRL + D

Come up with a name for your dev server

I’ll be using as my example.

Note: At the time of this writing, I own, but you can use literally any URL you want. You don’t have to own it. (I think may be an exception. They’ve got some fancy code going on and I wasn’t able to get my /etc/hosts to cooperate in my testing.) More on that in a sec.

Configure static IP address

Next, set your static IP address. You can do this by editing one file. Open it by typing sudo nano /etc/dhcpcd.conf

Inside the file (I made a comment above these lines, so I know what I typed if I open this file again later) add the following lines:

#Matt's static IP configuration:
interface wlan0
static ip_address=
static ip6_address=fd51:42f8:caae:d92e::ff/64
static routers=
static domain_name_servers= fd51:42f8:caae:d92e::1

So in my case, I made my static IP address Double check your router and network settings for an acceptable range of IP addresses to choose from.

Configure /etc/hosts file on your laptop

Note: You’ll have to edit the /etc/hosts file for every computer on your local network that you’ll be accessing your dev server from. In most home network dev server setups, this will just be a single computer.

Drop the following line at the very bottom of the file ON YOUR LAPTOP or DESKTOP and be sure to replace the IP address with the static IP you just configured in the previous step:

sudo nano /etc/hosts

## Raspberry Pi Server Address ##

WordPress Configuration

You can either leave your keyboard/mouse/monitor plugged into your pi, and go to localhost in a browser, or grab a different computer on your local network and go to the domain name you set up in /etc/hosts. In my case, it’s You should see the WordPress setup screen like this:

  • Choose your language
  • Click Let’s go!

Fill out your DB information:

Database Name:      wordpress
User Name:          root
Password:           <YOUR PASSWORD>
Database Host:      localhost
Table Prefix:       wp_

Click ‘Submit’ and ‘Run the install’.

Once you’re finished, drop into Settings > Permalinks. Select ‘Post name’ and hit ‘Save Changes’

Configure SSL Encryption

sudo apt install openssl

Create a root key that will be able to generate ssl certs. You can do this by running: mkdir ~/SSLcerts && cd SSLcerts and then openssl genrsa -des3 -out rootCA.key 2048

Create a root certificate by running openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem

Now you’ll need to trust your root CA on every machine you’ll be accessing the server with. To do this, you’ll need to copy the rootCA.pem file to your SSL trusted certs directory on every machine on your local network.

sudo scp pi@ /etc/ssl/certs

Next, create an OpenSSL configuration file for us to use with our server. sudo nano ~/SSLcerts/ and paste the following into that file, and save.

default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

CN =

Next, create a file called v3.ext and paste some more code into it. This will allow us to create a public certificate file.

sudo nano ~/SSLcerts/v3.ext and pasted the following:

keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

DNS.1 =

Next, we’ll use the configuration options we pasted into deadpool3.csr.cnf to create a key file for To do this, type: openssl req -new -sha256 -nodes -out -newkey rsa:2048 -keyout -config <( cat deadpool3.csr.cnf )

Next we need a domain certificate:

openssl x509 -req -in -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out -days 500 -sha256 -extfile v3.ext

That’s all the files we need to make! Lastly, we need to move the .key and .crt files into a directory where apache2 can access them. In that case, I’m just ging to create a new file in my apache2 root directory like so: sudo mkdir /etc/apache2/ssl

Next, just copy them over. sudo cp ~/SSLcerts/{,deadpool3.crt} /etc/apache2/ssl

And that’s SSL certs generated! Done!

Next, you’ll need to tell Apache where those new SSL keys and certs are. To do this, you’ll need to modify the <VirtualHosts> file. By default, you should have one file named /etc/apache2/sites-enabled/000-default.conf. We’ll use this as a template. sudo cp /etc/apache2/sites-enabled/000-default.conf /etc/apache2/sites-enabled/

We’ll want to change a few things and add some stuff. At the very top, inside the <VirtualHost> tag, you’ll want to change the port number to 443. Next we’ll add the following to line 2 (above the very first commented out line):

sudo nano /etc/apache2/sites-enabled/

No add these lines just below the opening <VirtualHost> tag

#Custom SSL setup
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/deadpool3.crt
SSLCertificateKeyFile /etc/apache2/ssl/

Next, remove the comment (#) in front of ServerName and replace with your server name (in my case, The remaining defaults should do fine for our purposes.

So at the end, your <VirtualHost> file should look something like this:

<VirtualHost *:443>
	#Custom SSL setup
	SSLEngine On
	SSLCertificateFile /etc/apache2/ssl/deadpool3.crt
	SSLCertificateKeyFile /etc/apache2/ssl/
	# 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  last resort to host regardless.
	# However, you must set it for any further virtual host explicitly.

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html

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

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configureation 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 only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf

Next, we’ll need to take a look at the master apache2.conf file. sudo nano /etc/apache2/apache2.conf. This is a super well-commented out file, so it should be largely self-explanatory. We’re going to scroll down until we find the <Directory> tag for /var/www/. Make sure that the AllowOverride parameter is set to All. Your <Directory> tag should look something like this:

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride All
	Require all granted

sudo a2enmod rewrite

sudo a2enmod ssl

sudo systemctl restart apache2

Other helpful resources

Oh wow

SUPER Apache2 guide:

Check out more articles

Create a Custom API Endpoint in WordPress

Creating a custom endpoint in WordPress to check for plugin updates involves several steps. This process includes setting up a custom REST API endpoint, creating a function to handle requests to this endpoint, and ensuring that the response contains the necessary...

Deploy WordPress Updates from a Private Repository

To push code to a private repository and trigger a pending WordPress update badge, you need to follow a systematic approach involving version control, continuous integration/deployment, and the appropriate use of WordPress hooks and filters. Here’s a step-by-step...

How to Generate a Ranger Config File

ranger --copy-config=all This will copy all the default config files from /usr/local/lib so you can make edits without messing anything up. Huge shout out to for explaining this and so much more. Took me a...

First Open Source Contribution

Surprise! I genuinely did not plan on making my first ever open source contribution today. In fact, I didn't plan on a lot of things happening this week at all. I recently got an awesome opportunity to work on a site that is being hosted on a platform called Pantheon,...

How to Exclude Specific Posts and Pages from WP_QUERY

For the sake of having something to work with, let's suppose we've got the following query:In this query, inside the $args array, there's a special parameter that allows you to exclude specific posts and pages from the query. This parameter is called post__not_in and...

Configure SSH For Password-less Connections

Preamble I'm slightly embarrassed to admit this, but it was a long time before I figured out how amazing this little file is and how exactly to put it to good use. The file I'm talking about is the SSH config file. By default, when you first connect to a server via...

WordPress Site Stuck in Maintenance Mode

Plugin Error Code 500 During Update While I was updating a WordPress plugin locally, something happened on my local server to trigger a 500 error code as the plugin was updating. On the frontend, I refreshed the page and was greeted with "Briefly Unavailable for...

Creating a WordPress Plugin Downloader

How it Started I was recently tasked with the challenge of creating a WordPress theme generator. The idea being, instead of writing your style.css file from scratch, you'd be able to just answer a few simple questions about how you'd like your theme set up, and those...

Fix Audio on XFCE Chromebook

The Problem After moving from GalliumOS to Xubuntu, I noticed that playing YouTube videos on both Firefox and Chromium would result in decent playback for a few minutes, but suddenly the audio would turn into a solid beeping tone while the YouTube video displayed the...

Adjust Trackpad Sensitivity XFCE

xinput set-prop "Elan Touchpad" "Synaptics Finger" 1 1 1 What are the values 1 1 1? This sets the sensitivity as close to the original ChromeOS as possible. Larger numbers will decrease sensitivity of various aspects. I never looked into which individual value...

Looking for a place to host your next project or design?

Use this link to get your first 4 months of WP Engine for free: WP Engine – Plans (With 4 months free)