VPS پر Docker Compose کی بنیادیں
Ubuntu 24.04 پر Docker Engine اور Compose v2 انسٹال کریں، دو سروس والی compose.yml لکھیں، ufw پورٹ پبلشنگ کے مسئلے سے بچیں اور والیومز کا بیک اپ لیں۔
آپ کیا بنا رہے ہیں
Docker Compose اس سائٹ پر تقریباً ہر چیز کا بنیادی ڈھانچہ ہے۔ Nextcloud، Vaultwarden، n8n، Immich، Rocket.Chat — ان سبھی گائیڈز کا آغاز "یہ compose فائل لکھیں" سے ہوتا ہے، اور یہ وہ صفحہ ہے جو وضاحت کرتا ہے کہ اس فائل کا اصل مطلب کیا ہے۔ آپ Ubuntu 24.04 پر Docker کے اپنے apt ریپوزیٹری سے Docker Engine اور Compose v2 پلگ ان انسٹال کریں گے، پھر ایک حقیقی دو سروس اسٹیک کھڑا کریں گے — Miniflux، ایک چھوٹا RSS ریڈر، اور PostgreSQL — کیونکہ یہ جوڑا وہ ہر پیٹرن استعمال کرتا ہے جو بڑی ایپس استعمال کرتی ہیں: پن شدہ امیجز، ہیلتھ چیک کے ساتھ ایک ڈیٹا بیس، ایک نامزد والیوم، .env فائل میں راز، اور صرف localhost تک محدود پبلش کردہ پورٹ۔
انسٹالیشن میں پانچ منٹ لگتے ہیں۔ اس گائیڈ کا باقی حصہ ان پہلوؤں پر گفتگو کرتا ہے جو بعد میں نقصان پہنچاتے ہیں: docker گروپ دوسرے نام سے روٹ ہونا، پبلش کردہ پورٹس آپ کے ufw قواعد کو بالکل نظر انداز کرنا، اور docker compose down پر وہ ایک flag جو بغیر کسی تصدیق کے آپ کا ڈیٹا بیس حذف کر دیتا ہے۔
ضروریات: ایک نیا Ubuntu 24.04 KVM VPS، sudo والا یوزر، اور ایک گیگابائٹ یا اس سے زیادہ RAM۔ موجودہ Docker انسٹالیشن بھی ٹھیک ہے — پہلا حصہ بتاتا ہے کہ کیا ہٹانا ہے۔
Docker کے ریپوزیٹری سے انسٹال کریں، Ubuntu کے ریپوزیٹری سے نہیں
پہلے کمانڈ سے پہلے دو غلط راستوں سے بچیں۔ Ubuntu کا اپنا docker.io پیکج کام تو کرتا ہے، لیکن Docker کے ریلیزز سے پیچھے رہتا ہے اور اس پلگ ان ترتیب سے محروم رہتا ہے جس کی ہر چیز کو ضرورت ہوتی ہے۔ اور الگ docker-compose بائنری — جس میں ہائفن ہے — وہ Compose v1 ہے: یہ Python پر مبنی ہے، 2023 سے اس کی زندگی ختم ہو چکی ہے، اور پرانے ٹیوٹوریلز کے خراب ہونے کی وجہ یہی ہے۔ آج کا Compose docker compose ہے جس میں خالی جگہ ہے، یہ ایک CLI پلگ ان ہے، اور انجن کے اسی ریپوزیٹری سے انسٹال ہوتا ہے۔
اگر ان میں سے کوئی چیز پہلے سے سرور پر موجود ہے، تو سب کو پہلے ہٹا دیں — بشمول docker-compose-v2، جو کہ پلگ ان کا Ubuntu کا اپنا پیکج ہے، تاکہ سب کچھ ایک ہی ریپوزیٹری سے آئے:
sudo apt remove -y docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runcایک بالکل نئے VPS پر Package 'docker.io' is not installed, so not removed عام آؤٹ پٹ ہے۔ پھر Docker کا ریپوزیٹری شامل کریں اور انسٹال کریں:
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginتینوں تہوں کی تصدیق کریں:
docker --version
docker compose version
sudo docker run --rm hello-worldپہلے دو ورژن اسٹرنگ پرنٹ کرتے ہیں — Docker Compose version v2.x.x اس بات کی تصدیق کرتا ہے کہ آپ کے پاس پلگ ان ہے، نہ کہ وہ مردہ v1 بائنری۔ hello-world کا چلنا Hello from Docker! پر ختم ہونا چاہیے۔ پیکج سروس کو بوٹ پر فعال کرتا ہے؛ systemctl is-enabled docker پرنٹ کرتا ہے enabled۔
docker گروپ روٹ ہے — آنکھیں کھلی رکھ کر فیصلہ کریں
ابھی ہر docker کمانڈ کو sudo درکار ہے، کیونکہ /var/run/docker.sock پر ڈیمن کا ساکٹ روٹ اور docker گروپ کی ملکیت ہے۔ بغیر رکنیت کے آپ کو ڈاکر کی سب سے زیادہ گوگل کی جانے والی غلطی ملتی ہے:
permission denied while trying to connect to the Docker daemon socket at
unix:///var/run/docker.sockمعیاری حل:
sudo usermod -aG docker $USERگروپ رکنیت لاگ ان پر لاگو ہوتی ہے، اس لیے غلطی آپ کے موجودہ شیل میں برقرار رہتی ہے۔ اس سیشن کے لیے newgrp docker چلائیں، یا لاگ آؤٹ کر کے واپس لاگ ان ہوں؛ id کو پھر آپ کے گروپس میں docker درج کرنا چاہیے۔
اب ایماندارانہ حصہ، واضح طور پر: docker گروپ کی رکنیت میزبان پر روٹ کے برابر ہے۔ نہ "روٹ جیسی"، نہ "بلند تر" — روٹ۔ اس گروپ کا کوئی بھی فرد docker run --rm -it -v /:/host alpine chroot /host چلا سکتا ہے اور پوری فائل سسٹم کا مالک بن سکتا ہے، بغیر پاس ورڈ پوچھے۔ یہ گروپ سہولت کے لیے موجود ہے، کنٹینمنٹ کے لیے نہیں۔
ڈاکر کا روٹ لیس موڈ حقیقی متبادل ہے — ڈیمن خود آپ کے غیر مراعات یافتہ صارف کے طور پر چلتا ہے۔ اس کی قیمت ہے: 1024 سے نیچے کے پورٹس کو اضافی سیٹ اپ درکار ہے، نیٹ ورکنگ ایک یوزر اسپیس شیم سے گزرتی ہے جس میں قابلِ پیمائش اوور ہیڈ ہے، اور کچھ امیجز حقیقی روٹ کے بغیر غلط رویہ دکھاتی ہیں۔ ایک سنگل ایڈمن VPS پر جہاں واحد لاگ ان پہلے ہی sudo رکھتا ہے، یہ گروپ عملی طور پر کچھ نہیں بدلتا، اور یہی وہ چیز ہے جسے یہاں کی ہر گائیڈ فرض کرتی ہے — بس اسے کبھی ایسے نہ دیں گویا یہ sudo سے کم ہو۔
compose فائل کی ساخت
ہر stack کو اپنی علیحدہ ڈائریکٹری دیں — ڈائریکٹری کا نام پروجیکٹ کا نام بن جاتا ہے، جو containers، networks اور volumes کے ساتھ prefix لگاتا ہے:
sudo mkdir -p /opt/miniflux && sudo chown $USER /opt/miniflux && cd /opt/minifluxcompose.yml بنائیں (یہ جدید نام ہے؛ docker-compose.yml اب بھی کام کرتا ہے)۔ پرانا version: کلید چھوڑ دیں — یہ متروک ہے اور Compose اسے دیکھنے پر تنبیہ کرتا ہے۔
services:
miniflux:
image: miniflux/miniflux:2.2.9
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
- DATABASE_URL=postgres://miniflux:${POSTGRES_PASSWORD}@db/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=miniflux
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux", "-d", "miniflux"]
interval: 10s
timeout: 5s
retries: 5
volumes:
db-data:اوپر کی ہر لائن ایک فیصلہ ہے۔ انہیں ایک وقت میں ایک لیں۔
image ورژنز کو مقرر کریں — :latest کے ساتھ pull کرنا ایک بے نگرانی اپ گریڈ ہے
postgres:16-alpine، نہ کہ postgres:latest۔ tag منجمد نہیں ہوتا: :latest ہر بار pull کرنے پر دوبارہ اس چیز سے تعلق قائم کرتا ہے جو maintainer نے حال ہی میں push کیا ہے۔ اسے اس معمول کی اپ گریڈ عادت کے ساتھ ملا دیں جو آپ سیکھنے والے ہیں — docker compose pull && docker compose up -d — اور :latest کا مطلب ہے کہ بڑے ورژن کی چھلانگیں اسی وقت آتی ہیں جب upstream انہیں جاری کرتا ہے، نہ کہ جب آپ منتخب کریں۔ PostgreSQL کے ساتھ یہ فرضی نہیں ہے: 16 سے 17 تک کی ایک غیر متوقع چھلانگ container کو ایک غیر مطابقت رکھنے والے data directory پر crash-loop میں ڈال دیتی ہے، کیونکہ Postgres بڑے اپ گریڈز کے لیے dump اور restore چاہیے، restart نہیں۔
کم از کم بڑا ورژن مقرر کریں (postgres:16-alpine 16.x patch ریلیزز پر عمل کرتا ہے)، اور ایپلیکیشنز کو miniflux/miniflux:2.2.9 جیسی ایک مخصوص ریلیز پر مقرر کریں — پروجیکٹ کی ریلیزز کا صفحہ چیک کریں اور فائل لکھنے کے وقت جو کچھ حالیہ ہو اسے استعمال کریں۔ اپ گریڈ پھر ایک لائن کی ترمیم بن جاتا ہے جو آپ نے جان بوجھ کر کی ہے، اور جو git diff میں نظر آتی ہے۔
127.0.0.1 پر شائع کریں، کیونکہ Docker ufw کو بائی پاس کرتا ہے
"127.0.0.1:8080:8080" — host ایڈریس، host پورٹ، container پورٹ۔ زیادہ تر ٹیوٹوریلز "8080:8080" لکھتے ہیں، جو 0.0.0.0:8080:8080 کا مختصر روپ ہے: ہر انٹرفیس پر سننا، بشمول عوامی انٹرفیس کے۔
یہاں ایک جال ہے، اور یہ تقریباً ہر کسی کو ایک بار کاٹتا ہے۔ Docker ایک پورٹ کو شائع کرنے کے لیے DNAT رول لکھتا ہے جو packet کی منزل کو container کے اندرونی IP میں فلٹرنگ سے پہلے دوبارہ لکھ دیتا ہے، اس لیے packet FORWARD راستہ اختیار کرتا ہے اور کبھی INPUT کو نہیں چھوتا، جہاں آپ کے ufw رولز موجود ہیں۔ sudo ufw deny 8080 کامیابی کی اطلاع دیتا ہے، ufw status پورٹ کو مسترد شدہ دکھاتا ہے، اور سروس پھر بھی پورے انٹرنیٹ کا جواب دیتی ہے۔ آپ کا فائر وال ٹوٹا ہوا نہیں ہے؛ اسے ڈیزائن کے مطابق بائی پاس کیا جا رہا ہے۔ Docker ufw کو کیوں بائی پاس کرتا ہے، اور container ٹریفک کو واقعی فلٹر کرنے کا طریقہ طریقہ کار اور ان پورٹس کے لیے DOCKER-USER فکس سے گزرتا ہے جنہیں عوامی رہنا چاہیے۔
وہ عادت جو پورے مسئلے کو غائب کر دیتی ہے: شائع شدہ پورٹس کو 127.0.0.1 سے بائنڈ کریں جب تک کہ آپ کے پاس ایسا نہ کرنے کی کوئی مخصوص وجہ نہ ہو، اور ان چیزوں کے لیے ایک ریورس پراکسی آگے رکھیں جو دنیا کا سامنا کرنی چاہئیں۔ یہ بالکل وہی ہے جو Traefik ریورس پراکسی گائیڈ اس صفحہ کے اگلے مرحلے کے طور پر بناتی ہے — ایک container جو پورٹس 80 اور 443 کا مالک ہے اور hostname کے ذریعے باقی سب کچھ تک روٹ کرتا ہے، TLS کے ساتھ۔ (ایک پرانے Traefik v2 سیٹ اپ سے آ رہے ہیں؟ Traefik v2 سے v3 تک مائیگریشن گائیڈ نام کی تبدیلیوں اور رول کی تبدیلیوں کا احاطہ کرتی ہے۔)
stack شروع کرنے کے بعد بائنڈ کی تصدیق کریں: sudo ss -tlnp | grep 8080 میں 127.0.0.1:8080 نظر آنا چاہیے، نہ کہ 0.0.0.0:8080 یا *:8080۔
نامزد volumes بمقابلہ bind mounts
db-data:/var/lib/postgresql/data ایک نامزد volume ہے: Docker /var/lib/docker/volumes/ کے تحت ایک ڈائریکٹری بناتا اور اس کا انتظام کرتا ہے اور اسے container میں ماؤنٹ کرتا ہے۔ متبادل ایک bind mount ہے، ./data:/var/lib/postgresql/data، جو host پر آپ کے منتخب کردہ path کو میپ کرتا ہے۔
عملی طور پر کارآمد تقسیم یہ ہے: صرف ان containers کے لیے نامزد volumes جو ڈیٹا کو چھوتے ہیں — سب سے بڑھ کر ڈیٹا بیس، کیونکہ Docker volume کو image کی متوقع ملکیت کے ساتھ شروع کرتا ہے اور فائل کی اجازتیں بالکل کام کرتی ہیں۔ ان فائلوں کے لیے bind mounts جنہیں آپ host سے چھوتے ہیں — کنفیگ فائلیں جو آپ ٹیکسٹ ایڈیٹر سے ترمیم کرتے ہیں، ایک میڈیا لائبریری جسے آپ rsync کرتے ہیں، کوئی بھی چیز جس کا path آپ واضح رکھنا چاہتے ہیں۔ کلاسک bind-mount ناکامی ملکیت ہے: container UID 999 کے طور پر چلتا ہے، آپ کی host ڈائریکٹری کی ملکیت UID 1000 کے پاس ہے، اور ایپ اسٹارٹ اپ پر اپنے لاگز میں permission denied کے ساتھ مر جاتی ہے۔ نامزد volumes اس قسم کی خرابی کو زیادہ تر غائب کر دیتے ہیں، اس قیمت پر کہ ڈیٹا Docker کے زیر انتظام path پر رہتا ہے — جس کا ذکر نیچے کیا گیا ہے۔
environment اور .env — رازوں کو git سے دور رکھیں
${POSTGRES_PASSWORD} آپ کے شیل سے نہیں پڑھا جاتا؛ Compose اسے compose.yml کے ساتھ موجود .env نامی فائل سے interpolate کرتا ہے۔ اسے بنائیں:
cat > .env <<'EOF'
POSTGRES_PASSWORD=change-me-to-something-long
ADMIN_PASSWORD=change-me-too
EOF
chmod 600 .env
echo ".env" >> .gitignoreحقیقی ویلیوز openssl rand -hex 24 کے ساتھ جنریٹ کریں۔ Hex، base64 نہیں، جان بوجھ کر: یہ پاس ورڈ DATABASE_URL کنکشن سٹرنگ کے اندر آتا ہے، اور /، +، اور = کریکٹرز جو base64 پیدا کرتا ہے URL parsing کو توڑ دیتے ہیں — یہ ناکامی تصدیق کی خرابی کے طور پر سامنے آتی ہے، نہ کہ syntax کی خرابی کے طور پر، اور ایک شام ضائع کر دیتی ہے۔ .gitignore لائن پہلے commit سے پہلے شامل کریں: compose فائل شائع کرنے اور ورژن کرنے کے لیے محفوظ ہے، .env فائل کبھی نہیں، اور وہ راز جو git ہسٹری کو چھو چکا ہے وہ راز ہے جسے آپ rotate کرتے ہیں۔ اگر آپ stack کو کوئی متغیر غائب ہونے کے ساتھ شروع کریں، تو Compose زور سے تنبیہ کرتا ہے اور خالی سٹرنگ کے ساتھ جاری رکھتا ہے — جو Postgres پاس ورڈ کے لیے ایک ٹوٹی ہوئی ڈپلائمنٹ کا مطلب ہے:
WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string.docker compose config مکمل interpolated فائل پرنٹ کرتا ہے — یہ چیک کرنے کا تیز ترین طریقہ ہے کہ containers دراصل کیا وصول کریں گے؛ یاد رکھیں کہ اس کا آؤٹ پٹ آپ کے رازوں پر مشتمل ہوتا ہے۔
depends_on کچھ کا انتظار نہیں کرتا — جب تک آپ healthcheck شامل نہ کریں
ایک خالی depends_on: [db] صرف شروع کرنے کے ترتیب کو کنٹرول کرتا ہے: Compose پہلے Postgres لانچ کرتا ہے اور ایپ کو ایک لمحے بعد، جبکہ Postgres کنکشن قبول کرنے سے ابھی کئی سیکنڈ دور ہوتا ہے۔ ایپ ڈیٹا بیس تک پہنچتی ہے، ناکام ہو جاتی ہے، اور اس بات پر منحصر ہے کہ اسے کتنا اچھا لکھا گیا تھا، crash ہو جاتی ہے یا دوبارہ کوشش کرتی ہے۔
قابل اعتماد ورژن وہی ہے جو اوپر کی فائل استعمال کرتی ہے: db سروس ایک healthcheck کی وضاحت کرتی ہے (Postgres بالکل اسی کے لیے pg_isready شپ کرتا ہے)، اور ایپ depends_on کے ساتھ condition: service_healthy کا اعلان کرتی ہے۔ Compose ڈیٹا بیس شروع کرتا ہے، ہر 10 سیکنڈ میں چیک کو poll کرتا ہے، اور Miniflux کو تب ہی شروع کرتا ہے جب چیک پاس ہو جائے۔ اگر ڈیٹا بیس کبھی صحت مند نہ ہو — غلط پاس ورڈ، خراب volume — تو ایپ کبھی شروع نہیں ہوتی اور Compose آپ کو بتاتا ہے کہ کونسی انحصار ناکام ہوا:
dependency failed to start: container miniflux-db-1 is unhealthyوہ پیغام آپ کو docker compose logs db کی طرف اشارہ کرتا ہے، جہاں اصل خرابی موجود ہے۔
restart: unless-stopped
دونوں سروسز پر restart: unless-stopped کا مطلب ہے کہ containers کریش کے بعد اور VPS ری بوٹ کے بعد واپس آتے ہیں، لیکن اگر آپ نے جان بوجھ کر docker compose stop چلایا تو وہ نیچے رہتے ہیں۔ متبادل always containers کو دستی اسٹاپ کے بعد بھی دوبارہ زندہ کرتا ہے — شاذ و نادر ہی آپ کی مراد ہوتی ہے۔ restart پالیسی کے بغیر، صبح 4 بجے کرنل اپ ڈیٹ کا ری بوٹ آپ کی سروسز کو اس وقت تک خاموش نیچے لے جاتا ہے جب تک آپ نوٹس نہ کریں۔
روزمرہ کے احکامات
ہر روز کا تمام کام پانچ احکامات ہیں، جو پروجیکٹ ڈائریکٹری سے چلائے جاتے ہیں۔
docker compose up -d # create and start; idempotent, recreates only what changed
docker compose ps # status, ports, and health of this project's containers
docker compose logs -f miniflux # follow one service's logs; --tail 100 for recent history
docker compose pull && docker compose up -d # upgrade to the pinned tags
docker compose down # stop and remove containers and the networkup -d کو بار بار چلانا محفوظ ہے — یہ فائل کو حقیقت سے موازنہ کرتا ہے اور صرف ان سروسز کو تبدیل کرتا ہے جن کی کنفیگریشن یا امیج تبدیل ہوئی ہو۔ اپ گریڈ کا جوڑا آپ کے مقرر کردہ ٹیگز کے موجودہ حوالہ جات کو لاتا ہے: postgres:16-alpine کے تحت پیچ ریلیزز، جبکہ عین مطابق پن کے لیے کچھ نہیں آتا جب تک آپ اسے ترمیم نہ کریں — اور یہی اس کا مقصد ہے۔ اپ گریڈ کے بعد پرانی امیجز جمع ہو جاتی ہیں؛ docker image prune -f سے ڈسک کی جگہ واپس حاصل کریں۔
اب تباہ کن حکم، واضح طور پر: docker compose down محفوظ ہے — کنٹینرز اور نیٹ ورک ضائع ہونے کے قابل ہیں، اور آپ کا ڈیٹا والیوم میں محفوظ ہے۔ docker compose down -v نامزد والیومز بھی حذف کر دیتا ہے۔ یہ آپ کا ڈیٹا بیس ہے، فوراً ختم، بغیر کسی تصدیق کے اور بغیر واپسی کے۔ -v فلیگ تجربات ختم کرنے کے لیے موجود ہے؛ حقیقی ڈیٹا رکھنے والے اسٹیک پر، اسے rm -rf کی طرح سمجھیں۔ /var/lib/docker/volumes/ کے تحت کوئی ردی کی ٹوکری نہیں ہے۔
چل رہے کنٹینر کے اندر ایک بار کا شیل چاہیے تو: docker compose exec db psql -U miniflux آپ کو ڈیٹا بیس میں لے جاتا ہے، اور docker compose exec miniflux sh آپ کو ایپ میں شیل دیتا ہے۔
آپ کا ڈیٹا دراصل کہاں محفوظ ہوتا ہے
نام والے والیومز پر پروجیکٹ کا پریفکس لگ جاتا ہے۔ لہٰذا miniflux نامی ڈائریکٹری میں db-data کا نام بدل کر miniflux_db-data ہو جاتا ہے:
docker volume ls
docker volume inspect miniflux_db-datainspect آؤٹ پٹ میں اہم لائن یہ ہوتی ہے:
"Mountpoint": "/var/lib/docker/volumes/miniflux_db-data/_data"وہ ڈائریکٹری ہی آپ کی ڈیٹا بیس ہے۔ اس کا مالک root ہے۔ یہ ہوسٹ فائل سسٹم پر موجود ہے۔ یہ down، اپ گریڈز اور کنٹینر ری بلڈز سے محفوظ رہتا ہے۔ آپ کے بیک اپز کو بالکل اسی چیز کو محفوظ کرنا چاہیے۔
نامزد والیوم کا بیک اپ
معیاری طریقہ ایک عارضی کنٹینر کا ہے جو والیوم کو صرف پڑھنے کے لیے ماؤنٹ کرتا ہے، ہوسٹ ڈائریکٹری کے ساتھ، اور tar کرتا ہے:
docker run --rm \
-v miniflux_db-data:/data:ro \
-v "$PWD":/backup \
alpine:3.22 tar czf /backup/miniflux-db-$(date +%F).tar.gz -C /data .کوئی انسٹالیشن نہیں، کوئی چیز چلتی نہیں رہتی، اور بحالی اس کا عکس ہے — tar xzf ایک نئی خالی والیوم میں اسی ماؤنٹ کے ساتھ الٹا۔
ڈیٹا بیس کے لیے ایک احتیاط: چلتے ہوئے Postgres ڈیٹا ڈائریکٹری کا tar کرنا درمیانی لکھائی کی حالت کو محفوظ کر سکتا ہے جو صاف شروع نہیں ہوگی۔ یا تو tar کے چند سیکنڈ کے لیے docker compose stop، یا — بہتر — منطقی ڈمپ لیں، جو ساخت کے لحاظ سے مستقل ہے:
docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gz-T Compose کے پہلے سے مختص کردہ pseudo-terminal کو غیر فعال کرتا ہے — TTY کے ذریعے ڈمپ آؤٹ پٹ کو پائپ کرنا اسے خراب کر سکتا ہے۔ ان میں سے ایک کو cron میں رکھیں اور نتیجے کو VPS سے باہر کاپی کریں؛ اسی ڈسک پر ڈیٹا کا بیک اپ جسے وہ محفوظ کرتا ہے، ایک کاپی ہے، بیک اپ نہیں۔ Nextcloud گائیڈ انہی دو طریقوں کے گرد ایک مکمل شیڈولڈ معمول بناتا ہے۔
ناکامی کے طریقے، جن میں آپ کو نظر آنے والے اسٹرنگز شامل ہیں
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock — آپ ابھی docker گروپ میں نہیں ہیں، یا ہیں لیکن سیشن اس سے پہلے کا ہے۔ id آپ کے مؤثر گروپس دکھاتا ہے؛ newgrp docker موجودہ شیل کو درست کرتا ہے، لاگ آؤٹ کر کے دوبارہ لاگ ان ہونا تمام کو درست کرتا ہے۔
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? — مختلف مسئلہ: daemon خود بند ہے۔ sudo systemctl status docker اور sudo journalctl -u docker -n 50 بتاتے ہیں کہ کیوں۔ VPS پر کلاسیکی وجہ بھرا ہوا ڈسک ہے — پہلے df -h /var/lib/docker چلائیں۔
Bind for 127.0.0.1:8080 failed: port is already allocated — ایک اور کنٹینر پہلے ہی اس ہوسٹ پورٹ کو شائع کر چکا ہے۔ docker ps دکھاتا ہے کہ کون سا؛ ہفتوں پہلے ایک تجرباتی docker run سے بچا ہوا کنٹینر عام مجرم ہے۔ اگر docker ps صاف ہے، تو ایک غیر Docker عمل اس پورٹ کو پکڑے ہوئے ہے: sudo ss -tlnp | grep 8080 اس کا نام بتاتا ہے۔
yaml: line 14: did not find expected key — نامزد لائن پر یا بالکل اوپر سنٹانش (indentation) کی خرابی ہے۔ Compose فائلیں YAML ہوتی ہیں: دو اسپیس کا سنٹانش، صرف اسپیسز، اور کہیں بھی tab کریکٹر مہلک ہے۔ docker compose config فائل کو بغیر کچھ شروع کئے تصدیق کرتا ہے، اور ہر ترمیم کے بعد اسے چلانا ایک سستا عادت ہے۔
ufw کا حیران کن رویہ بالکل کوئی ایرر نہیں چھاپتا، جو اسے خطرناک بناتا ہے: ڈیپلائے کام کرتا ہے، ufw status ٹھیک لگتا ہے، اور باہر سے پورٹ اسکین آپ کی ڈیٹا بیس کو پھر بھی ڈھونڈ لیتا ہے۔ اوپر دیے گئے پورٹس سیکشن کو دوبارہ پڑھیں، ہر ports: انٹری میں غائب 127.0.0.1: پریفکس کی جانچ کریں، اور ایک مختلف مشین سے curl http://your-vps-ip:8080 کے ساتھ تصدیق کریں — کنکشن ریفیوزڈ وہ جواب ہے جو آپ چاہتے ہیں۔
یہاں سے، Traefik گائیڈ اس واحد اسٹیک کو ایک HTTPS انٹری پوائنٹ کے پیچھے بہت سے ایپس میں بدل دیتا ہے، اور 2026 میں سیلف ہوسٹ کرنے کے قابل کیا ہے اسے چلانے کے لیے خریداری کی فہرست ہے۔
ایک گیم سرور جیسے VPS پر Minecraft سرور مشق کرنے کے لیے پہلا دوستانہ Compose پروجیکٹ ہے۔
FAQ
مجھے "permission denied while trying to connect to the Docker daemon socket" کیوں ملتی ہے؟
آپ کا صارف docker گروپ میں نہیں ہے، یا موجودہ سیشن شروع ہونے کے بعد شامل کیا گیا ہے — رکنیت صرف لاگ ان پر لاگو ہوتی ہے۔ sudo usermod -aG docker $USER چلائیں، پھر newgrp docker یا لاگ آؤٹ کر کے واپس لاگ ان ہوں، اور id سے تصدیق کریں۔ یہ گروپ ہوسٹ پر root کے مساوی رسائی دیتا ہے، اس لیے صرف ان صارفین کو شامل کریں جنہیں آپ sudo دینگے۔
کیا docker compose down میرا ڈیٹا حذف کر دیتا ہے؟
صرف docker compose down نہیں کرتا — یہ کنٹینرز اور پروجیکٹ نیٹ ورک ہٹاتا ہے؛ نامزد والیومز برقرار رہتے ہیں اور اگلا up -d انہیں دوبارہ منسلک کرتا ہے۔ docker compose down -v تباہ کن شکل ہے: یہ نامزد والیومز حذف کر دیتا ہے، یعنی آپ کی ڈیٹا بیس، بغیر کسی تصدیق کے اور بغیر واپس لانے کے۔ -v کو کبھی بھی حقیقی ڈیٹا والے اسٹیک پر نہ چلائیں جب تک آپ کے پاس تصدیق شدہ بیک اپ نہ ہو۔
docker-compose اور docker compose میں کیا فرق ہے؟
docker-compose (ہائفن) Compose v1 ہے، ایک اسٹینڈ ایلون Python بائنری جس کی زندگی 2023 میں ختم ہو گئی اور نئے سرورز پر انسٹال نہیں ہونی چاہیے۔ docker compose (اسپیس) Compose v2 ہے، Docker CLI کے لیے ایک Go پلگ ان، جو Docker کے apt ریپوزیٹری سے docker-compose-plugin کے طور پر انسٹال ہوتا ہے۔ کمانڈز اور YAML تقریباً مکمل مطابقت رکھتے ہیں، اس لیے جب کوئی پرانا ٹیوٹوریل docker-compose up کہے، تو docker compose up ٹائپ کریں۔
ufw پورٹ بلاک کرنے کے باوجود میں اپنے Docker کنٹینر تک انٹرنیٹ سے کیسے پہنچ سکتا ہوں؟
اس لیے کہ Docker پورٹس کو iptables کے PREROUTING چین میں DNAT قواعد کے ساتھ شائع کرتا ہے، اور دوبارہ لکھے گئے پیکٹس Docker کے اپنے چینز کے ذریعے FORWARD پاتھ سے گزرتے ہیں — وہ کبھی INPUT چین تک نہیں پہنچتے جہاں ufw کے قواعد لاگو ہوتے ہیں۔ اس لیے ufw deny 8080 شائع شدہ کنٹینر پورٹ پر کوئی اثر نہیں رکھتا۔ اسے ذریعے پر درست کریں: 127.0.0.1: پر شائع کریں اور سروسز کو ریورس پراکسی کے ذریعے بآسانی ظاہر کریں۔
کیا میں نامزد والیوم استعمال کروں یا بائنڈ ماؤنٹ؟
صرف کنٹینر جو ڈیٹا چھوتا ہے اس کے لیے نامزد والیومز — خاص طور پر ڈیٹا بیسز، کیونکہ Docker وہ ملکیت سیٹ کرتا ہے جو امیج توقع کرتی ہے اور اجازتیں بآسانی کام کرتی ہیں۔ ان فائلوں کے لیے بائنڈ ماؤنٹ جنہیں آپ ہوسٹ سے بھی سنبھالتے ہیں: وہ کنفیگز جنہیں آپ ایڈٹ کرتے ہیں، میڈیا جو آپ اپ لوڈ کرتے ہیں، وہ کچھ بھی جس کا پاتھ آپ واضح چاہتے ہیں۔ اگر کوئی کنٹینر بائنڈ ماؤنٹ پر permission denied کے ساتھ اسٹارٹ اپ پر ناکام ہوتا ہے، تو ہوسٹ بمقابلہ کنٹینر UID کا بے میل ہونا سب سے پہلے چیک کرنے کی چیز ہے۔