Self-Hosting a Website With a Raspberry Pi

Return to Homepage

Running your own webserver feels great, teaches you lots, and gives you nerd credit. Here's a crash course on how to do it!

Table of Contents

  1. First step: Materials and first setup
  2. Setting up a webserver
  3. Getting a domain name
  4. Virtual hosts
  5. Getting HTTPS
  6. Setting local hosts
  7. Editing your site
  8. More resources

Materials and setup

Before we begin, you'll need a couple of things.

The computer

The server that used to run this website! A Raspberry Pi 4 (2GB). I've since upgraded to a 4GB model with a fan case.

First and foremost is a computer to use as a server, and a home Internet connection. This guide is specifically for the Raspberry Pi and Raspbian GNU/Linux, but the steps will be similar for any computer running Debian or a Debian-based distro like Ubuntu, Mint, etc.

Assuming you're using a Pi, you'll need to install Raspbian, specifically Raspbian Buster Lite, which is headless, i.e. it has no graphical user interface (it's text-only). If you don't know how to install Raspbian, refer to this part of the Raspberry Pi's documentation.

For this next bit, you'll want to use a monitor and a keyboard with the Pi, but before this guide is finished, you'll be able to log into it remotely. You won't need a mouse because there is no GUI.

You need to do two things: First is to set up your Pi's network connection (if it isn't connected via Ethernet - if it is, skip this paragraph completely). You can use this part of the Raspberry Pi docementation to help with that.

Next, you need to enable SSH. SSH stands for 'secure shell', and provides a way to log into the system remotely. To do this, refer to this part of the Pi's documentation.

All that's left is to get the Pi's IP address. Run the command ifconfig. If you've connected the Pi to the Internet with an ethernet cable, look for eth0 on the left of the output, and find inet addr:{IP ADDRESS} in the paragraph next to it, and write down the IP. If you've connected over wi-fi, do the same but look for wlan0 instead.

Now we have connected the Pi to the Internet, enabled SSH, and found our IP. Basic setup of the computer is complete.

The network

The computer is set up, but now we need to configure our network to send Web traffic to the Pi instead of ignoring it.

Go to your router. Examine it. Somewhere on the router, there should be a sticker that has three things on it: an IP address, a username, and a password. These are your router's administrator credentials. While connected to your network, open a browser and enter the IP from the side of the router into the address bar, and then log in with the username and password. You are now logged into your router. Note: If you can't find the sticker, call your ISP. Or buy a new router.

Now that you're logged in, look for a button or menu that says something along the lines of 'port forwarding', 'firewall', or the like. This bit varies across routers, so if you struggle here it may be worth looking up the documentation for your router. The goal, no matter the steps: Configure your router to send traffic from, or 'forward', ports 80 and 443 to the IP address of your Pi. On my router, I had to 'add a rule', enter the IP address of the Pi, and set the start and end ports to 80. I then had to repeat for 443. Port 80 is used for HTTP traffic, and 443 is for HTTPS.

If you managed to make it this far, you have finished the hard bit. It gets easier from here.

Some software for your personal machine

This last bit is about installing an SSH client, which will allow you to log into the Pi remotely. If you use Micro$oft Window$, I suggest PuTTY. After installing, simply enter your Pi's IP and click 'Connect'. If you're on MacO$, or you're a real champ using a distribution of GNU/Linux, simply open your system terminal and type ssh pi@{PI's IP ADDRESS} (leave out the curly braces).

This completes our basic setup section. You can now leave the Pi plugged in and running, but remove the mouse and keyboard. This is great because you can keep the Pi anywhere - on a desk, in a TV stand, anywhere that's out of the way.

Setting up a webserver

SSH into the Pi. We will now install the webserver, which is the program that will deliver, or 'serve', your Web content to the users' computers, or 'clients', upon request. (The italicised words are server jargon.)

The webserver we will install is called Apache, which is the most widely-used webserver on the Internet. Recently, NginX has been gaining traction, but I am unfamiliar with it, and Apache is great and has excellent documentation. To install the webserver, run sudo apt update followed by sudo apt install apache2 -y

You have now installed Apache. On your machine, in your web browser, enter the IP address of your Pi into the address bar. It should bring you to a webpage - your Pi has served you a webpage! For any troubleshooting related to this step, refer to this page in the Pi's documentation.

Registering a domain name

This part is straightforward enough, but costs money. Luckily it isn't very much, and if you live in a country with a top-level domain that they like to promote (examples include .ca for Canada, which I use, and .de for Germany, etc.), it will likely be even cheaper.

First you need to find your network's public IP address. The easiest way to go about this is to go to any search engine and type "what's my IP". If it doesn't immediately show up, click on the first link that shows up. No matter what Dr. Phil told you, it is absolutely not dangerous for someone to know your public IP. Every website you access is given it, including this one. It is safe.

Note: If you're on a residential connection, this might change from time to time. No worries - if it does, simply edit the settings we are about to set so that the public IP is accurate.

Now is the part that involves throwing money around. Go to a domain name registrar, like GoDaddy or Epik or anything. Make an account, find a domain you like, and register it. Usually there are promotions where you get two years for somewhere around $20. I'm using Canadian dollars, so if you're a yank it may be even cheaper.

Once you've bought your domain name, you need to set up its DNS (domain name system) settings. Basically, you need to tell it what IP it's supposed to send people to. Add an 'A' record, set 'Host' or 'Name' to '@', and set 'Value' or 'Points to' to your public IP address. Once you set that it should take the DNS server up to an hour or two to sort itself out.

Note: Don't try to test this from your own network. Try viewing the test page from a smartphone on LTE and not your network. We'll get to actually being able to properly access your site in a minute

Virtual Hosts

This part is important for the next step. So far we have a Raspberry Pi that is running an Apache webserver, and we have a domain that is pointing to it. But the server doesn't really *know* what its domain is; it's just serving up a default. We need to make a profile, or a virtual host for our site.

Note: For this section, I'll be using as my domain. Replace this with your own domain.

First, you'll want to change the ownership of /var/www so that you can change things. To do this, run sudo chown -R pi:pi /var/www/ . Now, delete the test site, which should be in a directory called /var/www/html/  . To do this, run rm -r /var/www/html/ .

Note: If any of these commands return 'permission denied', stick a sudo in front of it and that should do the trick.

Next, we need to make two new directories - one for your site, and a subfolder for your site's files. Run mkdir /var/www/ followed by mkdir /var/www/ . Now, change into that directory with cd /var/www/ .

Now, create a copy of the default host file to use for our site. Run sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/ .

Now edit the copy by running sudo nano /etc/apache2/sites-available/ , and make it look like this:

<VirtualHost *:80>
	ServerAdmin webmaster@localhost

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

Naturally, remember to replace with your domain name.

Back in our folder we just made, make a blank homepage by running touch index.html .

The last step for this section is to run sudo a2ensite to enable our new site, sudo a2dissite 000-default.conf to disable our default site, and sudo systemctl reload apache2 to restart Apache. Now if you visit the website from a cellphone or from outside your network, you should see a blank page.

Getting HTTPS

HTTPS allows clients to have an encrypted connection to your site. Nowadays, not having HTTPS makes your site look suspicious and unprofessional. But luckily, it's incredibly easy to get an HTTPS certificate, and it's free forever, thanks to the Electronic Fronier Foundation and their tool called Certbot.

This is easy. Don't follow the instructions on their site because it tells you to use snap, which is stupid. Simply run sudo apt install certbot and then once it's done run sudo certbot --apache . Follow the instructions to obtain a certificate for your domain. When prompted, select the option to make all traffic redirect to HTTPS.

Your local hosts file

This part will allow us to actually view our site from a computer on our network. On your local machine, you need to find your hosts file. If you're on Window$, it's this file:


If you're on Linux, it's simply in /etc/hosts and on MacO$ it's at /private/etc/hosts .

Note: You'll need to be editing it with administrator privileges on Windows, or sudo on Linux. I'm sure MacOS has a similar system.

Now simply add a line with {IP OF PI} where {IP OF PI} is the IP of your pi, and is your domain. Restart your Web browser and enter your domain. You should see your blank page!

Editing your site

Now that everything is in order, you can create your website in your /var/www/ folder. I suggest making a link from your home folder to that one. If you don't know HTML, use the modern HTML/CSS guide that I wrote!

More resources