Shlink на Ubuntu 24.04: пошаговая установка
Публичные сокращатели ссылок вроде bit.ly или clck.ru удобны, пока не встаёт вопрос доверия: они видят весь трафик, могут заблокировать домен без объяснений и не дают доступа к сырым данным о переходах. Shlink закрывает эту проблему — open-source URL-shortener с собственным REST API, детальной аналитикой (гео, устройства, реферер) и поддержкой кастомных доменов. Ниже — рабочая установка на Ubuntu 24.04 через Docker Compose, с MySQL, Nginx и SSL.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Shlink и зачем он нужен
Shlink — PHP-приложение (ядро на Symfony), которое умеет: создавать короткие ссылки через API или CLI без веб-интерфейса из коробки; собирать статистику переходов (страна, город, браузер, ОС, referrer) без стороннего трекера; работать с несколькими доменами одновременно (multi-domain) — один сервер может обслуживать s.example.com и go.example2.ru; отдавать данные через REST API в JSON, что удобно для интеграции с ботами и CRM; ограничивать срок жизни ссылки, задавать кастомный слаг, добавлять теги.
Веб-интерфейса для конечного пользователя в самом Shlink нет — это осознанное решение проекта. Для UI ставится отдельное приложение Shlink Web Client, тоже open source и тоже в Docker. В этой статье фокус на backend — том, что реально нужно для интеграции по API. И ещё: Shlink не заменяет аналитику вроде Plausible или Matomo — метрики привязаны только к переходам по коротким ссылкам.
Требования к серверу
Shlink лёгкий, но запас под реальную нагрузку закладывать стоит:
| Ресурс | Минимум (тест/личный проект) | Рекомендуется (продакшн, десятки тысяч кликов/день) |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB | 2-4 GB |
| Диск | 15 GB SSD | 25-40 GB SSD (под БД и логи) |
| ОС | Ubuntu 24.04 LTS | Ubuntu 24.04 LTS |
Это ориентировочные цифры — реальная нагрузка зависит от числа доменов и частоты запросов к API. Для проекта с активным API-трафиком лучше сразу брать 2 vCPU и 4 GB RAM: миграция на больший тариф без даунтайма не проблема, но комфортнее заложить запас сразу.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПодготовка сервера и DNS
Подключаемся по SSH, обновляем систему и заводим пользователя без root-прав:
apt update && apt upgrade -y
adduser deploy
usermod -aG sudo deploy
su - deploy
Устанавливаем Docker и Docker Compose — Shlink официально распространяется как Docker-образ:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
docker --version
docker compose version
Открываем нужные порты через UFW:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Подробный разбор правил — в статье про настройку файрвола UFW на Ubuntu 24.04.
Shlink рассчитан на работу через собственный короткий домен. Заведите A-запись, направленную на IP сервера:
Тип: A
Имя: s (или go, l — что удобнее)
Значение: <IP-вашего-сервера>
TTL: 3600
Проверить распространение записи можно так:
dig +short s.example.com
Если результат — IP сервера, DNS настроен верно. Разбор с нуля — в статье настройка домена и DNS на Ubuntu 24.04.
Docker Compose: Shlink + MySQL
Создаём рабочую директорию и файл docker-compose.yml:
mkdir -p ~/shlink && cd ~/shlink
nano docker-compose.yml
Содержимое файла:
services:
shlink_db:
image: mysql:8.0
container_name: shlink_db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: shlink
MYSQL_USER: shlink
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- shlink_db_data:/var/lib/mysql
networks:
- shlink_net
shlink:
image: shlinkio/shlink:stable
container_name: shlink
restart: unless-stopped
depends_on:
- shlink_db
environment:
DEFAULT_DOMAIN: s.example.com
IS_HTTPS_ENABLED: "true"
DB_DRIVER: mysql
DB_NAME: shlink
DB_USER: shlink
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: shlink_db
GEOLITE_LICENSE_KEY: ${GEOLITE_KEY}
ports:
- "127.0.0.1:8080:8080"
volumes:
- shlink_data:/etc/shlink/data
networks:
- shlink_net
volumes:
shlink_db_data:
shlink_data:
networks:
shlink_net:
driver: bridge
Пояснения: DEFAULT_DOMAIN — короткий домен для ссылок (замените на свой); IS_HTTPS_ENABLED: "true" — Shlink генерирует ссылки с https://, SSL при этом терминирует Nginx; GEOLITE_LICENSE_KEY — ключ базы MaxMind GeoLite2, без него не будет геолокации переходов (регистрация бесплатная); порт наружу не пробрасывается (127.0.0.1:8080) — доступ только через Nginx.
Секреты выносим в отдельный .env рядом с docker-compose.yml:
nano .env
DB_ROOT_PASSWORD=сложный_пароль_root
DB_PASSWORD=сложный_пароль_shlink
GEOLITE_KEY=ваш_ключ_maxmind
Права на файл с секретами:
chmod 600 .env
Запускаем:
docker compose up -d
docker compose logs -f shlink
В логах должно появиться сообщение о готовности и об успешном применении миграций БД. Первый запуск занимает чуть дольше — Shlink создаёт схему.
Nginx как reverse proxy и SSL через Certbot
Ставим Nginx и Certbot:
sudo apt install -y nginx certbot python3-certbot-nginx
Конфиг сайта:
sudo nano /etc/nginx/sites-available/shlink
server {
listen 80;
server_name s.example.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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Активируем сайт и проверяем конфиг:
sudo ln -s /etc/nginx/sites-available/shlink /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Выпускаем сертификат — Certbot сам допишет блок для 443-го порта и настроит редирект с 80-го:
sudo certbot --nginx -d s.example.com
Если на этом шаге проблемы — разбор частых причин есть в статье Nginx не применяет SSL, а общий принцип reverse proxy для Docker-приложений — в статье про Nginx как reverse proxy на Ubuntu 24.04. Автопродление сертификата Certbot настраивает сам через systemd timer, проверить можно командой sudo systemctl list-timers | grep certbot.
Создание коротких ссылок через API и CLI
У Shlink нет встроенного веб-интерфейса, поэтому базовый способ работы — CLI внутри контейнера или REST API. Сначала генерируем API-ключ (сохраните его сразу — второй раз посмотреть не получится, только выпустить новый):
docker compose exec shlink shlink api-key:generate
Создать короткую ссылку можно из CLI:
docker compose exec shlink shlink short-url:create "https://maatrix.io/blog/" --tags=blog,promo
Или через REST API (именно этот способ используют в интеграциях с ботами и скриптами):
curl -X POST "https://s.example.com/rest/v3/short-urls" \
-H "X-Api-Key: ВАШ_API_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"longUrl": "https://maatrix.io/blog/", "tags": ["blog"]}'
В ответе — JSON с полями shortUrl и shortCode. Полная спецификация всех методов (статистика, редактирование, срок жизни ссылки) — в OpenAPI-документации прямо в репозитории проекта; через тот же API работает и Shlink Web Client, если решите его поставить.
Резервное копирование
Данные живут в MySQL-контейнере и в docker-volume shlink_data (там же база GeoLite2) — бэкапить нужно оба. Дамп с ротацией по crontab (ежедневно, хранить неделю):
docker compose exec -T shlink_db mysqldump -u root -p"$DB_ROOT_PASSWORD" shlink \
> ~/backups/shlink_$(date +%F).sql
find ~/backups -name "shlink_*.sql" -mtime +7 -delete
Для более серьёзного подхода — с шифрованием и версионированием — есть отдельная статья про установку BorgBackup на Ubuntu 24.04; её схему легко применить и к volume shlink_data.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли добавить несколько коротких доменов в один Shlink?
Да, это штатный сценарий (multi-domain) — домены добавляются через API-эндпоинт /rest/v3/domains, каждый новый домен нужно дополнительно прописать в Nginx отдельным server_name со своим SSL-сертификатом.
Нужен ли Shlink Web Client, если мне достаточно API?
Нет, backend самодостаточен: ссылки создаются через CLI или curl. Web Client нужен, только если хочется визуальную панель для нетехнических пользователей.
Контейнер shlink падает сразу после запуска — что делать?
Чаще всего MySQL ещё не успел подняться к моменту первого подключения. Проверьте docker compose logs shlink_db — с restart: unless-stopped контейнер переподключится сам.
Можно ли использовать PostgreSQL вместо MySQL?
Да, поддерживаются PostgreSQL, MariaDB и SQLite — достаточно поменять DB_DRIVER и сервис БД в docker-compose.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →