Make your own Raspberry Pi Webserver

Introduction

Do you wan’t to have your very own webserver where you can host your site without the need for third party hosting services that offers limited control of the server configuration? This tutorial will teach you how to setup your own webserver from scratch on a Raspberry Pi! A Raspberry Pi is a fully functional onecard computer with USB, HDMI output, ethernet-port, sound-output and even an IO-interface. All this for just around 40€.

Advantages & downsides

The advantages of this are obvious; it’s cheap, fast and easy to manage. The downsides comes with the hardware limitations of the Raspberry Pi itself. Obviously you get what you pay for, and a Raspberry Pi does not have the same CPU or disk speed capabilities as a regular server, which makes it inadequate for hosting any larger site with lots of heavy backend logic. For instance a regular server that used a SSD drive usually have a read speed of ~550Mb/s while a micro SD card uses clocks in at around 80Mb/s. But for a simpler site it is good enough, a website that is not too heavy will hardly be affected by this anyway. You may also just consider this tutorial for educational purposes as it pretty much covers the basics of setting up a public Linux distribution webserver.

What you need

The recommended version is the new Raspberry Pi 2 which has a much better CPU than the regular Raspberry Pi B+. An important thing to note is that the Raspberry Pi 2 does not come with any accessories, which mean you have to buy a separate micro USB cable (used for power) and a micro SD card (which is used instead of a harddrive). You also need a USB cardreader if you do not already have a computer that can read micro SD cards. I assume that you already a keyboard and a monitor 🙂

Get started

Setup the OS

1. Download a copy of the distribution you wan’t to use. I am using Raspbian Wheezy which can be found here: https://www.raspberrypi.org/downloads/raspbian/. Do not use Raspbian Jessie as this is meant for desktop use, unnecessary for a server.

2. Extract the image to your micro SD-card. This can be done for instance with the software “Win32 Disk Imager” which can be found here: http://sourceforge.net/projects/win32diskimager/

3. Put the micro SD-card into your Raspberry Pi. Plug in a keyboard and use a HDMI-cable to connect to a monitor or TV. Plug your Raspbery Pi into your router. Lastly plug in the micro USB-cable for power which will turn the Raspberry on.

4. After the OS have finished loading you will be prompted to login. The default user is named “pi” and the default username is “raspberry”. Login with this user.

5. Change password for your used by using the command

passwd pi

6. Enter your new password and then confirm it.

Update and upgrade your OS

1. To make sure your dist is up to date run the following commands:

sudo dpkg-reconfigure tzdata
sudo apt-get update
sudo apt-get upgrade

2. Configure the clock by using the following command (replace parts as necessary):

sudo date --set="30 December 2013 10:00:00"

Keep the Raspberry Pi firmdate up to date

1. Run the following commands

sudo apt-get install ca-certificates
sudo apt-get install git-core
sudo wget https://raw.github.com/Hexxeh/rpi-update/master/rpi-update  -O /usr/bin/rpi-update && sudo chmod +x /usr/bin/rpi-update
sudo rpi-update

2. Restart the Raspberry

sudo shutdown -r now

Setup SSH

Obviously it is not very practical to have to manage your webserver by working with it directly. By setting up SSH on your Raspberry you can connect from another computer and work remotely.

1. Type the command

ifconfig

You should see something that looks like this:

eth0  Link encap:Ethernet  HWaddr b8:27:XX:XX:XX:XX
      inet addr:192.168.XXX.XXX  Bcast:192.168.XXX.XXX  Mask:255.255.255.0
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:88025091 errors:0 dropped:0 overruns:0 frame:0
      TX packets:107766303 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000
      RX bytes:1275557050 (1.1 GiB)  TX bytes:1407571910 (1.3 GiB)

In this case the IP-address of the Raspberry Pi is 192.168.XXX.XXX. This means that you can connect via SSH to this IP from another computer. Do note though that this is a local IP, so you can only connect to it via a computer on the same network.

2. Enable SSH:

sudo /etc/init.d/ssh start

3. Restart your Raspberry:

sudo shutdown -r now

4. Now you can connect to your Raspberry from another computer! You can unplug monitor and keyboard from your Raspberry. Open up a terminal on your regular computer and connect to your Raspberry:

ssh pi@192.168.XXX.XXX

If you are using Windows you can use a ssh client like PuTTy. Personally though I prefer to use Git Shell which comes which “Github for Windows” (can be downloaded here: https://desktop.github.com/). Git Shell is an extension of Windows Powershell which can be used pretty much like a Linux terminal.

Installing the webserver

Now that you are connected via SSH to your Raspberry it is time to setup the webserver itself. In this tutorial I will be using Apache webserver with php, however you are obviously free to use whatever webserver you want.

1. Install using the following command:

sudo apt-get install apache2 php5 libapache2-mod-php5

2. Restart the service:

sudo /etc/init.d/apache2 restart

3. Now that Apache is running you should be able to access it via a browser with the IP: 192.168.XXX.XXX. You should see a simple page that says “It Works!”.

Your webserver is now and up running. The following steps will go through additional configuration you may or may not want depending on your needs.

Advanced (sort of) configuration

Access the web

What good is a webserver if you cant access it from the internet? If you have followed the tutorial up to this point you have a fully functional Apache webserver running on a Raspbian Wheezy distribution with support for php. It can be accessed when working on the same local network but is not yet suited for hosting any open website. In this section I will cover how to fix this.

There are several different solutions for this but the easiest one is to just redirect traffic to your Raspberry Pi by configuring your router that the Raspberry is connected to.

1. Login to your routers web interface

2. Look for “port forwarding” in the menus. Where to find this depends on what router you are using but it is usually quite easy to find.

3. Setup rules for your router to redirect traffic on port 80 (HTTP) and 443 (HTTPS) to 192.168.XXX.XXX

You should now be able to access your website in /var/www/ by entering the public IP of your router in a browser. You should be able to find your routers public IP somewhere from the routers web interface.

Connect with a domain name

Now that you can access your website via your routers public IP you might wan’t to connect a domain name to this IP for easier access. Obviously you have to buy a domain name from a site such as godaddy.com. When you own a domain, mydomain.com, you should configure the DNS settings for the domain name as follow:

    Subdomain    Type    IP
    ----------------------------------------
    wwww         A       

Dynamic DNS

If you’ve come this far you now your domain name mydomain.com now successfully leads to your website hosted on your server. But a problem with this setup is that the DNS configuration is static. If the IP of your router changes, which it most likely will for instance when restarting it, you will no longer be able to access your website via your domain name without manually updating the DNS configuration.

To fix this you should use Dynamic DNS. Make sure that the site from where you bought your domain name offers this service. For some sites, such as binero, you have to pay extra to enable this. With a dynamic DNS service, such as DynDNS, you can update the IP of your domain name via a HTTP request which can be done from a shellscript.

1. First of all, create the file for the script:

mkdir /home/pi/dyndns
touch /home/pi/dyndns/dyndns.sh

2. Edit the contents of the file:

nano /home/pi/dyndns/dyndns.sh

Add the following content:

#!/bin/bash

curl --user [username]:[password] [dyndns service update url]?hostname=www.mydomain.com&myip=

curl --user [username]:[password] [dyndns service update url]?hostname=mydomain.com&myip=

You should edit the contents as suitable. Exactly how the URL is structured for instance varies a bit depending on what dynamic DNS service you are using. By leaving the “myip” parameter value empty the target IP will automatically be set. The username and password should be for the domain service you are using such as godaddy.com. You should test out that the script is working by running:

sh /home/pi/dyndns/dyndns.sh

3. Assuming your script is working and is updating your DNS configuration correctly you can now create a cronjob for this script. A cronjob is a scheduled job or action that the OS handles, much like “task scheduler” in Windows. Run:

crontab -e

4. Scroll down to the end and add the following line:

*/5 * * * * sh /home/pi/dyndns/dyndns.sh

Save and close. This will make it so that the dyndns.sh script is run every 5 minutes automatically. You may change the interval to suit your own preference.

Now that you have a domain name with dynamic DNS setup you may from now access your server from any other computer with the following command:

ssh pi@mydomain.com

Free alternatives for domain and dynamic DNS

The solution described above requires that you pay for a domain name and a dynamic DNS service. However there are free alternatives that I can recommend, such as http://www.noip.com/ and https://www.duckdns.org/. With these services you may get a free domain name like mydomain.no-ip.org or mydomain.duckdns.org.

Several websites on same server

Perhaps you wan’t to host more than one website on the same server. For instance on my Raspberry Pi server I have several websites hosted, each with it’s own folder in /var/www and all use the same dynamic DNS service which means the same IP is assigned for each site. So how does the DNS setup work if they all point at the same IP? My way to solve this is to setup some rules in your Apache configuration.

Let’s say you have the websites website1.com and website2.org. They are located on the server in the folders /var/www/website1 and /var/www/website2. To make this work the configuration file for Apache found in /etc/apache2/sites-available/default should be configured to contain:

<VirtualHost *:80>
    ServerAdmin webmaster@website1.com
    ServerName *.website1.com
    ServerAlias website1.com *.website1.com
    DocumentRoot /var/www/website1

    <Directory />
        Options FollowSymLinks
        AllowOverride All
    </Directory>
    <Directory /var/www/website1>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    ErrorDocument 404 "/var/www/website1/404.html"
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin webmaster@website2.org
    ServerName *.website2.org
    ServerAlias website2.org *.website2.org
    DocumentRoot /var/www/website2

    <Directory />
        Options FollowSymLinks
        AllowOverride All
    </Directory>
    <Directory /var/www/website2>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    ErrorDocument 404 "/var/www/website2/404.html"
</VirtualHost>

With this Apache will know where to get content from depening on the URL that the user visits.

Now all you have to do is to restart your Apache server:

sudo /etc/init.d/apache2 restart

Overclock your Raspberry Pi (Optional)

It is possible to overclock the CPU of your Raspberry Pi using the built in options menu. I have not benchmarked in any way to see how this may benefit server response times so I cannot tell you how much you gain from this (if at all) but it most likely has to with what you do with your server.

1. Run the command:

sudo raspi-config

2. Go to “Overclock”

3. Choose how much you wan’t to overclock. Note that you do this at your own risk.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s