SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-15

LinkBreeze کو VPS پر Docker Compose سے چلائیں

VPS پر LinkBreeze چلانے کا درست طریقہ جانیں: Docker Compose، Caddy، pinned image tags، cookieless click tracking اور وہ واحد volume جو پوری site محفوظ رکھتا ہے۔

LinkBreeze کیا ہے

LinkBreeze ایک self-hosted Linktree متبادل ہے۔ یہ ایک Docker container ہے جو public link-in-bio page اور admin dashboard فراہم کرتا ہے۔ اس کی تمام state ایک SQLite file میں محفوظ ہوتی ہے۔ اسے MIT license کے تحت جاری کیا گیا ہے، TypeScript میں Next.js پر لکھا گیا ہے، اور ghcr.io/manak-hash/linkbreeze کے طور پر شائع کیا گیا ہے۔ اسے چلانے کے لیے آپ کو ایک VPS، ایسا domain درکار ہے جس کا A record اس VPS کی طرف اشارہ کرتا ہو، ports 80 اور 443 کھلے ہوں، اور Compose plugin کے ساتھ Docker Engine موجود ہو۔

یہ guide اس deployment کا احاطہ کرتی ہے جسے repository حقیقتاً support کرتی ہے: reverse proxy کے پیچھے Docker Compose، جہاں reverse proxy اپنے certificates حاصل کرتا ہے۔ اس guide میں یہ بھی بتایا گیا ہے کہ کیا چیزیں fail ہوتی ہیں، کیونکہ bio میں موجود link ایک public URL ہوتا ہے جس پر دوسرے لوگ click کرتے ہیں، اور broken link سے click ضائع ہو جاتا ہے۔

اس سے پہلے یہ واضح کر لیں کہ یہ project کتنا نیا ہے۔

کیا LinkBreeze عوامی پروفائل لنک کے لیے کافی پختہ ہے؟

August 2026 تک repository کے پاس 178 stars، 17 forks اور صرف ایک maintainer ہے۔ پہلی tagged release، v1.0.0، 1 July 2026 کی ہے۔ یہ چند ہفتے پرانا project ہے، چند سال پرانا نہیں۔

ChartLinkBreeze tagged releases per week, v1.0.0 to v1.2.7
The data behind this chart
[
  {
    "week": "2026-06-29",
    "releases": 3,
    "cumulative": 3
  },
  {
    "week": "2026-07-06",
    "releases": 3,
    "cumulative": 6
  },
  {
    "week": "2026-07-13",
    "releases": 1,
    "cumulative": 7
  },
  {
    "week": "2026-07-20",
    "releases": 2,
    "cumulative": 9
  },
  {
    "week": "2026-07-27",
    "releases": 3,
    "cumulative": 12
  },
  {
    "week": "2026-08-03",
    "releases": 2,
    "cumulative": 14
  },
  {
    "week": "2026-08-10",
    "releases": 3,
    "cumulative": 17
  }
]

v1.0.0 کے بعد project نے 17 tagged releases جاری کی ہیں، جو 7 calendar weeks پر محیط ہیں۔ اس chart کا آخری ہفتہ یہ guide لکھے جانے کے وقت ابھی جاری تھا اور اس میں پہلے ہی ان releases میں سے 3 شامل تھیں۔

اسے دو الگ حقائق کے طور پر سمجھیں۔ Maintainer فعال ہے اور bugs چند دنوں میں fix ہو جاتے ہیں۔ Schema اور defaults بھی ابھی تبدیل ہو رہے ہیں، اس لیے جو instance آپ deploy کرکے بھول جائیں گے، وہ لکھے جانے والے code سے وقت کے ساتھ کافی مختلف ہو جائے گا۔

License آپ کو بدترین صورتِ حال سے تحفظ دیتا ہے۔ MIT license، container image اور آپ کی اپنی disk پر موجود SQLite file کا مطلب ہے کہ development رک بھی جائے تو آپ کے پاس موجود setup چلتا رہے گا۔ لیکن یہ آپ کو اس public-facing web app سے محفوظ نہیں رکھتا جسے security fixes ملنا بند ہو جائیں اور جو وقت کے ساتھ liability بن جائے۔ اسے ایسی سروس کے طور پر deploy کریں جسے آپ مسلسل update کرتے رہیں، اور backup routine کو پہلے دن سے فعال رکھیں۔

image tag کو pin کریں، اور latest نہ چلائیں

release workflow ہر version کے لیے بالکل دو tags push کرتا ہے: latest، اور version number جس میں ابتدائی v ہٹا دیا گیا ہو۔ اس لیے release v1.2.7 کے لیے pinned tag ghcr.io/manak-hash/linkbreeze:1.2.7 ہے۔ :v1.2.7 لکھنے سے کچھ pull نہیں ہوتا اور Docker manifest unknown رپورٹ کرتا ہے، کیونکہ یہ tag کبھی push نہیں کیا گیا۔

اسے pin کریں کیونکہ latest تبدیل ہوتا رہتا ہے۔ اوپر دیے گئے chart کی cadence کے مطابق، latest کے خلاف docker compose pull آپ کے audience کے زیرِ استعمال page کا بغیر review کیا گیا upgrade ہے۔ pinned tag کے ساتھ upgrade اسی وقت ہوتا ہے جب آپ file میں ترمیم کرتے ہیں۔

image کے بارے میں ایک اور بات۔ release workflow بغیر platforms: setting کے build کرتا ہے، اس لیے published image صرف linux/amd64 ہے۔ arm64 host پر pull no matching manifest for linux/arm64/v8 in the manifest list entries کے ساتھ fail ہو جاتا ہے۔ اگر آپ x86 کے بجائے ARM VPS چلا رہے ہیں تو image اسی box پر build کریں:

git clone --branch v1.2.7 --depth 1 https://github.com/Manak-hash/LinkBreeze.git
cd LinkBreeze
docker build -t linkbreeze:1.2.7 .

پھر نیچے دی گئی compose file میں image name کے طور پر linkbreeze:1.2.7 استعمال کریں۔

Caddy کے پیچھے LinkBreeze تعینات کریں اور خودکار TLS فعال کریں

Caddy خود ہی Let's Encrypt سے certificates طلب اور renew کرتا ہے، اس لیے TLS (transport layer security) کے لیے certificate کا الگ مرحلہ درکار نہیں ہوتا۔ پوری deployment ایک ہی directory میں موجود تین files پر مشتمل ہے۔

پہلے secret بنائیں:

mkdir -p ~/linkbreeze && cd ~/linkbreeze
printf 'SECRET_KEY=%s\n' "$(openssl rand -hex 32)" > .env
chmod 600 .env

SECRET_KEY admin session cookie پر دستخط کرتا ہے اور analytics visitor hash میں salt شامل کرتا ہے۔ repository میں شائع شدہ compose file میں اس کی default value ${SECRET_KEY:-changeme-in-production} ہے۔ اس لیے اگر آپ یہ مرحلہ چھوڑ دیں تو instance ایسی session signing key کے ساتھ چلتا ہے جو GitHub پر public طور پر درج ہے۔ پہلی start سے پہلے اسے set کریں، کیونکہ بعد میں اسے تبدیل کرنے سے آپ logout ہو جائیں گے اور analytics salt reset ہو جائے گا۔

docker-compose.yml لکھیں:

services:
  linkbreeze:
    image: ghcr.io/manak-hash/linkbreeze:1.2.7
    restart: unless-stopped
    volumes:
      - linkbreeze-data:/app/data
    environment:
      - DATABASE_PATH=/app/data/linkbreeze.db
      - SECRET_KEY=${SECRET_KEY}
      - BASE_URL=https://links.example.com
    networks:
      - linkbreeze-net

  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    networks:
      - linkbreeze-net

networks:
  linkbreeze-net:

volumes:
  linkbreeze-data:
  caddy-data:
  caddy-config:

BASE_URL اختیاری ہے، لیکن اسے set کرنا مفید ہے۔ یہ app کو اس کا حقیقی public address بتاتا ہے۔ اس طرح forged Host header کے ساتھ آنے والی request app کو کسی دوسرے domain کے links generate کرنے پر مجبور نہیں کر سکتی۔

اس کے ساتھ Caddyfile اپنی domain کے ساتھ لکھیں:

links.example.com {
    encode zstd gzip
    reverse_proxy linkbreeze:3000
}

Caddy proxied requests پر default طور پر X-Forwarded-For اور X-Forwarded-Proto set کرتا ہے۔ analytics کا انحصار انہی پر ہے۔ اب اسے start کریں:

docker compose up -d
docker compose ps
docker compose logs -f caddy

docker compose ps میں LinkBreeze container کی حالت healthy دکھائی دینی چاہیے۔ image میں اپنا healthcheck شامل ہے، wget --spider -q http://127.0.0.1:3000/api/health، اس لیے آپ کو الگ healthcheck شامل کرنے کی ضرورت نہیں۔ repository کی اپنی Caddy example سے healthcheck copy نہ کریں۔ وہ curl چلاتا ہے، جبکہ image node:22-alpine پر built ہے، جس میں busybox wget موجود ہے اور curl موجود نہیں۔ pages درست طور پر serve ہونے کے باوجود وہ container unhealthy report کرتا ہے۔

browser میں https://links.example.com کھولیں۔ پہلی visit /setup پر setup wizard کھولتی ہے، جو واحد admin account بناتا ہے۔ اس کے بعد dashboard /dashboard پر اور login form /login پر دستیاب ہوتا ہے۔ یہ account اسی instance تک محدود ہے، اور app میں single sign-on کے لیے کوئی hook نہیں ہے۔ اگر آپ چاہتے ہیں کہ dashboard کا login آپ کی hosted دیگر services کے login جیسا ہو، تو اس کے لیے سامنے forward auth proxy درکار ہوگا، مثلاً self-hosted Authentik۔

غور کریں کہ compose file کیا نہیں کرتی: یہ port 3000 کو کبھی publish نہیں کرتی۔ public interface پر صرف Caddy listen کرتا ہے۔ اگر Compose file syntax آپ کے لیے نیا ہے تو VPS کے لیے Docker Compose basics ان حصوں کی وضاحت کرتا ہے جنہیں یہ file فرض کرتی ہے۔ اگر آپ پہلے ہی کوئی دوسری service سامنے چلا رہے ہیں تو Nginx، Caddy اور Traefik کا تقابلی جائزہ بتاتا ہے کہ کیا تبدیلیاں درکار ہوں گی۔ repository میں Nginx with Certbot، Traefik اور Cloudflare tunnel کے لیے working examples شامل ہیں۔

آپ کا ڈیٹا کہاں موجود ہے، اور backup میں کیا شامل ہونا چاہیے

DATABASE_PATH، /app/data/linkbreeze.db کی طرف اشارہ کرتا ہے۔ اپ لوڈ کیے گئے avatars اور link thumbnails اسی کے ساتھ /app/data/uploads میں لکھی جاتی ہیں۔ دونوں named volume linkbreeze-data میں موجود ہیں، اس لیے backup کی اکائی volume ہے، صرف database file نہیں۔ اگر uploads directory کے بغیر file بحال کی جائے تو صفحے کی ہر image 404 واپس کرے گی۔

باقی تمام ڈیٹا واقعی اسی ایک database میں موجود ہے: صفحات، links، settings، theme، email subscribers اور analytics rows۔

copy اس وقت بنائیں جب container بند ہو:

docker compose stop linkbreeze
docker compose cp linkbreeze:/app/data ./backup-$(date +%F)
docker compose start linkbreeze

پہلے container بند کریں، کیونکہ کسی process کے database میں لکھتے وقت SQLite database copy کرنے سے نامکمل transaction شامل ہو سکتی ہے۔ اس کے نتیجے میں copy corrupt file کے طور پر کھل سکتی ہے۔ copy بننے کے دوران صفحہ offline رہے گا۔ بحالی بھی اسی عمل کو الٹی سمت میں کرنے کے برابر ہے:

docker compose stop linkbreeze
docker compose cp ./backup-2026-08-14/. linkbreeze:/app/data
docker compose start linkbreeze
docker compose logs -f linkbreeze

dashboard JSON export بھی فراہم کرتا ہے، جو /api/backup سے linkbreeze-backup-YYYY-MM-DD.json کے طور پر دستیاب ہوتا ہے۔ اس میں profile، links، settings اور محفوظ themes شامل ہوتے ہیں۔ اس میں analytics history، email subscribers یا اپ لوڈ کی گئی images شامل نہیں ہوتیں۔ اسے بحال کرنے پر ان چار tables کی موجودہ rows حذف ہو جاتی ہیں، پھر file کی rows داخل کی جاتی ہیں۔ اسے hosts منتقل کرنے یا editing کی غلطی واپس لینے کے لیے config snapshot سمجھیں۔ اصل backup volume copy ہے۔

یہاں storage کے دو اصول وہی ہیں جو کسی بھی جگہ VPS پر SQLite کو production میں چلانے کے لیے لاگو ہوتے ہیں۔ database کو local disk پر رکھیں، کیونکہ network filesystem پر SQLite کی locking قابلِ اعتماد نہیں ہوتی۔ corrupt page کا سامنا ہونے پر اس کی وجہ واضح ہو جاتی ہے۔ اگر named volume کی جگہ host bind mount استعمال کریں تو پہلے host directory پر chown چلائیں۔ container non-root node user کے طور پر چلتا ہے، جس کا uid node:22-alpine میں 1000 ہے۔ root کی بنائی ہوئی directory اس user کے لیے writable نہیں ہوتی، اس لیے app database نہیں کھول سکتی اور startup پر container exit ہو جاتا ہے۔ Compose میں named volumes کے مقابل bind mounts اس انتخاب کی مکمل وضاحت کرتا ہے۔

یہ وہ feature ہے جو ایسی page کو self-host کرنے کا جواز فراہم کرتا ہے جسے آپ کہیں اور مفت حاصل کر سکتے ہیں۔

تجزیاتی اعداد و شمار cookies کے بغیر جمع کیے جاتے ہیں۔ visitor کے لیے کوئی cookie set نہیں کی جاتی اور public page پر کوئی third-party script load نہیں ہوتی۔ visitor کی شناخت IP address، user agent string اور salt کے SHA-256 hash سے کی جاتی ہے، جسے 16 hexadecimal characters تک محدود کیا جاتا ہے۔ salt خود موجودہ UTC date اور آپ کے SECRET_KEY کا hash ہوتا ہے، اس لیے یہ UTC midnight پر تبدیل ہو جاتا ہے اور کل کے hashes کو آج کے hashes سے match نہیں کیا جا سکتا۔ اصل IP address database میں کبھی نہیں لکھا جاتا۔

Clicks server پر count کیے جاتے ہیں۔ public page پر موجود ہر http link آپ کے اپنے domain پر /go/<id> کی طرف اشارہ کرتا ہے۔ یہ endpoint click record کرتا ہے اور پھر اصل destination پر 302 redirect کے ذریعے جواب دیتا ہے۔ اس لیے JavaScript disabled رکھنے والے readers اور ان in-app browsers میں بھی counting کام کرتی ہے جو background requests block کرتے ہیں۔ Page views /api/track کے ذریعے record کیے جاتے ہیں۔

دو exclusions کا جاننا مفید ہے۔ valid admin session رکھنے والی request کو skip کر دیا جاتا ہے، اس لیے اپنی page edit کرنے سے numbers میں اضافہ نہیں ہوتا۔ معلوم crawler user agents کو بھی skip کر دیا جاتا ہے۔

consent کے بارے میں: reader کے device پر کچھ بھی store نہیں کیا جاتا، اور reader کے device پر store کی جانے والی cookie ہی وہ مخصوص چیز ہے جس کے لیے cookie banner اجازت طلب کرتا ہے۔ آپ کی obligations اس بات پر بھی منحصر ہیں کہ آپ کے readers کہاں رہتے ہیں، اس لیے ان کی جانچ کریں۔ تاہم یہاں disclose کرنے کے لیے کوئی tracking cookie نہیں ہے اور data وصول کرنے والا کوئی third party بھی نہیں ہے۔

ایک caveat لوگوں کو حیران کرتا ہے: SECRET_KEY rotate کرنے سے daily salt بھی تبدیل ہو جاتا ہے، اس لیے اس لمحے کے بعد ہر returning visitor کو نئے visitor کے طور پر count کیا جاتا ہے۔

Analytics میں ملک کا کالم خالی کیوں ہے؟

کیونکہ آپ کے stack میں کوئی بھی چیز country header مقرر نہیں کرتی۔ LinkBreeze، ملک کا تعین cf-ipcountry اور x-vercel-ip-country جیسے proxy headers سے کرتا ہے۔ اپنے Caddy یا Nginx کے پیچھے موجود VPS پر ان میں سے کوئی header موجود نہیں ہوتا، اس لیے ملک کو null کے طور پر ریکارڈ کیا جاتا ہے اور breakdown خالی رہتا ہے۔ Container کے اندر کوئی GeoIP database موجود نہیں ہے۔

اسے پُر کرنے کے دو طریقے ہیں۔ Domain کے سامنے Cloudflare رکھیں، جو اپنی proxy کردہ ہر request میں cf-ipcountry شامل کرتا ہے۔ یا اپنے reverse proxy میں مقامی GeoIP lookup کے ذریعے ان headers میں سے ایک مقرر کریں۔

متعلقہ مسئلہ زیادہ سنگین ہے، اس لیے اسے بھی چیک کریں۔ Click اور view handlers پہلے client address کو X-Forwarded-For سے، پھر X-Real-IP سے پڑھتے ہیں، اور جب دونوں headers موجود نہ ہوں تو 0.0.0.0 پر fallback کرتے ہیں۔ اگر آپ port 3000 کو سامنے کسی proxy کے بغیر براہِ راست internet پر publish کریں تو ہر visitor کی hash ایک ہی value بنتی ہے۔ اس کا مطلب ہے کہ unique visitors ہمیشہ 1 دکھائے گا، اور فی-IP rate limit، جو 60 events فی minute ہے، بیک وقت آپ کے پورے audience پر لاگو ہوگی۔ اوپر موجود reverse_proxy directive کے پیچھے Caddy یہ header خود مقرر کر دیتا ہے، جس سے دونوں مسائل ختم ہو جاتے ہیں۔

Linktree سے درآمد، اور کون سی چیزیں منتقل نہیں ہوتیں

Dashboard کا migration wizard ایک public profile URL یا exported file قبول کرتا ہے۔ یہ linktr.ee، bento.me، lnk.bio، tap.link، hopp.bio، beacons.ai، solo.to، linkfly، mssg.me اور LittleLink صفحات کے علاوہ عمومی HTML اور JSON exports بھی پہچانتا ہے۔ Linktree یا Bento URL کے لیے یہ ان صفحات میں شامل __NEXT_DATA__ JSON پڑھتا ہے۔ Static page کے لیے یہ anchor tags پڑھتا ہے۔

منتقل ہونے والی معلومات میں ہر link کا title، URL، description اور image، یہ معلومات کہ link کسی social profile کا ہے یا نہیں، اور آپ کا display name، bio اور avatar شامل ہیں۔ Database میں کچھ بھی لکھنے سے پہلے آپ دریافت ہونے والے links میں سے منتخب کرتے ہیں کہ کنہیں رکھنا ہے۔

Analytics history، theme اور layout، email subscribers، scheduled publish dates، اور وہ تمام معلومات منتقل نہیں ہوتیں جنہیں پرانا platform اپنی login کے پیچھے رکھتا ہے۔ ظاہری انداز خود دوبارہ بنانے کی تیاری کریں، اور یہ تسلیم کریں کہ پرانے clicks کی history پرانی service پر ہی رہے گی۔

Importer URL آپ کے browser کے بجائے آپ کے server سے fetch کرتا ہے، اس لیے یہ ایسے addresses مسترد کرتا ہے جو public نہ ہوں۔ Private/local URLs are not allowed کا مطلب ہے کہ آپ نے اپنے network کے اندر موجود address دیا ہے، اور یہ انکار جان بوجھ کر کیا جاتا ہے: اس کے بغیر dashboard access رکھنے والا کوئی بھی شخص آپ کے server کو ایسی machines کی جانچ کے لیے استعمال کر سکتا تھا جن تک صرف آپ کا server پہنچ سکتا ہے۔ آپ کو جو دیگر messages دکھائی دے سکتے ہیں وہ Only http and https URLs are allowed، Request timed out اور Response too large ہیں۔

Scraping کسی دوسرے شخص کے markup پر منحصر ہوتی ہے۔ اگر wizard ایسے page پر کچھ نہ ڈھونڈ سکے جس پر واضح طور پر links موجود ہوں، تو اس platform نے اپنا HTML اس وقت تبدیل کر دیا ہے جب parser لکھا گیا تھا۔ Fix کا انتظار کرنے کے بجائے links دستی طور پر شامل کریں۔ اگر آپ کو دراصل profile page کے بجائے قابلِ پیمائش short links درکار ہیں، تو Shlink جیسا self-hosted URL shortener یہ کام کرتا ہے اور اسی box پر آسانی سے چلتا ہے۔

پن شدہ deployment کو اپ ڈیٹ کرنا

# edit the image tag in docker-compose.yml, then
docker compose pull
docker compose up -d
docker compose logs -f linkbreeze

Container شروع ہونے پر schema migrations خودکار طور پر چلتی ہیں۔ انہیں واپس چلانے کا کوئی documented طریقہ موجود نہیں، اس لیے پہلے volume کی copy بنائیں۔ ایسا upgrade جسے واپس نہ کیا جا سکے، صرف اسی وقت محفوظ ہے جب آپ پہلے والی حالت restore کر سکتے ہوں۔

نئی release دستیاب ہونے پر dashboard ایک banner دکھاتا ہے۔ یہ ہر 24 گھنٹے میں project کی GitHub repository سے ایک چھوٹی version file حاصل کر کے جانچ کرتا ہے، اور آپ کی instance کے بارے میں کوئی معلومات نہیں بھیجتا۔ tag تبدیل کرنے سے پہلے release notes پڑھیں، کیونکہ project کے اس مرحلے پر minor version ان defaults کو تبدیل کر سکتی ہے جن پر آپ انحصار کرتے ہیں۔

ناکامی کی صورتیں اور نظر آنے والے strings

manifest unknown کے دوران۔ tag کو :v1.2.7 کے طور پر لکھا گیا تھا۔ Registry tags میں v نہیں ہوتا، اس لیے :1.2.7 استعمال کریں۔

no matching manifest for linux/arm64/v8 in the manifest list entries۔ Published image صرف amd64 کو support کرتی ہے۔ اسے tagged source سے ARM host پر build کریں۔

صفحہ درست load ہو رہا ہے، لیکن container unhealthy رپورٹ کرتا ہے۔ آپ کی compose file میں healthcheck curl چلا رہا ہے، جو image میں موجود نہیں۔ اسے حذف کریں اور image کا اپنا wget healthcheck چلنے دیں۔

Caddy certificate error دکھاتا ہے، یا کچھ بھی serve نہیں کرتا۔ docker compose logs caddy چیک کریں۔ عام وجوہات یہ ہیں کہ A record ابھی اس VPS کی طرف point نہیں کر رہا، یا firewall پر port 80 بند ہے۔ اس سے ACME (automatic certificate management environment) کا HTTP challenge رک جاتا ہے، جسے Caddy domain پر اپنا control ثابت کرنے کے لیے استعمال کرتا ہے۔

Unique visitors کی تعداد 1 پر رکی ہوئی ہے۔ کوئی proxy X-Forwarded-For set نہیں کر رہا، اس لیے ہر visitor کا hash یکساں بنتا ہے۔

Container startup کے فوراً بعد exit ہو جاتا ہے، حالانکہ کل تک درست کام کر رہا تھا۔ اگر آپ named volume سے host bind mount پر منتقل ہوئے ہیں تو data directory کی ملکیت root کے پاس ہے، جبکہ app uid 1000 کے طور پر چلتی ہے۔ اس لیے app database file نہیں کھول سکتی۔ Host directory پر sudo chown -R 1000:1000 چلائیں۔

Tracking requests کا جواب HTTP 429 کے ساتھ آتا ہے۔ /api/track اور /go/<id> پر per-IP throttle کی حد پوری ہو گئی ہے۔ Visitors کو اب بھی اپنی destination پر redirect کیا جاتا ہے، صرف click count نہیں ہوتا۔

FAQ

یہ ایک نیا project ہے۔ August 2026 تک repository میں 178 stars، 17 forks اور ایک maintainer موجود ہے، جبکہ پہلی release کی تاریخ 1 July 2026 ہے۔ اوسطاً ہفتے میں دو مرتبہ سے زیادہ releases آتی ہیں، اس لیے bugs تیزی سے fix ہوتے ہیں اور behaviour بھی تیزی سے بدلتا ہے۔ MIT license اور local SQLite file کی وجہ سے development رک جانے پر بھی آپ کے پاس working page رہتا ہے، لیکن security fixes کے بغیر public web app ذمہ داری بن جاتی ہے۔ اس لیے اسے ایسی software سمجھیں جسے آپ مسلسل update کریں گے، نہ کہ ایک مرتبہ install کر کے چھوڑ دیں گے۔

مجھے LinkBreeze کا کون سا image tag چلانا چاہیے؟

version tag چلائیں، مثلاً ghcr.io/manak-hash/linkbreeze:1.2.7، اور اسے جان بوجھ کر تبدیل کریں۔ release workflow صرف latest اور bare version number push کرتا ہے، اس لیے v کے ساتھ :v1.2.7 موجود نہیں ہے اور Docker manifest unknown واپس کرتا ہے۔ image صرف linux/amd64 کے لیے build کی گئی ہے، اس لیے arm64 VPS پر آپ کو tag clone کر کے مقامی طور پر build کرنا ہوگا۔

LinkBreeze analytics میں ملکوں کی breakdown خالی کیوں رہتی ہے؟

LinkBreeze visitor کا ملک proxy headers، جیسے cf-ipcountry یا x-vercel-ip-country، سے پڑھتا ہے اور اس کا اپنا GeoIP database نہیں ہے۔ آپ کے اپنے Caddy یا Nginx کے پیچھے موجود VPS ان میں سے کوئی header set نہیں کرتا، اس لیے ملک null کے طور پر محفوظ ہوتا ہے۔ domain کے سامنے Cloudflare رکھیں، یا اپنے reverse proxy سے مقامی GeoIP lookup کی بنیاد پر ان headers میں سے کوئی ایک set کرائیں۔

مجھے عین کیا backup کرنا چاہیے، اور اسے restore کیسے کروں؟

صرف database file نہیں، بلکہ پوری linkbreeze-data volume کا backup لیں۔ /app/data/linkbreeze.db میں ہر link، page، setting، subscriber اور analytics row موجود ہوتی ہے، جبکہ /app/data/uploads میں page کے referenced avatar اور thumbnail images موجود ہوتی ہیں۔ container کو stop کریں، docker compose cp linkbreeze:/app/data ./backup-$(date +%F) چلائیں، پھر اسے دوبارہ start کریں۔ restore کرنے کے لیے directory کو stopped container میں واپس copy کریں اور container start کریں۔ dashboard سے حاصل ہونے والا JSON export profile، links، settings اور themes کا config snapshot ہوتا ہے۔ اس میں analytics یا images شامل نہیں ہوتیں۔

کیا Linktree سے import کرنے پر analytics اور theme بھی منتقل ہوتے ہیں؟

نہیں۔ migration wizard آپ کے پرانے public profile سے link titles، URLs، descriptions اور images کے علاوہ display name، bio اور avatar پڑھتا ہے۔ analytics history، theme، email subscribers اور scheduled publish dates منتقل نہیں ہوتیں۔ import کے بعد theme editor میں ظاہری انداز دوبارہ بنائیں، اور توقع رکھیں کہ click history پرانے platform پر ہی رہے گی۔

#linkbreeze#linktree-alternative#docker-compose#sqlite#self-hosting#analytics