TutorialsAugust 4, 20265 min read

How to Self-Host a URL Shortener on a VPS

Branded short links on your own domain, with real analytics and no third-party shutting them down. Install Shlink on a VPS with Docker.

NBy Nxeon

A self-hosted URL shortener gives you branded short links on your own domain, real click analytics, and the assurance that a third-party service won't shut down and break every link you've shared. This guide uses Shlink, a powerful open-source shortener with a REST API and a web dashboard. You'll want a short, memorable domain for the links themselves.

Why self-host a shortener?

  • Your brand: links look like go.example.com/launch, not a generic domain.
  • Link permanence: you control the service, so links don't die when a provider does.
  • Real analytics: clicks, locations and referrers, without handing data to anyone.

A dedicated short domain helps — grab one via domains if you don't have a spare.

Prerequisites

  • A VPS with Docker installed — run Docker on a VPS.
  • A short domain with an A record, e.g. go.example.com.

Deploy Shlink with a dashboard

We'll run the Shlink server, its web dashboard, and Caddy for automatic HTTPS.

mkdir -p ~/shlink && cd ~/shlink
services:
  shlink:
    image: shlinkio/shlink:stable
    restart: unless-stopped
    environment:
      - DEFAULT_DOMAIN=go.example.com
      - IS_HTTPS_ENABLED=true
      - GEOLITE_LICENSE_KEY=optional-for-geo-stats
    volumes:
      - ./data:/etc/shlink/data

  dashboard:
    image: shlinkio/shlink-web-client:stable
    restart: unless-stopped

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data

volumes:
  caddy_data:

Caddyfile — the short domain serves redirects, a separate host serves the dashboard:

go.example.com {
    reverse_proxy shlink:8080
}
admin.example.com {
    reverse_proxy dashboard:8080
}
docker compose up -d

Generate an API key and connect the dashboard

Shlink is driven by an API key. Create one from the container:

docker compose exec shlink shlink api-key:generate

Open https://admin.example.com, add a new server, and enter your Shlink URL (https://go.example.com) and the API key. The dashboard now manages all your links.

The Nxeon game-server control panel — live console, player slots, and TPS
The Nxeon game-server control panel — live console, player slots, and TPS

Create and track short links

From the dashboard, click Create short URL, paste a long link, and optionally set a custom slug like launch. Shlink returns https://go.example.com/launch. Every visit is recorded, so you can see click counts, geographic breakdowns and referrers per link — real analytics on infrastructure you own.

Lock down the firewall

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Keep the dashboard host restricted or behind a VPN if the links are for a business — the redirect domain stays public, but the admin surface doesn't need to be.

Tags, QR codes and the API

Shlink is more than a redirector. A few features make it genuinely useful for campaigns and sharing:

  • Tags: label links by campaign, channel or project, then filter analytics by tag to see what's performing.
  • QR codes: every short link can generate a QR code on the fly — handy for print, packaging or slides.
  • Device and time targeting: send mobile and desktop visitors to different destinations from the same short link.
  • REST API: because Shlink is API-first, you can create and query links from scripts or automations — pair it with n8n to auto-shorten links in a workflow.

Custom slugs, redirects and cleanup

When you create a link, set a memorable custom slug (go.example.com/launch) instead of a random one for anything you'll share widely. You can also update the destination of an existing short link later — useful when a target URL changes but you've already printed the short one. Shlink lets you set default redirect behaviour and expiration dates on links, and its visit data can be pruned or exported. Keep the container updated with docker compose pull && docker compose up -d, and back up the data directory, which holds your links and their stats — the whole point of self-hosting is that those links never break.

Choosing a short domain

The domain does a lot of the work for a URL shortener, so pick it deliberately. The shorter and more memorable, the better — every character counts when the whole point is brevity. A few tips:

  • Keep it short: two-word or single-word domains, ideally on a concise TLD, make the cleanest links.
  • Match your brand where you can, so links reinforce recognition instead of looking like spam.
  • Use a subdomain of a domain you own (go.example.com, l.example.com) if you don't want to register a new one — it works exactly the same and costs nothing extra.

You can register a fresh short domain via domains, or run our free domain generator to brainstorm available names. Shlink can even serve multiple domains from one instance, so a business can keep separate branded short domains for different products while managing them all from a single dashboard. Point each domain's A record at the VPS and add it in Shlink, and every link — whichever domain it's on — lands in the same analytics.

FAQ

Do I need a special domain for a URL shortener?

A short, memorable domain makes the links useful, but any domain works. Many people register a dedicated short domain purely for links.

Is Shlink free?

Yes, Shlink and its web dashboard are open source and free to self-host. You only pay for the VPS and domain.

Can I see analytics for each link?

Yes — Shlink records visits with click counts, locations (with an optional geo database) and referrers, all viewable in the dashboard.

Will my short links keep working long-term?

As long as you keep the VPS and domain, yes. That permanence is the main reason to self-host instead of relying on a third-party shortener.

Put your branded links on a reliable NVMe VPS and a memorable domain. Compare plans on the pricing page.

#url-shortener#shlink#docker#self-hosting#vps#seobatch

Deploy your first server in under a minute

Creating an account is free and takes no card details. You pay when you deploy — choose a billing term and pay from your wallet or by card at checkout.