Split-Domain Iceshrimp setup with Apache

Posted on October 31, 2024

I had to help setup an Iceshrimp (specifically the JavaScript version, although I’m sure this config is also applicable to the upcoming .NET version once it is ready for production) instance running behind an Apache server. It is a fairly straightforward process, but there are some caveats that lead to issues that are not entirely obvious to debug.

This guide assumes you have Iceshrimp already running at localhost:3000, and are using the AccountDomain example.com and the WebDomain fedi.example.com. This means that you’re accessing your instance at fedi.example.com, while your username would be user@example.com.

Installing the Apache modules §

The first step is to enable all the needed Apache modules:

a2enmod rewrite
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel

Setting up the Account Domain §

In the VirtualHost for example.com, add the following code:

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteRule ^/\.well-known/webfinger https://fedi.example.com/.well-known/webfinger [R=301,L]
  RewriteRule ^/\.well-known/host-meta https://fedi.example.com/.well-known/host-meta [R=301,L]
  RewriteRule ^/\.well-known/nodeinfo https://fedi.example.com/.well-known/nodeinfo [R=301,L]
</IfModule>

The account discovery process works by remote instances querying webfinger on example.com to discover the user’s account actually lives. Iceshrimp provides its own webfinger service, so we just redirect requests to Iceshrimp, see for instance the GoToSocial documentation for a more detailed description.

Setting up the Reverse Proxy §

Then, we configure the VirtualHost for fedi.example.com and add the following to the configuration:

RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:3000/$1 [P,L]
AllowEncodedSlashes On
ProxyPreserveHost On
ProxyPass "/" "http://localhost:3000/"
ProxyPassReverse "/" "http://localhost:3000/"

The Rewrite rules ensure that WebSocket requests actually pass through the proxy. If we do not do this, the UI just doesn’t react to events such as new posts hitting the timeline, or it doesn’t even register any likes or boosts on posts. The AllowEncodedSlashes On rule enables URLs with encoded slashes to pass through the proxy to the Iceshrimp backend, removing that line leads to custom emoji from remote instances not showing up. Finally, the ProxyPreserveHost On rule ensures the server actually federates, otherwise the account page will return a 400 code when accessed by an external instance while the instance appears to be perfectly functional to users of the Iceshrimp frontend.

Conclusions §

In general, this setup shows that hosting Iceshrimp on Apache is possible, but I still wouldn’t recommend it unless you have good reasons to be using Apache (such as other services running on the same host as your Iceshrimp instance). Almost no one uses Apache for this purpose these days, so you may be better off using nginx or caddy.