Oct 14, 2024 3 min read

Shlink: The Full Guide to Self-Hosting Anywhere

Shlink: The Full Guide to Self-Hosting Anywhere
Table of Contents

Shlink is a self-hosted URL shortener that empowers users with complete control over their link management. Designed for developers and system administrators, Shlink provides robust customization options, detailed analytics, and API integrations, making it a powerful alternative to third-party services. In this guide, we’ll cover installation, reverse proxy configuration, debugging, backups, updates, and advanced features to help you deploy and manage Shlink effectively.

πŸ“¦ Docker/Docker Compose Setup

Shlink is designed with Docker in mind, making deployment fast and reliable. Below is a docker-compose.yml file configured for Shlink:


version: "3.8"

services:

shlink:

image: shlinkio/shlink:stable

container_name: shlink

ports:

- "8080:8080" # Map Shlink's internal port to your host

environment:

- SHORT_DOMAIN_HOST=yourdomain.com

- SHORT_DOMAIN_SCHEMA=https

- DEFAULT_REDIRECT_URL=https://yourdomain.com

- DB_DRIVER=postgres

- DB_HOST=db

- DB_PORT=5432

- DB_USER=shlink

- DB_PASSWORD=shlinkpassword

- DB_NAME=shlink

depends_on:

- db

volumes:

- ./shlink-data:/etc/shlink

db:

image: postgres:13

container_name: shlink_db

environment:

POSTGRES_DB=shlink

POSTGRES_USER=shlink

POSTGRES_PASSWORD=shlinkpassword

volumes:

- ./postgres-data:/var/lib/postgresql/data

volumes:

shlink-data:

postgres-data:

Deploy Shlink using the following commands:


mkdir shlink && cd shlink

nano docker-compose.yml # Paste the content above

docker-compose up -d

πŸš€ Manual Installation

For those who prefer manual setups, follow these steps to install Shlink on a Linux server:

  1. Install dependencies:

sudo apt update

sudo apt install -y php-cli php-mbstring php-xml unzip composer curl git

  1. Clone and set up Shlink:

git clone https://github.com/shlinkio/shlink.git

cd shlink

composer install --no-dev

php bin/cli db:create

php bin/cli short-url:generate-key --clip

Replace the database configuration in .env or use the environment variables provided in your hosting setup.

Configuring Nginx as a Reverse Proxy

🌐 Nginx Configuration

Nginx serves as a reverse proxy to handle incoming requests for Shlink. Create a configuration file for your domain:


sudo nano /etc/nginx/sites-available/shlink

Paste the following configuration:


server {

listen 80;

server_name yourdomain.com;

location / {

proxy_pass http://127.0.0.1:8080;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

Enable the configuration and restart Nginx:


sudo ln -s /etc/nginx/sites-available/shlink /etc/nginx/sites-enabled/

sudo nginx -t

sudo systemctl reload nginx

πŸ”’ SSL/TLS Setup

Secure your Shlink instance with Let's Encrypt:


sudo apt install -y certbot python3-certbot-nginx

sudo certbot --nginx -d yourdomain.com

Automate certificate renewal:


sudo systemctl enable certbot.timer

sudo systemctl start certbot.timer

πŸ› οΈ Testing and Reloading Nginx

Validate and reload your configuration:


sudo nginx -t

sudo systemctl reload nginx

πŸ—ƒοΈ Enabling Debug Logs

To enable debug-level logging in Shlink, modify the environment variable APP_ENV:


docker-compose exec shlink bash -c 'export APP_ENV=dev'

πŸ“„ Viewing Logs

Access logs using Docker:


docker logs -f shlink

For manual setups, Shlink logs are often located in shlink/logs/.

πŸ› οΈ Troubleshooting Common Issues

Investigate common issues by looking for errors in the logs. For instance:

  • Database connection errors: Ensure the database credentials in .env are correct.

  • Nginx 502 errors: Verify Shlink is running and reachable on localhost:8080.

πŸ“€ Exporting Logs

Send logs to ELK Stack or an external system:


docker-compose exec shlink bash -c 'tail -f /var/log/shlink.log | nc logstash_server 5000'

Backup and Restore

πŸ—‚οΈ File-Based Backups

To back up critical files and configurations:


tar -czvf shlink-backup.tar.gz ./shlink-data ./postgres-data

πŸ”„ Database Backups

For database backups:


docker exec shlink_db pg_dump -U shlink shlink > shlink_db_backup.sql

Restore the database with:


docker exec -i shlink_db psql -U shlink shlink < shlink_db_backup.sql

πŸ“… Automated Backup Scripts

Automate backups with a cron job:


0 3 * * * tar -czvf /path/to/backups/shlink-$(date +\%Y-\%m-\%d).tar.gz /path/to/shlink-data /path/to/postgres-data

⬆️ Updating Docker Images

Pull the latest Shlink version and restart the container:


docker-compose pull

docker-compose up -d

πŸ› οΈ Manual Updates

For manual installations:


cd shlink

git pull

composer install --no-dev

php bin/cli db:update

πŸ” Checking for Updates

Check the latest version on Shlink’s GitHub repository or Docker Hub:


curl -s https://api.github.com/repos/shlinkio/shlink/releases/latest | jq '.tag_name'

Leveraging Shlink’s Unique Features

πŸ”§ Enabling APIs

Shlink includes a powerful API for programmatic URL management. Enable it by setting ENABLE_API=true in your environment variables. Example API call to create a short URL:


curl -X POST "http://yourdomain.com/rest/v2/short-urls" \

-H "X-Api-Key: YOUR_API_KEY" \

-H "Content-Type: application/json" \

-d '{"longUrl": "https://example.com", "tags": ["example", "test"]}'

🌟 Advanced Configurations

Customize Shlink with additional features, such as geotargeting or advanced analytics, by modifying the config/params/*.yaml files or using relevant CLI commands.

Wrapping Up

By following this guide, you’ve successfully deployed, configured, and secured your self-hosted Shlink instance. With full control over your URL shortening service, you can leverage its powerful APIs, detailed analytics, and customization to meet your unique needs. Dive deeper into Shlink’s features and enjoy the benefits of self-hosting!

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Selfhosted Ninja.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.