Graffiti of Mark Zuckerberg

Set up your own XMPP server on a Raspberry Pi in under five minutes

David Rutland
David Rutland Self-hosted

Trust is a hard thing to come by in the 21st century, and relying on third party services to keep your private communications private is a mug's game.

Right now, the most popular instant messaging app in the world is WhatsApp - a proprietary service owned and operated by Meta - the company formerly know as FaceBook - that routinely coughs of hundreds of millions in fines to pay for its egregious privacy-related offences.

In case you needed reminding, Facebook founder, Mark Zuckerberg, once referred to unsuspecting users who handed over their data to his nascent company as "dumb fucks". The Zuck's comments were made in 2004 - a more innocent time - but nearly two decades later, WhatsApp has more than 2 billion active users worldwide, sending 100 billion messages daily as well as making video calls, sending voice notes, and of cause, the ubiquitous duck-faced selfie.

That's a lot of data to entrust to a company that makes its money from scraping up data about your life, tracking you across the internet (and in the real world), and then selling that data on.

For us, it's not acceptable, and despite Meta's assurances that our data would be perfectly safe with them, we'd prefer not to take the risk. More to the point, we'd prefer a solution which kept our data and messages securely under our control.

WTF is Snikket?

You've probably never heard of Snikket, and none of your friends use it either.

Snikket is an easy-to-deploy XMPP (Extensible Messaging and Presence Protocol) server that can be up and running in virtually no time on a Raspberry Pi, VPS, or any random PC hardware you stumble across.

With Snikkett, you can create, own, and administer your own messaging service for friends, family, and casual acquaintances.

By running an XMPP instance on your own hardware, you can install the Snikket app on your devices, and communicate with your other Snikket users without any danger of being snooped on by predatory corps, or other interested parties. You'll also have the option of sending your messages unencrypted, secured with OMEMO (OMEMO Multi-End Message and Object Encryption) multi-end to multi-end encryption, or classic OpenPGP.

XMPP is capable of federating, meaning that users on your Snikket instance can communicate with users on any other XMPP instance, too. It's wild.

As you'd expect from a modern messaging app, your communications aren't limited to texts like it's 1999, and you have the full gamut of mid 21st century functionality. Send kisses to your spouse, a voice note of everlasting adoration to your paramour, a dick pic to your side-piece, and apology videos to all of them.

Snikket doesn't require much in the way of hardware to run, and a Raspberry Pi 4B will be ample for a family-sized instance. We've been running Snikket alongside an entire stable of self-hosted services including Immich, Audiobookshelf, Mealie, Pihole, Jellyfin,Nextcloud, and more. We haven't encountered any problems at all.

You'll need to register a domain name, too. We use Namecheap (affiliate link) for all of ours. 

How to install Snikket on your Raspberry Pi

Silver-cased Raspberry Pi 4B on a granite kitchen counter

We're using the Raspberry Pi because a server needs to be on 24 hours per day, 365 days per year. It needs to be reliable, and ideally, shouldn't draw a huge amount of power. The Raspberry Pi 4B pulls a mere 8 Watts - the equivalent of a low energy lightbulb, and reliability is improved by a pair of solid state drives (SSDs) in place of a failure-prone Micro SD card. Earlier models, such as the Raspberry Pi 2 and 3, can also run a Snikket instance without problems - although we haven't tried this ourselves.

That said, these instructions should work on any computer hardware from the last 15 years that you happen to have lying around making the place look untidy.

The quickstart guide on the Snikket website concisely sum up everything you need to get Snikket up and running in a hurry, although please do make sure that you read the linked page on which ports you need to open on your router and firewall.

It's only if you're running Snikket behind a reverse proxy that you'll run into trouble.

While the Snikket Operators Guide offers an exhaustive catalogue of reverse proxy example configs, you'll also need to make some changes to your docker-compose file - else Snikket will fail to initialise, and you'll see an endless stream of "Waiting for certificates" when you check the logs.

After you use Let's Encrypt to obtain an SSL certificate for your main domain, you need to mount your certificates directory as a volume in both the snikket_server and snikket-proxy containers. While you have your docker-compose.yml open in nano, take the opportunity to nuke the snikket-proxy container, too.

Our Snikket Docker Compose file looks like this:

version: "3.3"

services:
  snikket_proxy:
    container_name: snikket-proxy
    image: snikket/snikket-web-proxy:beta
    env_file: snikket.conf
    network_mode: host
    volumes:
      - snikket_data:/snikket
      - acme_challenges:/var/www/html/.well-known/acme-challenge
      - /etc/letsencrypt:/snikket/letsencrypt
    restart: "unless-stopped"

  snikket_portal:
    container_name: snikket-portal
    image: snikket/snikket-web-portal:beta
    network_mode: host
    env_file: snikket.conf
    restart: "unless-stopped"

  snikket_server:
    container_name: snikket
    image: snikket/snikket-server:beta
    network_mode: host
    volumes:
      - snikket_data:/snikket
      - /etc/letsencrypt:/snikket/letsencrypt
    env_file: snikket.conf
    restart: "unless-stopped"

volumes:
  acme_challenges:
  snikket_data:

You also need to add the following lines to snikket.conf:

SNIKKET_TWEAK_HTTP_PORT=5080
SNIKKET_TWEAK_HTTPS_PORT=5443

Start Snikket with:

docker-compose up -d

...and create an admin account link with:

docker exec snikket create-invite --admin --group default

That's it. Well done, open a browser, paste the link, and create the admin account on your server.

We found that using server aliases in our Apache conf file resulted in attached files such as photographs failing to be delivered. Setting up a seperate conf for the share subdomain, and deploying certbot against that solved the problem for us

Connect with the world over XMPP!

Snikket has it's own mobile app which is available from F-Droid, Google Play, and Apple's App store. However, it will work perfectly well with any generic XMPP client, so if you already have a favourite, or prefer the UX of a different app, feel free to use that instead.

Open the app, and you'll be asked to sign in. Your username is what you created during the admin setup, and will be in the format yourname@yourdomain.tld.

The Snikket interface is kind of sparse. You have no contacts (unless the people in your contacts lists have XMPP addresses ), but you can add contacts, create private groups, and discover channels using the big plus sign in the lower right portion of the screen.

And there are thousands of channels to join, so even if you have no friends in real life, you can still find people to talk to. A quick search for "Linux" yielded dozens of rooms dedicated to everything from Arch (BTW) to city-specific user groups. Of course, if you don't want to chat with the entire world, you can always decline to open port 5269. This will disable federation (there's probably another way to do it, but this sprung to mind as the most obvious).

To add other users to your instance, open the web admin panel at your-domain.tld/admin/, then click Manage Users, and Create new invitation. Copy the link and send it by email, text. or carrier pigeon. Alternatively, you can generate a QR code on your mobile device for them to scan.

Anyone who accepts your link will be automatically added as a contact, and as part of your circle. You can create and manage more circles through the admin panel.

Using Snikket with friends and fam

As a privacy-oriented individual, this writer has had limited options when communicating with others. Autocrypted chat over email via Delta Chat has been pretty good for sending pictures, texts, and voice notes. But the options for self-hosted video and voice calls have been limited, and either resource hungry, or fairly involved to set up.

Snikket changes that, and runs on extremely limited hardware. And you've already seen how very easy, and very quick it is to get up and running.

Voice and video calls have been (so far), flawless, high quality, and trouble free, and it's genuinely a joy to use. We've been sending memes at midnight, making calls around the clock, sharing our location with the lads, and getting some quality face-to-face with friends. 

Bear in mind though, if you have a large number of users, and anticipate that they'll all be calling simulataneously, you may need to expand the port range.

In addition to providing a first rate and effective messaging platform for the family unit, Snikket has opened up the world of XMPP. Thousands of channels, and yet more ways to waste time in the supermarket line.

It's cool. You should check it out.