This docker-compose file sets up a complete Shlink instance, a user-friendly URL shortener tool that supports custom domains.
It combines Shlink with a PostgreSQL database and a Cloudflare tunnel to ensure easy access and heightened security.
In just a few steps, you can create, manage, and secure your own short URLs while keeping everything safely behind Cloudflare's network.
Of course, replace YOURDOMAIN.com and set the ENV vars :).
services:
shlink:
image: shlinkio/shlink:stable
restart: unless-stopped
environment:
- DEFAULT_DOMAIN=YOURDOMAIN.com
- GEOLITE_LICENSE_KEY=${GEOLITE_LICENSE_KEY}
- IS_HTTPS_ENABLED=true
- INITIAL_API_KEY=${INITIAL_API_KEY}
- DEFAULT_SHORT_CODES_LENGTH=4
- DB_DRIVER=postgres
- DB_USER=postgres
- DB_PASSWORD=${POSTGRES_PASSWORD}
- DB_HOST=postgres
depends_on:
- postgres
postgres:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- shlink-dbdata:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
admin:
image: shlinkio/shlink-web-client:latest
restart: unless-stopped
environment:
- SHLINK_SERVER_URL=https://YOURDOMAIN.com
- SHLINK_SERVER_API_KEY=${INITIAL_API_KEY}
- SHLINK_SERVER_NAME=YOURDOMAIN.com
cf-tunnel-shlink:
container_name: cf-tunnel-shlink
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel run
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
volumes:
shlink-dbdata:
i'm assuming you're not totally unfamiliar with cloudflare, the interface for the most part is self explanatory tho.
- Create a "Tunnel" in Zero Trust -> Access in Cloudflare. This provides the
TUNNEL_TOKEN
in thecloudflared
-Installation snippet. Remove thesudo apt...
stuff and just use the token starting withay....
. - Add the API domain, (e.g.
YOURDOMAIN.com
) to the "Public Hostnames" and point it tohttp://shlink:8080
. - Add an "Application" in Zero Trust -> Access.
- Set up an admin hostname for your Shlink frontend, e.g.,
admin.YOURDOMAIN.com
. - This application must ensure that only you or authorized individuals can use Shlink to create new links and edit/delete existing ones:
- For beginners, using the email code is probably the simplest method, while more advanced users might prefer OIDC, for example with auth0.com (free tier).
- Then, whitelist the email addresses that should have access.
- Set up an admin hostname for your Shlink frontend, e.g.,
- Return to your tunnel and add the admin hostname from the Application, (here:
admin.YOURDOMAIN.com
), to thePublic Hostname
section and usehttp://admin:80
as the service URL. VERY IMPORTANT: While adding this hostname, click onAdditional application settings
->Access
->Protect with Access
and enable it. Then select the "Application" you created in step 3. DO NOT SKIP THIS STEP, OR YOU WILL RISK EXPOSING YOUR API KEYS.
This should be it :) Try to access your version of https://admin.YOURDOMAIN.com.