Shlink is a free, open-source self-hosted URL shortener written in PHP that provides both a REST and a CLI interface to interact with it to generate and manage short URLs. One of the main features and URL shorting is that you can track all visits to these generated URLs such as location, browser, referrer and much more. Additionally, an official Shlink web client uses Shlink’s REST API and provides the user with an optional WebUI.
At the end of the guide, you will know how to install Shlink URL Shortner on your Ubuntu server 20.04 LTS Focal Fossa using Nginx. The same principle will work for the newer version Ubuntu 21.04 (Hirsute Hippo) server.
Table of Contents
Pre-requisites
- Recommended OS: Ubuntu 20.04 – optional (Ubuntu 21.04 and Linux Mint 20).
- User account: A user account with sudo or root access.
- Required packages: mariadb php7.4 or php8.0 installed and configured.
- Additional packages: curl wget unzip.
Check and upgrade your Ubuntu operating system.
sudo apt update && sudo apt upgrade -y
Next, install the required packages for this guide:
sudo apt install curl wget unzip
Download Shlink Archive
The first step is to visit the Shlink Github page and check out the latest stable version. At the time of this guide, the current stable version is 2.7.1. However, this will change in future. Shlink comes in 3 versions for PHP 7.4, PHP 8.0 and the source code.
To download Shlink, 2.7.1, execute the following command:
PHP 7.4:
wget https://github.com/shlinkio/shlink/releases/download/v2.7.1/shlink2.7.1_php7.4_dist.zip
PHP 8.0:
wget https://github.com/shlinkio/shlink/releases/download/v2.7.1/shlink2.7.1_php8.0_dist.zip
Source Code:
wget https://github.com/shlinkio/shlink/archive/refs/tags/v2.7.1.zip
For the guide purpose, it will follow the PHP 7.4 download example. The next step is to use the (unzip) command to extract the archive to your (/var/www/html) directory.
sudo unzip shlink2.7.1_php7.4_dist.zip -d /var/www/html
You should rename the extracted folder to make life easier by executing the following command:
sudo mv /var/www/html/shlink2.7.1_php7.4_dist/ /var/www/html/shlink
Before moving on, it is advised to set permissions of the directory to the (www-data) user as currently it is set as (root). To do this, type and enter the following (chown) command:
sudo chown -R www-data:www-data /var/www/html/shlink/
Create new MariaDB database and user for Shlink
The next step is to create a new database and a dedicated new user with only permission to access this database. It is not recommended to use root or the same user account on multiple databases if one is compromised.
The guide installed MariaDB and familiar with the terminology below.
Enter the MariaDB/MySQL terminal console by executing the root command:
sudo mysql -u root
Next, create the new database for Shlink using the following terminal command:
CREATE DATABASE shlink;
After creating the database, create a new user account and grant it access to the Shlink database. If you are hosting Nginx, PHP and MariaDB on the same server, keep the (localhost). If using a secondary server to host MariaDB on internal or external, enter the (IP address) in place (localhost).
GRANT ALL ON shlink.* TO 'shlinkuser'@'localhost' IDENTIFIED BY 'password';
To make changes live, you need to flush the privileges:
FLUSH PRIVILEGES;
To exit the MariaDB terminal execute the following command:
EXIT;
Install PHP 7.4 Latest Version & Extensions
As part of the requirements, PHP 7.4 or 8.0 is required. Shlink needs certain extensions for the software to operate using PHP. It’s ideal for making sure PHP is up to date. The custom PPA by Ondrej, the maintainer and PHP for Debian, is highly recommended.
Below, the guide will add the repository and install the PHP extensions required for PHP 7.4. If you want to install PHP 8.0, change the 7.4 to 8.0 or visit our official How to install PHP 8.0 on Ubuntu 20.04 Tutorial.
Install the custom PHP PPA by ondrey:
sudo apt install software-properties-common && sudo add-apt-repository ppa:ondrej/php -y
After adding the repository, execute the following command to update or install the latest PHP 7.4 software:
sudo apt install php7.4-apcu php7.4-fpm php7.4-mysql php7.4-gd php7.4-common php7.4-curl php7.4-intl php7.4-gmp php7.4-xml php7.4-json -y
To make sure PHP 7.4 is running correctly after the installation or update, enter the following:
sudo systemctl status php7.4-fpm
Example output:

Installing Shlink
Now you can proceed with installing the PHP Shlink installation script as the (www-user) by executing the following PHP command in your Ubuntu terminal:
sudo -u www-data php7.4 /var/www/html/shlink/bin/install
Straight away, you will find yourself looking at a new screen that will ask you to enter the database details.

Database
In the guide, you will choose MariaDB; however, if you prefer to go back and set up another optional database software, you can certainly do this.
As per below, an example of creating Shlink set up using MariaDB:

The options entered in summary:
- Select database type: 1 (MariaDB)
- Database name: shlink
- Database port: 3306
- Database username: shlinkuser
- Database password: <yourpassword>
- Unix socket: <leave blank>
URL Shortner
On the next screen, you will find another page of options. Here, you will find specific HTTP or HTTPS, the domain name, and some Shlink URL options. Example settings below:

The options entered in summary:
- Default domain for generated short URLs: <yourdomain>
- Select schema for generated short URLs: HTTPS (Use HTTP if not using SSL)
- Do you want to validate long urls by 200 HTTP status code on response? (yes/no): yes
- What is the default length you want generated short codes to have? (You will still be able to override this on every created short URL): 5
- Do you want Shlink to resolve the short URL title based on the long URL ‘s title tag (if any)? Otherwise, it will be kept empty unless explicitly provided. (yes/no): yes
- Provide a GeoLite2 license key. (Leave empty to use default one, but it is strongly recommended to get your own. Go to https://shlink.io/documentation/geolite-license-key to know how to get it): license key
If you would like to use GeoLite2, you will need to create an account at MaxMind and create a key. A guide for doing this can be found in MaxMind GeoLite2’s documentation. Once done, replace and enter your key in the Shlink setup.
Following on, you will have the option to set 301 or 302 re-direct. You must use 301, or else your SEO, as the software suggests, indeed can be hurt in various ways.

Tracking
After setting 301 as your permanent re-direct, the next page you will see is tracking. Most of the default settings are fine, and if you are in the EU or have EU visitors, you must anonymize your data which luckily Shlink can do for you.
Example settings below:

The options entered in summary:
- Do you want track orphan visits? (visits to the base URL, invalid short URLs or other “not found” URLs): yes
- Provide a parameter name that you will be able to use to disable tracking on specific request to short URLs (leave empty and this feature won’t be enabled): <leave empty>
- Do you want to completely disable visits tracking?: no
- Do you want to disable tracking of visitors’ IP addresses?: no
- Do you want to disable tracking of visitors’ “User Agents”?: yes
- Do you want visitors’ remote IP addresses to be anonymized before persisting them to the database?: yes
- Do you want to disable tracking of visitors’ “User Agents”?: no
- Do you want to disable tracking of visitors’ “Referrers”? (yes/no): no
Redirects
Redirect set-up is fairly easy. The best option is to link everything back to your home page for any 404 / not found errors that may occur on your website. Example below:

The options entered in summary:
- Custom URL to redirect to when a user hits Shlink’s base URL (If no value is provided, the user will see a default “404 not found” page): https://www.example.com
- Custom URL to redirect to when a user hits an invalid short URL (If no value is provided, the user will see a default “404 not found” page): https://www.example.com
- Custom URL to redirect to when a user hits a not found URL other than an invalid short URL (If no value is provided, the user will see a default “404 not found” page): https://www.example.com
Application
In the application options, you can enable a safety check, which will now allow short URLs to be deleted after a certain amount of visits, along with setting the path from which Shlink will be served if not the root path:

The options entered in summary:
- Do you want to enable a safety check which will not allow short URLs to be deleted after receiving a specific amount of visits?: yes
- What is the amount of visits from which the system will not allow short URLs to be deleted?: 15
- What is the path from which shlink is going to be served? (Leave empty if you plan to serve shlink from the root of the domain): <blank for root>
Note, you can modify the 15 to something larger or smaller depending on your site, mainly around traffic.
Intergrations
Shlink has only one integration: Redis, which you can configure below in a single or cluster instance. It’s recommended to use a single server for Redis until you are very familiar with Redis clustering, sharding and replication as it is quite in-depth, and the average small to medium website shouldn’t need this unless receiving huge traffic loads.

In the guide, we left it blank, but if you were to use it on the localhost, type 127.0.1.1:6379.
Congratulations, you have installed Shlink on Ubuntu 20.04.

Nginx Server Block Example
To use Shlink with Nginx, you will need to configure your server block. You can do this by copying and pasting the following configuration with modifying it to suit your needs with HTTPS or not:
server {
listen 80;
listen [::]:80;
server_name www.linuxcapable.com
root /var/www/html/shlink/public;
error_log /var/log/nginx/shlink.error;
access_log /var/log/nginx/shlink.access;
index index.php index.html index.htm index.nginx-debian.html;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
# redirect some entire folders
rewrite ^/(vendor|translations|build)/.* /index.php break;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Before restarting your Nginx server, do a dry run by entering the following code:
sudo nginx -t
You should receive the following output:
nginx: the configuration file /etc/nginx/my-server.conf syntax is ok
nginx: configuration file /etc/nginx/my-server.conf test is successful
If everything is ok, restart your Nginx server as below:
sudo systemctl restart nginx
Create Short Links
To create short links with Shlink, you first need to create an API key by executing the PHP command:
sudo -u www-data php7.4 /var/www/shlink/html/bin/cli api-key:generate
Once you have your API key, you need to visit Shlink.io to register your server.

Enter the name of the server, URL of the server and the API key as the example below:

Now you can add short links using Shlink’s WebUI if you prefer. Remember these are stored on your server:

The most common option is using the terminal commands to generate short URLs.
To do this, execute the following command:
sudo -u www-data /var/www/html/shlink/bin/cli short-url:generate
To list the short URLs that are generated, using the following command:
sudo -u www-data /var/www/html/shlink/bin/cli short-url:list
To seek help, run the following command:
sudo -u www-data php /var/www/html/shlink/bin/cli
Example output:
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
help Displays help for a command
list Lists commands
api-key
api-key:disable Disables an API key.
api-key:generate Generates a new valid API key.
api-key:list Lists all the available API keys.
db
db:create Creates the database needed for shlink to work. It will do nothing if the database already exists
db:migrate Runs database migrations, which will ensure the shlink database is up to date.
short-url
short-url:delete Deletes a short URL
short-url:generate Generates a short URL for provided long URL and returns it
short-url:list List all short URLs
short-url:parse Returns the long URL behind a short code
short-url:visits Returns the detailed visits information for provided short code
tag
tag:create Creates one or more tags.
tag:delete Deletes one or more tags.
tag:list Lists existing tags.
tag:rename Renames one existing tag.
visit
visit:locate Resolves visits origin locations.
Comments and Conclusion
You have learnt how to install Shlink on Ubuntu 20.04 with downloading the archive, extracting, setting up a database and user with MariaDB, running through the Shlink installer, Creating or Modifying Nginx server block and lastly, learning how to create short URLs in this tutorial.
Overall, Shlink is probably one of the better URL options currently and should be considered if you prefer to keep short URLs in your own domain and control. For more information, visit the official documentation from Shlink.