February 20, 2017

How To: Host your own secure wiki with a Raspberry Pi

Hey, you! You look like you want to run a wiki on your Raspberry Pi. And if you know anything about me, I LOVE wikis. So grab that Pi that’s sitting around and let’s do this!

Using a project I’ve been developing (Dockuwiki), I’m going to show you how to go from a Pi collecting dust to a self hosted wiki that backs itself up, is accessible over HTTPS, and can be used from any device with a web browser.

Components

So what is everything we’ll use to make this work? Like any good open source project, we’re able to accomplish this thanks to the incredible work of many others. Let’s break it down!

DokuWiki

I think the DokuWiki website best describes what it is: DokuWiki is a simple to use and highly versatile Open Source wiki software that doesn’t require a database.

DokuWiki is ideal for our purposes because all data is stored as files. This makes it super easy to backup and serve. Without the need for database software, DokuWiki runs great on the resource constrained Pi.

Git

To simplify backups, we’ll be using Git to store hourly snapshots of DokuWiki. Of course, Git will detect any changes to any of the files. If the wiki isn’t modified, no snapshot will be taken for that hour. We’ll be creating a private Git repo on Bitbucket, but you can use any Git host that you’d like.

Duck DNS

Assuming that you’re hosting your Raspberry Pi wiki from home, you’ll need a URL to point at the wiki. We’ll also want the URL to continue functioning if your IP address changes. Duck DNS is a fantastic (and free!) service that allows you to register your own MYNAME.duckdns.org hostname and have your Pi periodically update the IP it points to.

Let’s Encrypt

Let’s Encrypt is another excellent project that provides TLS/HTTPS certificates for free. In order to secure your wiki data in transit, we’ll be using the service to automatically register and renew a certificate for your Duck DNS hostname.

Docker

Docker is a handy tool that allows us to define and run “containers”. You can think of containers as being a little bit like virtual machines that start almost instantly and have almost no overhead. All of the DokuWiki and Let’s Encrypt software is already configured as Docker images, so it’ll be simple to deploy to the Pi.

Raspberry Pi

The low cost computer that everyone loves! For this project, you’ll definitely want to use a Raspberry Pi 3 if possible. Generating your certificate keys the first time can take up to 20 minutes on a Pi 2. Your wiki pages will also render faster when being served up by a Pi 3.

Dockuwiki

Dockuwiki is the name of this project. It’s a mashup of “DokuWiki” and “Docker”. I tried to be cute, but I think I just came up with a name that’s hard to spell.

Steps

1. Image the SD card

First up, you’ll want to download the latest release of Raspbian Lite and write it to your microSD card. Etcher is a handy open source tool for writing OS images.

After the image finishes writing, you’ll want to unplug the microSD card and plug it back in. This should mount the “boot” partition on your computer. In order to access the Pi over SSH, we need to enable SSH by creating an empty file named “ssh” in this partition. After you’ve created the file, eject the microSD. Plug it into your Pi and boot up!

Note that this guide assumes you are connecting your Pi over Ethernet.

2. Router Config

Once you’re Pi boots, you’ll need to locate its IP address on your LAN. This is most easily accomplished by logging into your router (often found at 192.168.1.1) and looking at the DHCP leases table. Once you find this table, take note of the IP of the “raspberrypi” host.

While you’re logged into your router, you’ll want to assign a static DHCP lease to your Pi. This will ensure that the Pi always has the same IP address, even if it reboots. This is important, as next we’ll be forwarding ports.

To make your Pi accessible from the outside world, you’ll want to forward TCP ports 80 and 443 to your Pi’s IP address. These are the standard ports for HTTP/HTTPS.

3. Setup your Pi

Now that we’ve got our router set, let’s SSH into the Pi and configure it. If you’re running Windows, PuTTY is usually the go to software. If you are on Linux or a Mac, you almost certainly have the ssh command available from the command line.

SSH into your Pi’s IP. The username is “pi” and the password is “raspberry”. Speaking of passwords, let’s change that right now by executing passwd.

After setting a new password, you’ll want to expand the Raspbian partition to take up the entire SD card. You can do this by executing sudo raspi-config and selecting the top item. Once you expand the partition, select “Finish” and hit Yes to reboot the Pi.

4. Upgrade packages

Give the Pi a minute or so to reboot, then SSH back in. The next thing we’ll want to do is upgrade all of the software on the Pi: sudo sh -c "apt update; apt -y full-upgrade"

5. Install Docker

Now that our Pi is up to date, we can install Docker.

  • curl -sSL get.docker.com | sh
    • You may see: E: Sub-process /usr/bin/dpkg returned an error code (1). That’s okay!
  • sudo usermod -a -G docker pi
    • This will allow you to control the Docker software from the “pi” user account
  • sudo reboot
    • Yes, one more reboot!
6. Setup Duck DNS

At this point, you’ll want to register your Duck DNS domain name. Create an account and specify the name you’d like. After you’ve registered your name, you’ll want to setup a cron job on your Pi to keep your home IP linked to the Duck DNS name. Simply follow the instructions after click on “pi” at the top of the page.

7. Create a private git repo

Now we need a place to backup the wiki to. For the purposes of this guide, we’ll be using Bitbucket. Bitbucket will allow you to create a free private Git repository that your Raspberry Pi can sync with.

When creating the repository on Bitbucket, make sure that the “private” checkbox is selected. Otherwise all of your wiki data will be exposed to anyone who stumbles upon the repo.

For this guide, we’ll assume that your wiki’s repo is named “wiki”.

8. Create and start the Docker containers

The moment of truth! We need to fire up 3 Docker containers to make this all work. The first container we’ll start is the webserver (nginx). Run the following command:

docker run -d --restart=always --name=nginxproxy \
    -p 80:80 -p 443:443 \
    --name nginx-proxy \
    -v /etc/nginx/certs \
    -v /etc/nginx/vhost.d \
    -v /usr/share/nginx/html \
    -v /var/run/docker.sock:/tmp/docker.sock:ro \
    ericbarch/nginx-proxy-rpi

After the container starts, we can then bring up the Let’s Encrypt container:

docker run -d --restart=always --name=letsencrypt \
    --volumes-from nginx-proxy \
    -v /var/run/docker.sock:/var/run/docker.sock:ro \
    ericbarch/letsencrypt-nginx-proxy-companion-rpi

And finally we’ll start the wiki container. Make sure to fill in YOUR_BITBUCKET_USERNAME, YOUR_DUCK_NAME, and [email protected]_DOMAIN.com.

docker run -d --restart=always --name=wiki \
    -e SSH_DOMAIN=bitbucket.org \
    -e [email protected]:YOUR_BITBUCKET_USERNAME/wiki.git \
    -e VIRTUAL_HOST=YOUR_DUCK_NAME.duckdns.org \
    -e LETSENCRYPT_HOST=YOUR_DUCK_NAME.duckdns.org \
    -e [email protected]_DOMAIN.com ericbarch/dockuwiki:rpi
9. Load the wiki’s SSH key into your Git provider

Alright, now let’s grant Bitbucket access to the wiki container. Execute the following command to get the output from the wiki container: docker logs wiki

You should see YOUR WIKI'S SSH PUBLIC KEY (ADD THIS TO YOUR GIT SERVER / HOSTING SERVICE)

If not, wait a few seconds and try executing the command again.

Directly below that line, you’ll need to copy exactly from the beginning of “ssh-rsa” to the end of “[email protected]”. Browse to your SSH keys on Bitbucket and create a new key with that string you just copied.

After a few moments, your wiki should make its first backup to Bitbucket.

10. Wait for keys to be generated

Although all the software is now configured, the initial generation of keys for Let’s Encrypt will take several minutes. On a Raspberry Pi 2 this can take up to 20 minutes! You can check the progress by executing docker logs -f letsencrypt. If you still see “This is going to take a long time” as the last line, it’s not done yet!

As soon as the keys finish generating, hit “Ctrl” and “C” at the same time to exit the logs. Within a minute or so, you should be able to access and configure your new wiki.

11. Setup your freshly minted wiki!

If everything worked, you should now have your own self hosted wiki setup! Configure it by visiting the setup page at:

https://YOURDUCKNAME.duckdns.org/install.php

Congrats!

Conclusion

Thanks for reading! I sincerely hope this guide helped you and showed you how you can get started with self hosting. Of course, if you had any issues along the way, feel free to reach out to me! You can always find me @ericbarch.

-Eric

© Eric Barch 2017