SSD Nodes Learn 8GB RAM — $66/वर्ष
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-01

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

Docker Compose द्वारे VPS वर Shlink सेटअप करा. यामध्ये Postgres डेटाबेस, सानुकूल डोमेन DNS, API की आणि क्लिक सांख्यिकी ट्रॅकिंगची संपूर्ण माहिती दिली आहे. Shlink 5.1 सह सुरुवात करा.

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

सेल्फ-होस्टेड URL शॉर्टनर हे एक लहान सर्व्हर आहे जे लांब लिंकला तुमच्या मालकीच्या लहान लिंकमध्ये रूपांतरित करते आणि त्यावर होणाऱ्या प्रत्येक क्लिकची गणना करते. यासाठी Shlink हा सर्वोत्तम पर्याय आहे: हे ओपन सोर्स आहे, ते Docker इमेज म्हणून उपलब्ध आहे आणि ते एका कंटेनरमध्ये डेटाबेससह संपूर्ण काम करते. हे मार्गदर्शक त्याला एका VPS वर, एका वास्तविक शॉर्ट डोमेनच्या मागे, HTTPS, API key, QR कोड आणि क्लिक सांख्यिकीसह स्थापित करते.

दोन घटक याला व्यावसायिक शॉर्टनरसारखे बनवतात. API सर्व्हर रिडायरेक्टला प्रतिसाद देतो आणि डेटा साठवतो. वेब क्लायंट हे एक स्वतंत्र स्टॅटिक ॲप आहे जे तुमच्या ब्राउझरवरून त्या API शी संवाद साधते. तुम्ही दोन्ही चालवू शकता किंवा फक्त API चालवून कमांड लाईनवरून ते नियंत्रित करू शकता.

येथे दिलेले व्हर्जन नंबर जुलै 2026 पर्यंतचे अद्ययावत आहेत: Shlink 5.1 आणि shlink-web-client 4.8.

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

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

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

dig +short s.example.com A

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

The compose file

Shlink ला डेटाबेसची आवश्यकता असते. चाचणीसाठी SQLite चालते, परंतु तुम्ही भविष्यात वापरणार असलेल्या कोणत्याही गोष्टीसाठी Postgres हा योग्य पर्याय आहे. याचे कारण असे की, व्हिजिटच्या ओळी (visit rows) वाढत जातात आणि 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:

दोन्ही पब्लिश केलेले पोर्ट्स 127.0.0.1 वर बाइंड होतात, त्यामुळे पुढील विभागातील रिव्हर्स प्रॉक्सी सेटअप होईपर्यंत इंटरनेटवरून काहीही ॲक्सेस करता येत नाही. Docker स्वतःचे फॉरवर्डिंग नियम होस्ट फायरवॉलच्या आधी लिहितो, याचा अर्थ असा की एक साधा 8080:8080 नियम अशा सर्व्हरवरही ॲप उघडेल ज्याचा फायरवॉल बंद असल्याचे दिसते. लूपबॅक ॲड्रेसवर बाइंड केल्यामुळे हे टाळता येते. तुम्ही अशा प्रकारे चालवलेल्या कोणत्याही ॲपसाठी हीच पद्धत लागू होते आणि Docker Compose on a VPS वरील मार्गदर्शकामध्ये याबद्दल अधिक तपशील दिला आहे.

डेटाबेसचा पासवर्ड compose फाईलच्या शेजारी असलेल्या .env फाईलमधून येतो, त्यामुळे तो कधीही 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 कार्यान्वित होताना पहा.

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

पहिली सुरुवात डेटाबेस मायग्रेशन्स चालवते, त्यामुळे नंतरच्या वेळेपेक्षा याला जास्त वेळ लागतो. जेव्हा सर्व्हिस स्थिर होईल, तेव्हा ती स्थानिक पातळीवर प्रतिसाद देत आहे का ते तपासा.

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

200 चा अर्थ असा आहे की API जिवंत आहे आणि डेटाबेस कनेक्शन काम करत आहे. येथे 500 येण्याचे कारण बहुतेक वेळा डेटाबेस असते: .env मधील DB_PASSWORD हे Postgres तयार करताना वापरलेल्या पासवर्डशी जुळत नाही, कारण Postgres इमेज केवळ रिकामी डेटा डिरेक्टरी इनिशिअलाईज करतानाच POSTGRES_PASSWORD वाचते. व्हॉल्यूम काढून टाकून पुन्हा सुरू केल्याशिवाय पासवर्ड नंतर बदलल्याचा कोणताही परिणाम होत नाही.

HTTPS टर्मिनेशन समोर ठेवा

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

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 त्याच्याद्वारे परत मिळणाऱ्या शॉर्ट URL मध्ये https:// प्रिंट करते. हे स्वतःहून TLS सक्षम करत नाही. जर तुम्ही हे HTTPS प्रॉक्सीच्या मागे false ठेवले, तर API द्वारे मिळणारी प्रत्येक लिंक ही http:// लिंक असेल, जी नंतर रिडायरेक्ट होते. यामुळे एक अतिरिक्त राऊंड ट्रिप लागते आणि वेब क्लायंटमध्ये ते चुकीचे दिसते.

API की (key) तयार करणे

API की (key) शिवाय कोणतीही गोष्ट API शी संवाद साधू शकत नाही. कंटेनरमधील CLI द्वारे एक की (key) तयार करा.

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

ही कमांड की (key) एकदाच प्रिंट करते. ती आताच कॉपी करा, कारण ती हॅश (hashed) स्वरूपात साठवली जाते आणि पुन्हा दाखवता येत नाही. shlink api-key:list प्रत्येक की (key) चे नाव आणि ती सक्षम (enabled) आहे की नाही हे दर्शवते, परंतु की (key) स्वतः कधीही दाखवत नाही. shlink api-key:disable आणि की (key) चे नाव वापरून तुम्ही ती रद्द (revoke) करू शकता.

प्रत्येक REST कॉलमध्ये X-Api-Key हेडरमध्ये की (key) असणे आवश्यक आहे.

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

shortUrls की (key) असलेला JSON ऑब्जेक्ट म्हणजे की (key) कार्य करत आहे. INVALID_API_KEY असलेला 401 म्हणजे की (key) चुकीची आहे, अक्षम (disabled) आहे किंवा तिची मुदत संपली आहे.

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

लिंक्स तयार करण्याचा 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 चा वापर पुन्हा पुन्हा करता येतो आणि टॅग्सच्या मदतीने तुम्ही अशा लिंक्स एकत्र करू शकता ज्यांची एकत्रित आकडेवारी तुम्हाला नंतर पाहायची आहे.

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

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

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

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

वेब क्लायंट आता 127.0.0.1:8081 वर उपलब्ध आहे. यासाठी स्वतंत्र प्रॉक्सी एन्ट्री आवश्यक आहे, किंवा जर तुम्हाला तो सार्वजनिक करायचा नसेल तर तुम्ही SSH टनेल वापरू शकता. पहिल्यांदा लोड होताना तो सर्व्हर URL आणि API की विचारतो. तिथे https://s.example.com आणि तुम्ही तयार केलेली की प्रविष्ट करा. क्लायंट ही माहिती ब्राउझर स्टोरेजमध्ये ठेवतो आणि थेट तुमच्या API ला कॉल करतो, त्यामुळे कोणताही डेटा इतर कोणाकडेही जात नाही.

QR कोडसाठी कोणत्याही कॉन्फिगरेशनची आवश्यकता नसते. कोणत्याही शॉर्ट URL च्या शेवटी /qr-code जोडा, म्हणजे API तुम्हाला इमेज देईल.

https://s.example.com/docs/qr-code?size=500&format=svg&margin=20

size म्हणजे पिक्सेलमध्ये असलेली रुंदी, जी 50 ते 1000 पर्यंत असू शकते; 300 हे डीफॉल्ट मूल्य आहे. format हे png किंवा svg असू शकते. margin म्हणजे कोडच्या भोवती असलेली रिकामी जागा (पिक्सेलमध्ये), आणि अंतिम इमेजचा आकार हा कोडचा आकार अधिक दोनदा मार्जिन इतका असतो. लहान आकारात छापल्यावर किंवा अंशतः झाकले गेल्यावरही स्कॅन होऊ शकणाऱ्या कोडसाठी errorCorrection=Q जोडा.

सेवा सुरू ठेवा

एक शॉर्टनर शांतपणे निकामी होतो. लिंक्स रिडायरेक्ट होणे थांबतात आणि कोणालाही याची माहिती मिळत नाही, कारण लिंकवर क्लिक करणाऱ्या व्यक्तीला ती लिंक मृत असल्याचे वाटते. होम पेजऐवजी प्रत्यक्ष शॉर्ट URL वर अपटाइम चेक सेट करा आणि रिडायरेक्ट नसलेल्या कोणत्याही गोष्टीसाठी अलर्ट मिळवा. एक सेल्फ-होस्टेड Uptime Kuma इन्स्टन्स हे काम उत्तम प्रकारे करतो आणि तो विशिष्ट स्टेटस कोडसाठी मॉनिटर करू शकतो.

कंटेनरचा नाही, तर डेटाबेसचा बॅकअप घ्या. एका कमांडद्वारे तो डंप केला जातो.

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

ती फाईल आणि तुमची compose फाईल नवीन सर्व्हरवर संपूर्ण सेवा पुन्हा तयार करतात. अपग्रेड्ससाठी sudo docker compose pull नंतर sudo docker compose up -d वापरावे लागते आणि Shlink सुरू होताना सर्व नवीन मायग्रेशन्स कार्यान्वित करते. पुल करण्यापूर्वी डंप घ्या, कारण मायग्रेशन रोल बॅक करता येत नाही.

FAQ

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

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

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

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

मी कॉपी करायला विसरलेली 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 वापरून डेटाबेस डंप करा, डंप आणि compose फाईल नवीन सर्व्हरवर कॉपी करा, स्टॅक सुरू करा आणि प्रत्यक्ष ट्रॅफिक येण्यापूर्वी रिकाम्या डेटाबेसमध्ये डंप रिस्टोअर करा. DNS रेकॉर्ड सर्वात शेवटी बदला. शॉर्ट कोड्स आणि त्यांचा व्हिजिट इतिहास सुरक्षित राहतो, कारण सर्व काही डेटाबेसमध्ये असते.

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