Shlink with Docker and Cloudflare Tunnel

Shlink with Docker and Cloudflare Tunnel

I write a lot of PowerShell scripts for application installations, and many download the install files from a URL. Because the URL is hardcoded in the scripts, if the URL changes, I need to update all the scripts. This exact issue happened to me a few years ago, and my solution at the time was to write a Python script to update the PowerShell scripts. You can read about that solution in my blog post, Script to make Scripts.

However, if my scripts had used a URL shortener instead, I could’ve edited the short URL to resolve the issue. The problem with most URL shorteners is that you can make short URLs all day long, but you can’t edit them, and if they let you edit them, it’s a paid feature, and they also start limiting how many hits your short URL can get. I am not a fan of any of that.

Fortunately, a URL shortener named Shlink exists. Shlink is a self-hosted open-source URL shortener. With Shlink, you can do whatever you want with your short URL, including editing them.

Once I got Shlink set up, I re-wrote my PowerShell scripts to use my Shlink short URLs. Now, if an install URL changes, I can edit the Shlink short URL, and I don’t need to update my PowerShell scripts.

In this post, I will show you step-by-step how to set up Shlink with Docker and Cloudflare Tunnels.

The Shlink setup will use a Cloudflare tunnel for external access and a MariaDB database for the Shlink database. I selected MariaDB as I am more familiar with it. However, Shlink does support other databases. We will also use the Shlink web client as a UI to easily manage the short links.

Prerequisites

The Process

I’ll call mine shlink.

.env Setup

For example, I will use the domain dxt.zip as the primary domain for Shlink. I will be redirecting all non-short URL traffic to my blog, thedxt.ca. I will use port 8788 for the Shlink application and port 8787 for the Shlink web client to manage Shlink.

Here is an example of what my .env file looks like.

CONTAINER_NAME=DXT-SHLINK
DB_NAME=shlink
DB_ROOT_PWD=KFHDFh2hjshd34jsdfiuwjkls4dfjhk9
DB_USER=shlink_user
DB_USER_PWD=dfgjkhjF3DSH2FSDJlkj42dfdjklf
SHORT_DOMAIN=dxt.zip
REDIRECT_DOMAIN=https://thedxt.ca
APP_PORT=8788
ADMIN_API=sjkhfdDFJFKD378kfhjsdSdshs433
WEB_CLIENT_PORT=8787
CF_TUNNEL_B64=Code language: plaintext (plaintext)

Cloudflare Tunnel Setup

For more details on how to set up a Cloudflare tunnel, my blog post, Cloudflare Tunnel with Docker, goes into more detail.

I will use the name DXT-ZIP-SHLINK.

Example Cloudflare tunnel Base64

eyJhIjoiTXlBY2NvdW50VGFnMTIzIiwidCI6Ik15VHVubmVsSUQxMjMiLCJzIjoiTXlUdW5uZWxTZWNyZXQxMjMifQCode language: plaintext (plaintext)

Save the Cloudflare tunnel Base64 as the variable CF_TUNNEL_B64= in your .env file.

I will be using dxt.zip.

I will use the Shlink app on a docker host running on 192.168.172.19 on port 8788.

With the Cloudflare tunnel configured, your .env file should look something like this now.

CONTAINER_NAME=DXT-SHLINK
DB_NAME=shlink
DB_ROOT_PWD=KFHDFh2hjshd34jsdfiuwjkls4dfjhk9
DB_USER=shlink_user
DB_USER_PWD=dfgjkhjF3DSH2FSDJlkj42dfdjklf
SHORT_DOMAIN=dxt.zip
REDIRECT_DOMAIN=https://thedxt.ca
APP_PORT=8788
ADMIN_API=sjkhfdDFJFKD378kfhjsdSdshs433
WEB_CLIENT_PORT=8787
CF_TUNNEL_B64=eyJhIjoiTXlBY2NvdW50VGFnMTIzIiwidCI6Ik15VHVubmVsSUQxMjMiLCJzIjoiTXlUdW5uZWxTZWNyZXQxMjMifQCode language: plaintext (plaintext)

If we go to the IP of the docker host with port 8787, we can access the Shlink web client.

The Shlink setup uses the ADMIN_API= variable to preload the Shlink web client with the API key needed to access Shlink.

I wouldn’t expose your Shlink web client to the internet because it automatically has access to your Shlink due to the preloading of the API key. The goal should be to use the Shlink web client internally to manage your Shlink.

If you want to manage your Shlink externally, you could use the free web client that Shlink themselves hosts on app.shlink.io.

Once you log in to the Shlink web client, you can now create your own short links.

Testing

First, make sure the Cloudflare tunnel is up by checking the Cloudflare tunnel dashboard.

It’s a bit hard to illustrate that Shlink is working because it just forwards you along and works. However, curl can help.

If we curl the root Shlink domain dxt.zip, we get nothing, but that’s because curl doesn’t follow redirects by default.

If we run curl with the -L option, curl will now follow redirects. Because the examples I am using are full web pages, I will also use the -s option to silence the progress meter and pipe the output to grep to show only the web page’s title as a simple example.

Now, if we run curl on the root Shlink domain dxt.zip curl -s -L dxt.zip | grep '<title>' we see that the title is theDXT.

If we run the same curl command for thedxt.ca curl -s -L thedxt.ca | grep '<title>' we can see that the title is also theDXT, which shows that raw visits to dxt.zip are redirected to thedxt.ca.

If we curl the URL of my blog post about Cloudflare tunnels with Docker we see that the title is Cloudflare Tunnel with Docker.

I will create a short link for that post using Shlink. The short link is https://dxt.zip/DVW93.

If we curl just the short link without the -L option, the output is nothing.

If we add back in -L we can see that Shlink forwarded us to the blog post.

Because Shlink is self-hosted, we control everything. I’m going to edit the short link to go to another post.

If we curl the same short link, Shlink sends us to a different blog post.

Summary

With the power of the self-hosted URL shortener Shlink, the possibilities are endless. My use of Shlink hardly scratches the surface of the available features, but that’s ok. It works perfectly for what I need it for. It blows my mind that it works so well and is entirely free and open-source.

I’ve been using Shlink for a few years, and it has been rock solid. I think the version I first started playing with was version 2. Development is very active with Shlink. They are currently on version 4.

Now, all my PowerShell install scripts use short links from Shlink, and if I need to change a URL, I can do so without needing to edit my scripts.

If you want to check out all the features of Shlink, here is their list of features. If you want to read more about Shlink, here is their documentation.

If you want to read more about Cloudflare tunnels, here is their documentation.

Exit mobile version