Part I: Raspberry PI, Dynamic DNS, Apache 2 (Virtual Hosts and Reverse Proxy)

In Ersilia, to establish the relationships that sustain the city’s life, inhabitants stretch strings from the corner’s of the houses, white or black or gray or black-and-white according to whether they mark a relationship of blood, of trade, authority, agency. When the treads become so numerous that you can no longer pass among them, the inhabitants leave: the houses are dismantled.

Italo Calvino “Invisible Cities”

This article stems from a number private queries, the questions being mostly twofold: How to ensure that a private web server is reachable per DNS (Domain Name System)? And can a private web server maintain more than one website? Furthermore, these questions where as a rule concerned with Raspbian, Apache2 as well as any cloud or file sharing software had already been installed.

Raspberry Pi are especially useful as private cloud or photo sharing application platforms. They’re cheap, silent and economical, while being relatively easy to install and maintain. Web applications such as OwnCloud, NextCloud, PicApport, Piwigo, RoundCude, DokuWiki and many others lend themselves naturally to Raspbian.

Dynamic DNS
Every machine in the Internet has a public IP address.  Some are fixed and unchanging, others are changed intentionally in regular intervals. Most private Internet connections will be of the latter type (addresses which are changed at regular intervals). This is a problem. How to ensure that a private server is still reachable even though and despite of regular IP changes. The answer is DNS or more precisely dynamic DNS. There are a number of free DNS providers (This article here describes a few) available.  Alternatively, most commercial web service providers also provide dynamic DNS.  So a decision has to be made, free or commercial DNS provider and then there are still two questions open:
Firstly, how to (regularly) retrieve your public IP?
Secondly, how to inform your DNS provider about any changes?

Retrieving your public IP address
Any external (external insofar as that the server is not within the LAN) website knows your public IP address. They have to if they wish to communicate with you. There are also servers whose soul purpose it is to communicate this public IP back to the requester.  https://wtfismyip.com/, https://api.ipify.org/ or http://checkip.dyndns.org/ to name just a few such servers. So retrieving the public IP isn’t a problem. Now the only question is how to automate this request so that the public IP address can be retrieved in regular intervals. There are various possibilities: BASH, PERL, Ruby, C#, Python, Javascript, JQuery, NodeJS to name but a few. Here’s an example in BASH

#!/bin/bash
IP=$(curl --silent 'https://api.ipify.org')
echo $IP

This code snippet will retrieve the public IP address. But it won’t inform the DNS provider of any changes.

Regularly informing the DNS provider of any changes
Each provider will have different ways of automatically updating a DNS record. The web service provider STRATO serves here as an example. STRATO provides a DNS update web page for it’s customers. The following example retrieves the public IP and sets two separate DNS records for two different sites. Both sites being housed on the same PI.

#!/bin/bash

# Get the public IP address
IP=$(curl --silent 'https://api.ipify.org')
# Which Sites get should be reachable over this IP
HOSTS="ownCloud.travers-berlin.de dokuWiki.travers-berlin.de"
# User Credentials
USER="XXXXXXXXXXXX"
PASS="XXXXXXXXXXXX"
# Strato web page
URL="https://dyndns.strato.com/nic/update/nic/update"

# Now set the DNS record for all websites.
for HOST in ${HOSTS}
do
  QUERY="?system=dyndns&hostname=${HOST}&myip=${IP}"
  curl --ssl --user ${USER}:${PASS} ${URL}${QUERY}
done

This script must now run in regular intervals and this can be achieved using the Linux scheduling daemon crond. The script has to be saved. The directory and name are arbitrary, something like /root/ipUpdate.sh is more than sufficient. Crond reads crontabs (cron tables) and executes the programs listed. The criteria for running are listed together with the program in the crontab. Each user has his or her own crontab. To create a crontab for root, use the following command:

pi :~ $ sudo crontab -e -u root

and add the following table entry:

0.15,30,45 * * * * /root/ipUpdate.sh

This will ensure that ipUpdate.sh will run every 15 min.

Public Domain Mark