DEV Community

Karthikey Hegde
Karthikey Hegde

Posted on

Self Hosting with Tailscale and Caddy

Well a couple of months ago as I was going through my normal routine, I got a notification from Google Photos, it says Your storage is 70% full upgrade your plan to get more storage, but I have already upgraded the plan a week ago how have I used 70% of it already. While I was going through these thoughts, I just saw my old laptop which I don’t use at all with 2TB of SSD and lots of computing power sitting idle in my shelf. That’s when the thought of self hosting came to my mind.

My laptop with Vito Corleone

Well whenever I have a problem it’s usually my practice to go scour through Reddit and see if anyone else have same issue, In this case I stumbled upon r/selfhosted. I went around looking for Google photos alternatives and found immich, It seemed too good to be free so I just went around their GitHub and checked if I am not dealing with paid licensing.

Setting up immich was very easy they had a very good documentation on How to setup immich with Docker Compose in their website, and within two minutes immich was up. With my slender networking knowledge I thought I can just port forward port where immich is running (2283) and setup DynDns (Too poor for static IP) and ta rah everything would work fine, well that’s where I hit the road block.

CGNAT Shenanigans

There aren’t things that humans have done to address IPv4 exhaustion, they even had to invent ugly looking IP addresses (Sorry IPV6 fans). Well CGNAT is one of those things that’s used by ISP’s to address this. In CGNAT two or more devices can have same IP addresses since it is a shared IP address place, so there’s no way to directly connect to a service running in your devices using the public IP address.

Related articles:

https://en.wikipedia.org/wiki/Carrier-grade_NAT

https://en.wikipedia.org/wiki/IPv4_shared_address_space

https://datatracker.ietf.org/doc/html/rfc6264

https://datatracker.ietf.org/doc/html/rfc6598

A personal VPN

Well my personal need isn’t to expose my hosted services to the whole internet but just to my devices. So a personal VPN makes a lot of sense than a static IP (Also you can set your own IP in a private VPN :v). So I ended up with two choices Wireguard and Tailscale (Which is based on wireguard). I would do a wireguard setup but if I had to add a non-techy friend into the network or family member it would be little difficult to make them understand how to set it up. So I chose tailscale.

Tailscale

Tailscale is based on Wireguard a pretty popular and open source personal VPN package. With tailscale they have made setting up a VPN and connecting devices into a hub very easy you can literally do it in two commands. I use arch so the commands I mention to install packages will be specific to that.

Installing Tailscale

sudo pacman -S tailscale
Enter fullscreen mode Exit fullscreen mode

Starting a tailscale server

sudo tailscale up
Enter fullscreen mode Exit fullscreen mode

And… that’s it your personal VPN is setup on your device. When you login to tailscale.com you can see a dashboard like this with all of your devices

Tailscale Dashboard

So you can now ssh into any of your machine, transfer files pretty easier. If you are a privacy ninja and you don't want your data to go through tailscale you can even check HeadScale - An open source tailscale control server (You should host it in a server with public static IP otherwise it wont work).

Accessing the services without Domain

Tailscale comes with a MagicDNS feature (Of course if you have your own domain you don't need this, I will explain this in next section). With this you don't have to access your services like http://100.20.10.0:2283. You can use meaningful texts in the URL like http://FlyingElephant.ts.net:2283 . This is pretty useful for people without a domain and they dont want to bother about buying a domain and maintaining DNS entries of your servers.

Accessing services with Domain

If you have a domain it would be pretty convenient for you, You can use something called a Reverse Proxy. There are plenty of options out there like Nginx,Traefik,Caddy,Envoy etc. In this section we will learn how to set it up with Caddy since that’s what I use.

Prerequisites for this, You need to have Cloudflare as your nameserver, it’s convenient and supported by most of reverse proxies.

Go to cloudflare and create an API token with these permissions

Cloudflare Permissions

Install xcaddy , And install Caddy with cloudflare plugin using the following command.


xcaddy build master --with github.com/caddy-dns/cloudflare@master

Enter fullscreen mode Exit fullscreen mode

To get certificate from cloudflare you need to configure this in your Caddyfile

{

        acme_dns cloudflare <your-cloudflare-token>
}
Enter fullscreen mode Exit fullscreen mode

Now that the certificate part is done, Most of the stuffs in the reverse proxy configuration is done, All that remains is routing the traffic to your instance. For that first of all you need to add a DNS entry in Cloudflare

immich    A    <your-machine-tailscale-ip>
Enter fullscreen mode Exit fullscreen mode

Now you need to configure your reverse proxy listen to port 443 and route it to port where your service is running. Add this in your Caddyfile



immich.yourdomain.com {
        log {
            output file /var/log/caddy/immich.log
        }
        reverse_proxy http://0.0.0.0:2283
}

Enter fullscreen mode Exit fullscreen mode

Now if you share the server with someone else and you don’t want that person to access your service you can make the following changes to your Caddyfile



immich.yourdomain.com {
        @blocked not remote_ip <your IP's seperated by space>
        abort @blocked
        log {
            output file /var/log/caddy/immich.log
        }
        reverse_proxy http://0.0.0.0:2283
}
Enter fullscreen mode Exit fullscreen mode

And that’s it your server is ready to serve you, Go to immich.yourdomain.com in the browser of your choosing, It will redirect you to your server.

Top comments (0)