Build a long-to-short link tool based on shlink
This article was last updated 287 days ago. The information within may have evolved or changed; if anything is outdated or broken, please feel free to leave a message in the comments section.
Article Abstract
To solve the problem of long links not being concise enough in sharing scenarios, the author compared and analyzed tools like Myurls and YOURLS, and chose to deploy shlink as the short link generation solution. This tool supports advanced features such as device-specific routing, access limits, and geolocation, which requires registering with MaxMind to obtain a GeoLite2 database key for visitor location analysis. The deployment process involves containerizing the backend server and frontend web-client using Docker, configuring the domain name via a reverse proxy, and generating an API key to complete the integration. Ultimately, it achieves short link generation and management, with its core principle being mapping short links to original long links via HTTP redirection, making it suitable for scenarios requiring fine-grained control over link access.
Qwen3-14B · 2026-06-18

Preface

Originally, I didn't have much need for the function of converting long links to short links, because I was using cryptgeon, and the generated links could also have read counts and expiration times set (although in minutes), as well as access passwords. However, I later found that in situations where cryptgeon is not suitable, some long links (especially shared download links) look unsightly and very unprofessional when sent directly to others or placed on a webpage, so I was forced to do some research and chose the one that suits me best, shlink, from three short link generation tools (Myurls, YOURLS, shlink).

Comparison of Long-to-Short Link Tools

Here is a brief comparison of these 3 tools:

Myurls

Extremely simple, the interface is as follows:

image.png

Simple, right? However, setting it up is not that simple, and it also relies on Redis, which feels like it doesn't offer great value for money...

YOURLS

This one has more features than Myurls, as shown below:

image.png

As can be seen from the image above, YOURLS provides more information, including the click count of short links, and YOURLS features login account authentication, which is secure and convenient. In this regard, it is actually better than both Myurls and shlink.

shlink

Why did I ultimately choose shlink? No picture, no proof. Here is the image:

image.png

Device-specific long URLs:
It can return different long links based on different visiting devices, such as Android, iOS, and desktop systems.
Limit access to the short URL:
You can set the maximum number of visits for the short link, as well as its expiration time.
Just these two are already very powerful, not to mention it also includes: "Extra checks", where "Validate URL" can check the validity of the long link and throw an error upon saving if it is inaccessible; and in "Configure behavior", "Make it crawlable" allows short links to be indexed by search engines, etc. Moreover, you can view short link access statistics from multiple dimensions and even locate visitors, as shown below:
image.png

So, I ultimately chose shlink. A solid reason, right?

Register a MaxMind Account

However, shlink is also the most troublesome to set up, mainly because locating the visitor's origin requires using MaxMind's GeoLite2 database. Therefore, you need to register an account with MaxMind and obtain a key:

image.png

It is recommended to use the second method to register. The registration link is as follows:
https://www.maxmind.com/en/geolite2/signup?utm_source=kb&utm_medium=kb-link&utm_campaign=kb-create-account
You can complete the registration on your own. After successful registration, click the red box at the bottom as shown in the image below:
image.png

Enter a description, and then click "confirm" below to complete the generation:
image.png

Note that the key will only be displayed when it is first created successfully, and will not be visible afterwards. Please make sure to save it carefully.

Deploy shlink

Now that the preparations are complete, let's begin the formal creation process.

Simply put, the deployment of shlink is divided into two parts: the backend server and the frontend web-client. These two can be deployed together or separately. You can choose based on your own conditions. I chose to deploy the backend server on a Tencent Cloud Lighthouse server because it has port 443, which is more convenient, while the frontend web-client is deployed at home, so there is no need to map ports, prioritizing security.

Deploy backend server:

docker run --name shlink -d --restart=always \
    -p 9040:8080 \
    -e DEFAULT_DOMAIN=example.com \
    -e IS_HTTPS_ENABLED=true \
    -e GEOLITE_LICENSE_KEY=xxxxxxxxxxxxxxxxxxxxxxxx \
    shlinkio/shlink:latest

-p 9040:8080
Specifies the mapped port of the container. You can modify 9040 according to your own planning.
-e DEFAULT_DOMAIN
Used to specify your short domain name. Actually, you don't necessarily need to buy a very short one separately; generally, your existing domain name will do, such as the domain name corresponding to your cloud host. Assuming the domain name corresponding to your cloud host is example.com, you can directly fill in example.com here, provided that you have an A record for @ on your DNS server. Of course, you can also set up a separate domain name, such as a.example.com, as long as it can resolve to your cloud host, because the format of the final generated short link will be https://example.com/xxxxx or https://a.example.com/xxxxx. Therefore, as long as the specified domain name can reach port 443 of the server where you deployed shlink, it will work. What if it is a public IP of a home broadband connection without port 443 or 80? The answer is yes. For example, if your home broadband mapped port is 44444, then -e DEFAULT_DOMAIN=example.com:44444 will do. However, this can be annoying in some scenarios, such as clicking links in WeChat chat history, which will prompt that it is not a standard port, which is also a pain. That's why I ultimately deployed the server side on a Tencent Cloud Lighthouse server.
-e IS_HTTPS_ENABLED=true
Used to specify whether shlink generates https links or http links; true is https, and false is http. It is recommended to enable https for security, and http links will trigger an insecure connection warning on mobile Chrome browsers, which is very annoying.
-e GEOLITE_LICENSE_KEY
This is the key you obtained after registering with MaxMind earlier; just paste it directly after the = sign.


By default, shlink will use a SQLite database. If you want to utilize another existing database, you can specify it using the following -e parameters:
-e DB_DRIVER=maria \
-e DB_NAME=shlink \
-e DB_USER=shlink \
-e DB_PASSWORD=xxx\
-e DB_HOST=xxx \
Among them, the type of DB_DRIVER can be: mysql, maria, postgres, mssql, and you need to configure the shlink database and the corresponding user and password in the database to be used in advance.


After the above steps, the server side is fully set up. Then, reverse proxy port 443 of example.com to 127.0.0.1:9040 (the port is subject to what you actually specified) and you are good to go (for reverse proxy configuration methods, you can refer to my other two articles:Linux Panel Series: Configuring Reverse Proxy and Publishing Using Non-443 Ports和Docker Series: Building Your Own Reverse Proxy Based on NPM Using Docker). Actually visithttps://example.com, and if the following 404 output appears, it is considered successful:

image.png

Then execute the following command to obtain the api-key of the shlink backend server, and save the output result, which needs to be configured in the frontend web-client:

docker exec -it shlink shlink api-key:generate

Deploy frontend web-client:

Note: The usage habits of Shlink's web-client frontend are slightly different from general containers. There are 2 options to choose from:
Specify the server address and key using the -e parameter when creating the container.
The advantage of this is that you can see the saved server information even if you switch login devices at will.

Do not specify the server information in advance when creating the container, and add it after logging in once creation is complete.
In this way, the server information you add will be saved in the cookies of the current login device. That is to say, if you clear cookies or change login devices, you will need to re-add the backend server information.

Please choose different methods according to your environment.

The first method:

docker run --name shlink-web-client -d --restart=always \
  -p 9050:80 \
  -e SHLINK_SERVER_URL=http(s)://example.com \
  -e SHLINK_SERVER_API_KEY=xxxxxxxxxxxxxx \
  shlinkio/shlink-web-client

The second method:

docker run --name shlink-web-client -d --restart=always \
  -p 9050:80 \
  shlinkio/shlink-web-client

This is very simple. Once the container is set up, you can use it directly.http://ip:9050Just access it via the port.

Configure shlink via web-client

If you deploy using the second method, you will see the following interface upon your first login:

image.png

Click "Add a server":
image.png

The name can be anything, and fill in the backend server's access address for the URL:https://example.com, fill in the API key obtained from the previous command, and then click "Create server", as shown below:
image.png

Click the 3 vertical dots on the right and select the first option, "Connect":
image.png

Once successful, you can log in to the server:
image.png

After entering, you will see the Overview interface. On the right, you can see some statistics, including how many short URLs, how many tags, and how many visits, etc. In this interface, you can also use "Create a short URL" on the right to start creating short URLs.
image.png

Click on the advanced options in the red box, and you can see the interface we saw earlier:
image.png

The "URL to be shortened" in the red box on the left is where you fill in the long URL. You can explore the many other options on your own. Finally, click "Save" at the bottom to generate the short URL.

All done.

Summary: In fact, converting long URLs to short URLs is just that when everyone accesses the backend server through the generated short URL, the backend server returns a 301 or 302 redirect pointing to the original long URL based on the long URL corresponding to this short URL. It's that simple. However, if the traffic is heavy, the performance consumption on the server should not be underestimated, which is something everyone should pay attention to.

View Related Categories · 3 Matches
📌 Content Structure Prompt:
This content is part of the following knowledge map, where you can view the complete content path: Blog Knowledge Map。
📎 Related Articles
Share this article
The blog content is original, please indicate the source when reposting! The RSS address of the blog is:https://blog.tangwudi.com/feed, welcome to subscribe; if needed, you can join theTelegram Groupto discuss questions together.
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗ
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Kaomoji
Emoji
Little Dinosaur
Flower!
Previous
Next
       

👋 Welcome to “Wudi's Personal Blog”

Here, long-term exploration is mainly carried out around the following directions:

🧱 Personal Digital Infrastructure and Blog System Construction
☁️ Cloudflare and Network Architecture Practice
🧠 AI and Knowledge System Exploration
🛡️ Network Security and Access Optimization
🎵 Music and Sound Cognition
👁️ Cognitive Perspectives and Worldviews