SSD Nodes Learn Hosting plans →
मार्गदर्शक Matt Connorद्वारे Matt Connor

Shlink वापरून स्वतःचे URL Shortener कसे तयार करावे

Docker Compose द्वारे VPS वर Shlink इन्स्टॉल करा. या मार्गदर्शकामध्ये Postgres डेटाबेस सेटअप, API की जनरेशन, HTTPS कॉन्फिगरेशन आणि क्लिक स्टॅट्स ट्रॅकिंगची संपूर्ण प्रक्रिया दिली आहे.

तुम्ही काय तयार करणार आहात

Self-hosted URL shortener हा एक लहान सर्व्हर असतो. तो तुमच्या मालकीच्या लांब लिंकचे रूपांतर छोट्या लिंकमध्ये करतो आणि त्या लिंकवरील प्रत्येक click मोजतो. यासाठी Shlink निवडा. हा open source आहे, Docker image म्हणून उपलब्ध आहे आणि database सह एका container मध्ये संपूर्ण काम करतो. या मार्गदर्शकात तो प्रत्यक्ष short domain मागे असलेल्या VPS वर HTTPS, API key, QR codes आणि click stats सह सेट केला आहे.

यामुळे सेवा commercial shortener सारखी कार्य करते. API server redirects साठी प्रतिसाद देतो आणि data साठवतो. Web client हा स्वतंत्र static app आहे. तो तुमच्या browser मधून त्या API शी संवाद साधतो. तुम्ही दोन्ही चालवू शकता किंवा फक्त API चालवून त्याचे नियंत्रण command line मधून करू शकता.

येथील version numbers October 2026 मध्ये उपलब्ध असलेल्या आवृत्तींनुसार आहेत: Shlink 5.1 आणि shlink-web-client 4.8.

सर्वप्रथम सर्व्हरवर एक छोटा डोमेन पॉइंट करा

डोमेन हेच तुमचे उत्पादन आहे. s.example.com/abc123 ही ती लिंक आहे जी लोक पाहतात, त्यामुळे काहीही इन्स्टॉल करण्यापूर्वी एक छोटा डोमेन निवडा. Shlink प्रत्येक शॉर्ट URL सोबत डोमेन साठवते, त्यामुळे नंतर ते बदलल्यास तुम्ही आधी वाटलेल्या सर्व लिंक्स काम करणे बंद करतील.

तुमच्या शॉर्ट डोमेनसाठी एक DNS A record तयार करा, जो तुमच्या VPS च्या सार्वजनिक IPv4 ॲड्रेसकडे निर्देश करेल. जर सर्व्हरकडे IPv6 असेल, तर एक AAAA record देखील जोडा. त्यानंतर, पुढे जाण्यापूर्वी तो डोमेन रिझॉल्व्ह होत असल्याची खात्री करा.

dig +short s.example.com A

आउटपुटमध्ये तुमच्या सर्व्हरचा ॲड्रेस दिसला पाहिजे. जर आउटपुट रिकामे असेल, तर याचा अर्थ असा की रेकॉर्ड अजून प्रोपॅगेट झालेला नाही. अशा स्थितीत पुढील सर्व पायऱ्या गोंधळात टाकणाऱ्या पद्धतीने अपयशी ठरतील, कारण ज्या नावाचे रिझोल्यूशन होत नाही, त्यासाठी TLS (transport layer security) प्रमाणपत्र जारी करता येत नाही.

Compose फाइल

Shlink ला database आवश्यक आहे. चाचणीसाठी SQLite चालते; परंतु दीर्घकाळ ठेवायच्या deployment साठी Postgres योग्य पर्याय आहे. Visit rows वाढत जातात आणि indexes तसेच concurrent writes हाताळण्यात Postgres अधिक सक्षम आहे. हे /opt/shlink/compose.yaml मध्ये ठेवा.

services:
  shlink:
    image: shlinkio/shlink:stable
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      DEFAULT_DOMAIN: s.example.com
      IS_HTTPS_ENABLED: "true"
      DB_DRIVER: postgres
      DB_HOST: database
      DB_NAME: shlink
      DB_USER: shlink
      DB_PASSWORD: ${DB_PASSWORD}
    depends_on:
      - database

  database:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: shlink
      POSTGRES_USER: shlink
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - shlink_db:/var/lib/postgresql/data

  web-client:
    image: shlinkio/shlink-web-client:stable
    restart: unless-stopped
    ports:
      - "127.0.0.1:8081:8080"

volumes:
  shlink_db:

दोन्ही प्रकाशित ports 127.0.0.1 ला bind केले आहेत. त्यामुळे पुढील section मधील reverse proxy लागू होईपर्यंत इंटरनेटवरून काहीही उपलब्ध होणार नाही. Docker स्वतःचे forwarding rules host firewall च्या आधी लागू करते. त्यामुळे साधी 8080:8080 ओळ firewall बंद असल्यासारखा दिसत असला तरी app सार्वजनिकपणे उपलब्ध करून देऊ शकते. Loopback address ला bind केल्याने हे टाळता येते. अशाच प्रकारे चालवलेल्या कोणत्याही app साठी हीच पद्धत लागू होते. VPS वरील Docker Compose मार्गदर्शकात याचे अधिक तपशीलवार वर्णन आहे.

Database password compose file शेजारील .env file मधून घेतला जातो. त्यामुळे तो YAML मध्ये साठवला जात नाही.

sudo mkdir -p /opt/shlink
printf 'DB_PASSWORD=%s\n' "$(openssl rand -base64 24)" | sudo tee /opt/shlink/.env
sudo chmod 600 /opt/shlink/.env

ते सुरू करा आणि API उपलब्ध होईपर्यंत monitor करा.

cd /opt/shlink
sudo docker compose up -d
sudo docker compose logs -f shlink

पहिल्यांदा सुरू करताना database migrations चालतात. त्यामुळे पुढील वेळेपेक्षा अधिक वेळ लागतो. सेवा स्थिर झाल्यावर ती स्थानिक पातळीवर उत्तर देते का ते तपासा.

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/rest/health

200 याचा अर्थ API सुरू आहे आणि database connection कार्यरत आहे. 503 याचा अर्थ Shlink चालू आहे; परंतु database check अयशस्वी झाला आहे. कोणत्याही database error साठी health endpoint 503 उत्तर देतो; 500 कधीही देत नाही. त्याऐवजी curl ने 000 दाखवले, तर port वर कोणतेही उत्तर मिळत नाही. Container त्याच्या start-up checks दरम्यान बंद झाला आहे आणि Docker तो पुन्हा सुरू करत आहे. त्यामुळे वरील logs वाचा. दोन्हीपैकी कोणतेही लक्षण आढळले तरी नेहमीचे कारण हेच असते की .env मधील DB_PASSWORD, Postgres तयार करताना वापरलेल्या password शी जुळत नाही. Postgres image रिकामी data directory initialize करतानाच POSTGRES_PASSWORD वाचते. नंतर password संपादित केल्याने काही परिणाम होत नाही. Volume काढून पुन्हा सुरू करेपर्यंत नवीन password लागू होत नाही.

त्याच्या समोर HTTPS समाप्त करा

Shlink पोर्ट 8080 वर साधे HTTP सर्व्ह करते. TLS हे reverse proxy मध्ये हाताळले पाहिजे आणि सर्वात महत्त्वाची सेटिंग म्हणजे मूळ host name पुढे पाठवणे. Shlink हे Host हेडर वाचून एखादा short code कोणत्या domain शी संबंधित आहे हे ठरवते, त्यामुळे जे हेडर rewrite करते असा proxy अस्तित्वात असलेल्या लिंक्ससाठी 404 प्रतिसाद देतो आणि चुकीच्या domain वर भेट दिलेल्या सांख्यिकी (stats) जोडतो.

server {
    server_name s.example.com;
    listen 80;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

त्यानंतर प्रमाणपत्र (certificate) जारी करा. नूतनीकरण टायमरसह (renewal timer) संपूर्ण प्रक्रिया Ubuntu 24.04 वरील nginx साठी Certbot मार्गदर्शिका मध्ये दिली आहे.

sudo certbot --nginx -d s.example.com

compose फाईलमधील IS_HTTPS_ENABLED: "true" मुळेच Shlink त्याच्याद्वारे परत केलेल्या short URLs मध्ये https:// प्रिंट करते. हे स्वतःहून TLS सक्षम करत नाही. याला HTTPS proxy च्या मागे false ठेवा, अन्यथा API द्वारे परत केलेली प्रत्येक लिंक ही http:// लिंक असेल जी नंतर redirect होते. यामुळे एक अतिरिक्त round trip लागते आणि web client मध्ये ते चुकीचे दिसते.

API key तयार करा

API शी कोणताही संवाद साधण्यासाठी key आवश्यक आहे. कंटेनरमधील CLI वापरून एक key तयार करा.

sudo docker compose exec shlink shlink api-key:generate --name "web client"

Command key फक्त एकदाच दाखवतो. तो आत्ताच कॉपी करा, कारण तो hashed स्वरूपात साठवला जातो आणि पुन्हा दाखवता येत नाही. shlink api-key:list मध्ये key ची नावे आणि प्रत्येक key enabled आहे का हे दिसते; प्रत्यक्ष key कधीही दिसत नाही. shlink api-key:disable आणि key चे नाव वापरून एखादी key revoke करा.

प्रत्येक REST call मध्ये X-Api-Key header द्वारे key पाठवली जाते.

curl -H "X-Api-Key: YOUR_KEY" https://s.example.com/rest/v3/short-urls

shortUrls key असलेला JSON object म्हणजे key कार्यरत आहे. type चे मूल्य https://shlink.io/api/error/invalid-api-key असलेला 401 आणि त्याचे title Invalid API key असल्यास key चुकीची, disabled किंवा expiry date नंतरची आहे.

कमांड लाइनवरून शॉर्ट लिंक्स तयार करणे

लिंक्स तयार करण्याचा CLI हा सर्वात जलद मार्ग आहे आणि तो स्क्रिप्टिंगसाठी उत्तम आहे.

sudo docker compose exec shlink shlink short-url:create https://example.com/a/very/long/path
sudo docker compose exec shlink shlink short-url:create https://example.com/docs --custom-slug docs --tag reference

--custom-slug वापरल्यामुळे तुम्हाला जनरेट केलेल्या कोडऐवजी वाचनीय लिंक मिळते. स्लग (slugs) हे प्रत्येक डोमेनसाठी युनिक असतात, त्यामुळे जर एखादा स्लग आधीच वापरला असेल, तर दुसरी विनंती अयशस्वी होते; ती जुन्या लिंकवर ओव्हरराईट होत नाही. --tag चा वापर पुन्हा पुन्हा करता येतो आणि टॅग्सच्या (tags) मदतीने तुम्ही अशा लिंक्स एकत्र करू शकता ज्यांची एकत्रित आकडेवारी तुम्हाला नंतर पाहायची आहे.

अस्तित्वात असलेल्या लिंक्सची यादी करा आणि त्यानंतर एखाद्या विशिष्ट लिंकची ट्रॅफिक तपासा.

sudo docker compose exec shlink shlink short-url:list
sudo docker compose exec shlink shlink short-url:visits docs

short-url:visits प्रत्येक क्लिकसाठी एक ओळ प्रिंट करते, ज्यामध्ये तारीख, रेफरर (referrer) आणि युजर एजंट (user agent) यांची माहिती असते. जोपर्यंत तुम्ही GEOLITE_LICENSE_KEY एनवायरमेंट व्हेरिएबल सेट करत नाही, तोपर्यंत देश आणि शहराचे कॉलम रिकामे राहतात. हे एक मोफत MaxMind की आहे, ज्याचा वापर करून Shlink हे GeoLite2 डेटाबेस डाउनलोड करते. हे सेट न केल्यास, भेटींची नोंद केली जाते, परंतु त्यांचे भौगोलिक स्थान समजत नाही.

वेब क्लायंट आणि QR कोड

वेब क्लायंट आता 127.0.0.1:8081 वर उपलब्ध आहे. त्यासाठी स्वतंत्र proxy entry आवश्यक आहे. ते सार्वजनिकपणे उपलब्ध करायचे नसल्यास SSH tunnel वापरा. पहिल्यांदा लोड केल्यावर ते server URL आणि API key विचारते. https://s.example.com आणि तुम्ही तयार केलेली key प्रविष्ट करा. क्लायंट या दोन्ही गोष्टी browser storage मध्ये ठेवतो आणि तुमच्या API ला थेट calls करतो. त्यामुळे कोणताही data इतर कोणत्याही सेवेतून जात नाही. Interface आणि API वेगळे ठेवण्याची ही पद्धत लक्षात ठेवण्यासारखी आहे. याच पद्धतीमुळे media server मध्ये बदल न करता Halcyon Jellyfin library ला 1990 च्या दशकातील rental store सारखे रूप देते.

QR codes वेब क्लायंटमधून तयार होतात, API मधून नाही. Shlink 5 ने short URL च्या शेवटी /qr-code जोडण्याची जुनी पद्धत काढून टाकली. त्यामुळे तो address आता image परत करत नाही. त्याऐवजी वेब क्लायंट तुमच्या browser मध्येच code तयार करतो. यासाठी Shlink ला request पाठवली जात नाही. Short URL list मधील कोणत्याही link साठी QR code option उघडा. Size, format आणि margin सेट करा. त्यानंतर result download करा. Code लहान आकारात print केल्यावर किंवा त्याचा काही भाग झाकला गेल्यावरही scan व्हावा, असे असल्यास error correction level वाढवा. याच dialog मध्ये colours आणि logo देखील सेट करता येतात.

ते सुरू ठेवा

URL shortener शांतपणे अपयशी ठरतो. Links redirect होणे थांबते आणि कोणीही तुम्हाला सांगत नाही, कारण link वर click करणाऱ्या व्यक्तीने तो link dead आहे असे गृहीत धरलेले असते. Home page ऐवजी प्रत्यक्ष short URL वर uptime check लावा आणि redirect नसलेल्या कोणत्याही प्रतिसादासाठी alert द्या. Self-hosted Uptime Kuma instance हे काम चांगल्या प्रकारे करते आणि ते विशिष्ट status code साठीही तपासणी करू शकते.

Container चा backup घेऊ नका; database चा backup घ्या. एक command त्याचा dump तयार करते.

sudo docker compose exec -T database pg_dump -U shlink shlink | gzip > shlink-$(date +%F).sql.gz

ही file आणि तुमची compose file मिळून नवीन server वर संपूर्ण service पुन्हा उभारता येते. Server वरील प्रत्येक app साठी या जोडीची स्वतंत्र आवृत्ती आवश्यक आहे. Photo library हे अवघड प्रकरण आहे, कारण PhotoPrism आणि Immich दोन्ही originals disk वर आणि rows database मध्ये ठेवतात. त्यामुळे केवळ dump मुळे accounts आणि settings परत मिळतात; एकही photo परत मिळत नाही. Upgrades साठी sudo docker compose pull नंतर sudo docker compose up -d चालवले जाते आणि Shlink सुरू होताना नवीन migrations चालवतो. Pull करण्यापूर्वी dump घ्या, कारण migration rollback करता येत नाही.

FAQ

रिव्हर्स प्रॉक्सी जोडल्यानंतर माझ्या शॉर्ट लिंक्स 404 (404) एरर का देत आहेत?

Shlink हे Host हेडरमधील डोमेनशी शॉर्ट कोड जुळवते. जर प्रॉक्सीने स्वतःचे नाव किंवा अंतर्गत पत्ता पाठवला, तर Shlink त्या कोडला अशा डोमेनवर शोधते जिथे कोणतीही लिंक नसते, त्यामुळे ते 404 एरर देते. nginx लोकेशन ब्लॉक मध्ये proxy_set_header Host $host; सेट करा आणि प्रॉक्सी रीलोड करा. कंटेनर रीस्टार्ट न करता लिंक्स लगेच काम करू लागतील.

मला Postgres ची गरज आहे की SQLite पुरेसे आहे?

Shlink वापरून पाहण्यासाठी SQLite ठीक आहे आणि त्यासाठी दुसऱ्या कंटेनरची गरज नाही. महत्त्वाच्या लिंक्स प्रकाशित करण्यापूर्वी Postgres वर स्थलांतर करा, कारण प्रत्येक क्लिकसोबत व्हिजिटच्या ओळी वाढत जातात आणि SQLite रायट्स (writes) सीरियलाइज करते. नंतर स्विच करताना लिंक्स एक्सपोर्ट आणि पुन्हा इम्पोर्ट कराव्या लागतात, त्यामुळे सुरुवातीलाच Postgres निवडल्यास तुमचे हे स्थलांतर वाचते.

मी कॉपी करायला विसरलेली API की (API key) पुन्हा मिळवू शकतो का?

नाही. Shlink की चा हॅश स्टोअर करते, त्यामुळे api-key:list फक्त नावे आणि स्थिती दाखवते, पण की चे मूल्य कधीही दाखवत नाही. shlink api-key:generate वापरून नवीन की तयार करा, ती वेब क्लायंटमध्ये पेस्ट करा आणि त्यानंतर जुनी की shlink api-key:disable वापरून डिसेबल करा जेणेकरून ती काम करणे थांबवेल.

माझ्या व्हिजिट स्टॅट्समध्ये देशाचे कॉलम रिकामे का आहेत?

जियोलोकेशनसाठी GeoLite2 डेटाबेसची आवश्यकता असते, जो Shlink फक्त तेव्हाच डाउनलोड करते जेव्हा तुम्ही त्याला GEOLITE_LICENSE_KEY देता. ही की MaxMind कडून मोफत मिळते. ती एन्व्हायरनमेंट सेक्शनमध्ये जोडा, कंटेनर पुन्हा तयार करा आणि नवीन व्हिजिट्सचे लोकेशन शोधले जाईल. त्याआधी नोंदवलेल्या व्हिजिट्स रिकाम्याच राहतील, जोपर्यंत तुम्ही shlink visit:locate चालवत नाही.

डोमेन कायम ठेवा आणि डेटा हलवा. pg_dump वापरून डेटाबेसचा डंप घ्या, डंप आणि कंपोज फाईल नवीन सर्व्हरवर कॉपी करा, स्टॅक सुरू करा आणि प्रत्यक्ष ट्रॅफिक येण्यापूर्वी रिकाम्या डेटाबेसमध्ये डंप रिस्टोअर करा. DNS रेकॉर्ड सर्वात शेवटी बदला. शॉर्ट कोड्स आणि त्यांचा व्हिजिट इतिहास सुरक्षित राहतो, कारण सर्व काही डेटाबेसमध्ये असते.

हा लेख उपयुक्त होता का?

#shlink#url-shortener#self-hosting#docker#postgres