Home lab setup


I run a server on an old Macbook, and I host a couple service on it. This gives a few details of how it's done.


I use Tailscale to set up a mesh network that gives the server a static IP regardless of where it goes. On another device that is connected to the VPN, I can access all of the ports on the server directly without having to deal with port forwarding. This is convenient for when the Macbook is moved to another location/network, and essentially no reconfiguration is required when doing so. I also use Tailscale to connect to the server directly (ssh/VNC) if required.

For convenience and for a few services that I want to be publicly accessible, I have a couple of the ports mapped to a subdomain on this site (e.g., the server's homepage is accessible at server.jshen.dev). I do this using Cloudflare Tunnels, which are sort of like a reverse proxy but without the need for port forwarding (otherwise I would probably just set up a reverse proxy with nginx).


To manage and play my media, I use Jellyfin, which I find to be slightly better than Plex (although I also have a Plex server running). I organize movies with Radarr and TV shows with Sonarr. I have a Jellyseerr (Jellyfin:Plex; Jellyseerr:Overseerr) instance running that allows me and friends/family to easily request new movies/shows. Jellyseerr integrates very nicely with Jellyfin, Radarr, and Sonarr. To continue the *arr stack, Bazarr automatically gets subtitles for any movies/shows in my collection.

Making the Jellyfin instance publically accessible is a particularly interesting case. As mentioned above, Cloudflare Tunnels would be perfect for this. However, using Tunnels proxies traffic through the Cloudflare servers, which is against their terms of service. As such, I need to find an alternative for connecting to the server. Why not just connect directly to the server? Unfortunately for me, I use Princeton's network, which is extremely hostile, so much so that I can't make a direct connection to my server (and they do not hand out IPv6 addresses, which might solve the problem). This means that the requests go through Tailscale's DERP servers, and the bandwidth is severely limited. This is a problem for streaming video. Cloudflare Tunnels happens to resolve this problem, because I can make a strong connection to their servers from behind this network and from the server. Taking inspiration from this, I set up a free AWS EC2 instance. I then set up NGINX on the EC2 instance to reverse proxy from the server (over Tailscale, because the EC2 instance can connect directly to the server) to the public subdomain. Now I can easily and quickly connect to the EC2 instance from anywhere.


I run a Synapse server at matrix.jshen.dev. I am running this on bare metal, and have found the documentation on setting this up to be great. I also have a few bridges running: mautrix-facebook; mautrix-whatsapp; and mautrix-imessage. These also run bare metal, and I manage the bridges with the pm2 daemon process manager. All this allows me to use Element as a unified messaging app.