SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-27

Ubuntu 24.04 पर Docker Compose कैसे सेटअप करें

Ubuntu 24.04 पर Docker Engine और Compose v2 इंस्टॉल करने का तरीका सीखें। हम ufw पोर्ट बायपास समस्या को हल करेंगे और डेटा सुरक्षा के लिए वॉल्यूम बैकअप के सटीक स्टेप्स साझा करेंगे।

आप क्या बना रहे हैं

Docker Compose इस साइट पर मौजूद लगभग हर चीज़ का आधार है। Nextcloud, Vaultwarden, n8n, Immich, Rocket.Chat, इन सभी गाइड की शुरुआत "यह compose file लिखें" से होती है, और यह पेज बताता है कि उस फ़ाइल का वास्तव में क्या अर्थ है। आप Ubuntu 24.04 पर Docker के आधिकारिक apt repository से Docker Engine और Compose v2 प्लगइन इंस्टॉल करेंगे, और फिर एक वास्तविक दो-सर्विस स्टैक तैयार करेंगे: Miniflux (एक छोटा RSS रीडर) और PostgreSQL। यह जोड़ी उन सभी पैटर्न्स का अभ्यास कराती है जिनका उपयोग बड़े ऐप्स करते हैं: pinned images, healthcheck के साथ एक डेटाबेस, एक named volume, .env फ़ाइल में secrets, और केवल localhost पर पब्लिश किया गया पोर्ट।

इंस्टॉलेशन में पाँच मिनट लगते हैं। इस गाइड का बाकी हिस्सा उन समस्याओं को कवर करता है जो बाद में परेशान करती हैं: docker ग्रुप का root के समान होना, पब्लिश किए गए पोर्ट्स का सीधे आपके ufw रूल्स को बायपास करना, और docker compose down पर वह एक फ्लैग जो बिना किसी पुष्टि के आपके डेटाबेस को डिलीट कर देता है।

पूर्व-आवश्यकताएँ: एक नया Ubuntu 24.04 KVM VPS, sudo एक्सेस वाला एक यूजर, और एक गीगाबाइट या उससे अधिक RAM। यदि Docker पहले से इंस्टॉल है तो भी ठीक है, पहला सेक्शन यह बताता है कि क्या हटाना है।

Ubuntu के repo के बजाय Docker के repo से install करें

पहला command चलाने से पहले दो गलतियों से बचें। Ubuntu का अपना docker.io package काम तो करता है, लेकिन यह Docker के releases से पीछे रहता है और इसमें उस plugin layout का अभाव होता है जिसकी अन्य सभी tools अपेक्षा करते हैं। और standalone docker-compose binary, यानी वह जिसमें hyphen लगा है, Compose v1 है: यह Python पर आधारित है, 2023 से end-of-life है, और यही कारण है कि पुराने tutorials काम नहीं करते। आज का Compose docker compose है, जिसमें space का उपयोग होता है, यह एक CLI plugin है, और इसे engine वाले repository से ही install किया जाता है।

यदि इनमें से कुछ भी पहले से server पर मौजूद है, तो उसे पहले हटा दें, जिसमें docker-compose-v2 भी शामिल है, जो कि plugin का Ubuntu का अपना packaging है, ताकि सब कुछ एक ही repository से आए:

sudo apt remove -y docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc

Package 'docker.io' is not installed, so not removed एक fresh VPS पर सामान्य output है। इसके बाद Docker का repository जोड़ें और install करें:

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

तीनों layers को verify करें:

docker --version
docker compose version
sudo docker run --rm hello-world

पहले दो commands version strings print करते हैं, Docker Compose version v2.x.x यह पुष्टि करता है कि आपके पास plugin है, न कि पुरानी v1 binary। hello-world run का अंत Hello from Docker! के साथ होना चाहिए। यह package boot के समय service को enable कर देता है; systemctl is-enabled docker चलाने पर enabled print होना चाहिए।

docker group root है, इसे समझदारी से चुनें

अभी हर docker कमांड के लिए sudo की आवश्यकता होती है, क्योंकि /var/run/docker.sock पर स्थित डेमन का सॉकेट root और docker ग्रुप के स्वामित्व में होता है। ग्रुप की सदस्यता के बिना आपको 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 ग्रुप की सदस्यता होस्ट पर root के बराबर है। यह "root जैसा" या "elevated" नहीं है, यह पूर्ण root है। इस ग्रुप का कोई भी सदस्य docker run --rm -it -v /:/host alpine chroot /host चला सकता है और पूरे फाइलसिस्टम का मालिक बन सकता है, बिना किसी पासवर्ड के। यह ग्रुप सुविधा के लिए मौजूद है, सुरक्षा के लिए नहीं।

Docker का rootless मोड एक वास्तविक विकल्प है, जहाँ डेमन स्वयं आपके unprivileged यूजर के रूप में चलता है। इसकी अपनी सीमाएं हैं: 1024 से नीचे के पोर्ट्स के लिए अतिरिक्त सेटअप की आवश्यकता होती है, नेटवर्किंग एक userspace shim के माध्यम से चलती है जिसमें मापने योग्य ओवरहेड होता है, और कुछ इमेजेज वास्तविक root के बिना ठीक से काम नहीं करती हैं। एक सिंगल-एडमिन VPS पर जहाँ एकमात्र लॉगिन के पास पहले से ही sudo है, यह ग्रुप बदलाव व्यवहार में कुछ भी नहीं बदलता है, और यहाँ दिए गए सभी गाइड इसी को मानकर चलते हैं। बस इसे कभी भी sudo से कम न समझें।

Compose file की संरचना

प्रत्येक stack को अपनी एक अलग directory दें। directory का नाम ही project का नाम बन जाता है, जो containers, networks और volumes के लिए prefix का काम करता है:

sudo mkdir -p /opt/miniflux && sudo chown $USER /opt/miniflux && cd /opt/miniflux

compose.yml बनाएँ (यह आधुनिक नाम है; docker-compose.yml अभी भी काम करता है)। पुराने version: key का उपयोग न करें, यह अब obsolete है और Compose इसे देखने पर warning देता है।

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 versions को pin करें, :latest और pull का उपयोग unattended upgrade जैसा है

postgres:16-alpine का उपयोग करें, न कि postgres:latest का। एक tag स्थिर नहीं होता: :latest हर बार pull करने पर उस image को फिर से resolve करता है जिसे maintainer ने सबसे हाल ही में push किया है। यदि आप इसे अपनी routine upgrade habit, docker compose pull && docker compose up -d के साथ मिलाते हैं, तो :latest का अर्थ है कि major-version के बदलाव आपके बिना चुने ही लागू हो जाएंगे। PostgreSQL के मामले में यह केवल एक संभावना नहीं है: 16 से 17 पर अचानक jump होने से container crash-loop में चला जाता है क्योंकि data directory incompatible हो जाती है। Postgres के major upgrades के लिए restart नहीं, बल्कि dump और restore की आवश्यकता होती है।

कम से कम major version को pin करें (postgres:16-alpine, 16.x patch releases के साथ काम करता है), और applications को सटीक release जैसे miniflux/miniflux:2.2.9 पर pin करें। project के releases page को देखें और file लिखते समय जो current हो, उसका उपयोग करें। इसके बाद upgrade करना आपके द्वारा जानबूझकर किया गया एक-लाइन का बदलाव होगा, जो git diff में दिखाई देगा।

127.0.0.1 पर publish करें, क्योंकि Docker ufw को bypass कर देता है

"127.0.0.1:8080:8080", host address, host port, container port। अधिकांश tutorials "8080:8080" लिखते हैं, जो 0.0.0.0:8080:8080 का shorthand है: यह हर interface पर listen करता है, जिसमें public interface भी शामिल है।

यही वह trap है, और यह लगभग हर किसी को एक बार फँसाता है। Docker एक port को DNAT rule लिखकर publish करता है जो filtering से पहले packet के destination को container के internal IP में बदल देता है। इसलिए packet FORWARD path लेता है और कभी भी INPUT तक नहीं पहुँचता, जहाँ आपके ufw rules मौजूद होते हैं। sudo ufw deny 8080 सफलता की रिपोर्ट देता है, ufw status दिखाता है कि port denied है, और service फिर भी पूरे internet को जवाब दे रही होती है। आपका firewall खराब नहीं है; इसे design के अनुसार ही bypass किया जा रहा है। Docker ufw को क्यों bypass करता है, और container traffic को वास्तव में कैसे filter करें इस mechanism को विस्तार से समझाता है और उन ports के लिए DOCKER-USER fix बताता है जिन्हें public रहना ही है।

वह आदत जो इस पूरी समस्या को खत्म कर देती है: published ports को 127.0.0.1 पर bind करें जब तक कि आपके पास ऐसा न करने का कोई ठोस कारण न हो, और जो कुछ भी दुनिया के सामने आना चाहिए उसके आगे एक reverse proxy लगाएँ। यही वह चीज़ है जिसे Traefik reverse proxy guide इस पेज के बाद अगले कदम के रूप में बनाती है। एक container जो ports 80 और 443 को संभालता है और TLS के साथ hostname के आधार पर बाकी सब कुछ route करता है। (पुराने Traefik v2 setup से आ रहे हैं? Traefik v2 to v3 migration guide renames और rule बदलावों को कवर करता है।)

Stack start करने के बाद bind को verify करें: sudo ss -tlnp | grep 8080 को 127.0.0.1:8080 दिखाना चाहिए, न कि 0.0.0.0:8080 या *:8080

Named volumes बनाम bind mounts

db-data:/var/lib/postgresql/data एक named volume है: Docker /var/lib/docker/volumes/ के अंतर्गत एक directory बनाता और manage करता है और उसे container में mount करता है। इसका विकल्प bind mount है, ./data:/var/lib/postgresql/data, जो host पर आपके द्वारा चुनी गई path को map करता है।

वह विभाजन जो व्यवहार में काम आता है: named volumes केवल उन containers के data के लिए हैं जिन्हें containers ही touch करते हैं, विशेषकर databases, क्योंकि Docker volume को उस ownership के साथ initialize करता है जिसकी image को अपेक्षा होती है और file permissions अपने आप सही काम करते हैं। Bind mounts उन files के लिए हैं जिन्हें आप host से touch करते हैं, जैसे text editor से edit की जाने वाली config files, media library जिसे आप rsync करते हैं, या कोई भी ऐसी चीज़ जिसकी path आप स्पष्ट रखना चाहते हैं। Bind-mount की सामान्य विफलता ownership है: container UID 999 के रूप में चलता है, आपकी host directory का owner UID 1000 है, और app startup पर logs में permission denied के साथ crash हो जाती है। Named volumes इस तरह के bug को काफी हद तक खत्म कर देते हैं, बस इसकी कीमत यह है कि data Docker-managed path पर रहता है, जिसे नीचे कवर किया गया है।

environment और .env, secrets को git से दूर रखें

${POSTGRES_PASSWORD} को आपके shell से नहीं पढ़ा जाता; Compose इसे compose.yml के बगल में स्थित .env नामक file से 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 के साथ वास्तविक values generate करें। जानबूझकर Hex का उपयोग करें, न कि base64 का: यह password DATABASE_URL connection string के अंदर जाता है, और base64 द्वारा उत्पन्न /, +, और = characters URL parsing को तोड़ देते हैं। यह एक ऐसी विफलता है जो syntax error के बजाय authentication error के रूप में सामने आती है और एक पूरी शाम बर्बाद कर सकती है। .gitignore लाइन पहले commit से पहले आनी चाहिए: compose file को publish और version करना सुरक्षित है, .env file कभी भी सुरक्षित नहीं होती, और जो secret git history में चला गया, उसे rotate करना ही पड़ता है। यदि आप किसी missing variable के साथ stack start करते हैं, तो Compose जोर से चेतावनी देता है और empty string के साथ जारी रहता है, जिसका Postgres password के लिए मतलब है एक broken deployment:

WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string.

docker compose config पूरी तरह से interpolated file को print करता है, यह जाँचने का सबसे तेज़ तरीका है कि containers को वास्तव में क्या प्राप्त होगा; याद रखें कि इसके output में आपके secrets शामिल होते हैं।

depends_on किसी चीज़ का इंतज़ार नहीं करता, जब तक आप healthcheck न जोड़ें

एक साधारण depends_on: [db] केवल start order को नियंत्रित करता है: Compose पहले Postgres को launch करता है और उसके कुछ पल बाद app को, जबकि Postgres को connections स्वीकार करने में अभी भी कुछ सेकंड बाकी होते हैं। App database को hit करती है, विफल हो जाती है, और crash हो जाती है या retry करती है (यह इस पर निर्भर करता है कि उसे कितनी अच्छी तरह लिखा गया है)।

विश्वसनीय version वह है जिसका उपयोग ऊपर दी गई file में किया गया है: db service एक healthcheck को define करती है (Postgres ठीक इसी के लिए pg_isready प्रदान करता है), और app condition: service_healthy के साथ depends_on घोषित करती है। Compose database को start करता है, हर 10 सेकंड में check को poll करता है, और check पास होने पर ही Miniflux को start करता है। यदि database कभी healthy नहीं होता (गलत password, corrupt volume), तो app कभी start नहीं होती और Compose आपको बताता है कि कौन सी dependency विफल रही:

dependency failed to start: container miniflux-db-1 is unhealthy

वह संदेश आपको docker compose logs db की ओर ले जाता है, जहाँ वास्तविक error मौजूद होती है।

restart: unless-stopped

दोनों services पर restart: unless-stopped का मतलब है कि containers crash होने के बाद और VPS reboot के बाद वापस आ जाते हैं, लेकिन यदि आपने जानबूझकर docker compose stop चलाया है तो वे down ही रहते हैं। इसका विकल्प always है जो manual stop के बाद भी containers को पुनर्जीवित कर देता है, जो शायद ही कभी आपका उद्देश्य होता है। बिना restart policy के, सुबह 4 बजे kernel-update reboot आपके services को चुपचाप बंद कर देगा जब तक कि आप उस पर ध्यान न दें।

दैनिक क्रियाएं

दैनिक कार्यों के लिए केवल पांच commands हैं, जिन्हें project directory से चलाया जाता है।

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 network

up -d को बार-बार चलाना सुरक्षित है। यह file की तुलना वर्तमान स्थिति से करता है और केवल उन्हीं services को प्रभावित करता है जिनकी config या image बदली है। upgrade pair उन tags को fetch करता है जिन पर आपने पिन किया है: postgres:16-alpine के तहत patch releases, और exact pin के लिए तब तक कुछ नहीं होता जब तक आप उसे edit न करें, जो कि इसका मुख्य उद्देश्य है। upgrades के बाद पुरानी images जमा हो जाती हैं; डिस्क स्पेस खाली करने के लिए docker image prune -f का उपयोग करें।

अब विनाशकारी command की बात, जिसे ध्यान से समझें: docker compose down चलाना सुरक्षित है, containers और network को कभी भी हटाया जा सकता है, और आपका डेटा volume में सुरक्षित रहता है। docker compose down -v named volumes को भी हटा देता है। इसका मतलब है कि आपका database तुरंत नष्ट हो जाएगा, बिना किसी पुष्टि या undo के। -v flag का अस्तित्व प्रयोगों को मिटाने के लिए है; वास्तविक डेटा वाले stack पर, इसे वैसे ही समझें जैसे आप rm -rf को समझते हैं। /var/lib/docker/volumes/ में कोई trash can नहीं होता है।

चल रहे container के अंदर एक बार shell access पाने के लिए: docker compose exec db psql -U miniflux आपको database में ले जाता है, और docker compose exec miniflux sh आपको app में shell प्रदान करता है।

आपका डेटा वास्तव में कहाँ रहता है

Named volumes को project prefix मिलता है, इसलिए db-data जो miniflux नामक directory में है, वह miniflux_db-data बन जाता है:

docker volume ls
docker volume inspect miniflux_db-data

inspect के output में वह line शामिल होती है जो महत्वपूर्ण है:

"Mountpoint": "/var/lib/docker/volumes/miniflux_db-data/_data"

वह directory database है, जो host filesystem पर root-owned है, और यह down, upgrades, और container rebuilds के बाद भी सुरक्षित रहती है। यही वह डेटा है जिसे आपके backups में अनिवार्य रूप से शामिल किया जाना चाहिए।

Named volume का बैकअप लेना

इसका मानक तरीका एक अस्थायी container का उपयोग करना है, जो volume को read-only मोड में host directory के साथ mount करता है और 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 .

इसमें किसी इंस्टॉलेशन की आवश्यकता नहीं होती, कुछ भी बैकग्राउंड में नहीं चलता, और restore की प्रक्रिया इसका बिल्कुल उल्टा है, जहाँ tar xzf का उपयोग करके एक नए खाली volume में mounts को उलट दिया जाता है।

डेटाबेस के लिए एक सावधानी: एक चलते हुए Postgres डेटा डायरेक्टरी का tar लेने से वह स्थिति कैप्चर हो सकती है जो लिखते समय बीच में हो, जिससे डेटाबेस बाद में सही ढंग से start नहीं होगा। या तो tar के दौरान कुछ सेकंड के लिए docker compose stop का उपयोग करें, या बेहतर होगा कि एक logical dump लें, जो अपनी संरचना के कारण हमेशा consistent रहता है:

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

-T उस pseudo-terminal को अक्षम कर देता है जिसे Compose डिफ़ॉल्ट रूप से allocate करता है, क्योंकि dump आउटपुट को TTY के माध्यम से पाइप करने से वह corrupt हो सकता है। इनमें से किसी एक कमांड को cron में डालें और परिणाम को VPS से बाहर कॉपी करें; जिस डिस्क पर डेटा है उसी पर बैकअप रखना केवल एक कॉपी है, वास्तविक बैकअप नहीं। Nextcloud guide ठीक इन्हीं दो पैटर्न्स के आधार पर एक पूर्ण निर्धारित रूटीन तैयार करता है।

विफलता के प्रकार और उनसे संबंधित संदेश

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock, आप अभी तक docker group में शामिल नहीं हैं, या आप शामिल तो हैं लेकिन आपका वर्तमान session उससे पुराना है। id आपके प्रभावी groups को दिखाता है; newgrp docker वर्तमान shell को ठीक कर देता है, जबकि logout करके फिर से login करने से सभी sessions ठीक हो जाते हैं।

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 पर इसका सबसे आम कारण disk का भर जाना है, इसलिए पहले df -h /var/lib/docker चलाएं।

Bind for 127.0.0.1:8080 failed: port is already allocated, किसी अन्य container ने पहले ही उस host port को publish कर दिया है। docker ps दिखाता है कि वह कौन सा है; आमतौर पर इसका कारण कुछ docker run सप्ताह पहले का कोई पुराना container होता है। यदि docker ps खाली है, तो कोई non-Docker process उस port का उपयोग कर रही है: sudo ss -tlnp | grep 8080 उसका नाम बता देगा।

yaml: line 14: did not find expected key, यह निर्दिष्ट line या उसके ठीक ऊपर एक indentation त्रुटि है। Compose files YAML होती हैं: इसमें दो-space का indentation अनिवार्य है, केवल spaces का उपयोग करें, और tab character का कहीं भी होना घातक है। docker compose config बिना कुछ शुरू किए file को validate करता है, और हर बदलाव के बाद इसे चलाना एक अच्छी आदत है।

ufw surprise कोई त्रुटि नहीं दिखाता है, जो इसे खतरनाक बनाता है: deployment सफल हो जाता है, ufw status सही दिखता है, और बाहर से port scan करने पर भी आपका database मिल जाता है। ऊपर दिए गए ports section को फिर से पढ़ें, हर ports: entry में missing 127.0.0.1: prefix की जाँच करें, और किसी दूसरे machine से curl http://your-vps-ip:8080 के साथ पुष्टि करें; connection refused ही वह उत्तर है जो आप चाहते हैं।

यहाँ से, Traefik guide इस single stack को एक HTTPS entry point के पीछे कई apps में बदल देता है, और what's worth self-hosting in 2026 वह सूची है जिसे आप चला सकते हैं। जब ऐसे कई stacks चल रहे हों और प्रत्येक का अपना login form हो, तो a self-hosted SSO server like Authentik उन्हें उसी proxy के पीछे एक ही account में समेट देता है।

VPS पर Minecraft server जैसा game server अभ्यास के लिए एक अच्छा पहला Compose project है। यदि आप ऐसी चीज़ से सीखना चाहते हैं जिसे रोज़ खोलते हैं, तो openGym, self-hosted workout tracker एक छोटा stack है, जो image tag के बजाय git tag पर pinned है। पहला passkey register करने से पहले इसके सामने TLS होना चाहिए। Photos आम तौर पर पहली ऐसी चीज़ होती हैं जिसे लोग किसी और के cloud से वापस लाना चाहते हैं। PhotoPrism और Immich की तुलना करने से यह तय करने में मदद मिलती है कि न्यूनतम कितनी RAM चाहिए और किस backup routine के लिए आप सहमत हो रहे हैं, इससे पहले कि आप इनमें से किसी के लिए volume निर्धारित करें। जब दो services पर्याप्त नहीं लगतीं, तो AFFiNE को Notion-style workspace के रूप में स्थापित करना चार containers में उन्हीं patterns को लागू करता है। यह जाँचने का अच्छा तरीका भी है कि ऊपर बताए गए pinned tags, healthchecks और named volumes अब आपकी आदत बन चुके हैं या नहीं।

FAQ

मुझे "permission denied while trying to connect to the Docker daemon socket" क्यों मिलता है?

आपका user docker समूह में नहीं है, या उसे वर्तमान session शुरू होने के बाद जोड़ा गया है; सदस्यता केवल login के समय लागू होती है। sudo usermod -aG docker $USER चलाएं, फिर newgrp docker करें या log out करके वापस log in करें, और id के साथ पुष्टि करें। यह समूह host पर root के बराबर access देता है, इसलिए केवल उन्हीं users को जोड़ें जिन्हें आप sudo अधिकार देना चाहेंगे।

क्या docker compose down मेरा डेटा डिलीट कर देता है?

साधारण docker compose down ऐसा नहीं करता है, यह केवल containers और project network को हटाता है; named volumes सुरक्षित रहते हैं और अगला up -d उन्हें फिर से जोड़ देता है। docker compose down -v विनाशकारी रूप है: यह named volumes को डिलीट कर देता है, जिसका अर्थ है कि आपका database बिना किसी पुष्टि या undo के हट जाएगा। यदि आपके पास verified backup न हो, तो कभी भी वास्तविक डेटा वाले stack पर -v न चलाएं।

docker-compose और docker compose में क्या अंतर है?

docker-compose (हाइफ़न) Compose v1 है, जो एक standalone Python binary है। यह 2023 में end of life हो चुका है और इसे नए servers पर install नहीं किया जाना चाहिए। docker compose (space) Compose v2 है, जो Docker CLI के लिए एक Go plugin है, जिसे Docker के apt repository से docker-compose-plugin के रूप में install किया जाता है। Commands और YAML लगभग पूरी तरह से compatible हैं, इसलिए जब कोई पुराना tutorial docker-compose up कहे, तो docker compose up टाइप करें।

ufw द्वारा port block होने के बावजूद मैं इंटरनेट से अपने Docker container तक क्यों पहुँच सकता हूँ?

क्योंकि Docker, iptables की PREROUTING chain में DNAT rules के साथ ports को publish करता है, और rewrite किए गए packets Docker की अपनी chains के माध्यम से FORWARD path पर चलते हैं। वे कभी भी उस INPUT chain तक नहीं पहुँचते जहाँ ufw के rules लागू होते हैं। इसलिए ufw deny 8080 का किसी published container port पर कोई असर नहीं पड़ता है। इसे स्रोत पर ठीक करें: 127.0.0.1: पर publish करें और services को reverse proxy के माध्यम से expose करें।

क्या मुझे named volume का उपयोग करना चाहिए या bind mount का?

केवल उस डेटा के लिए named volumes का उपयोग करें जिसे container ही access करता है, विशेषकर databases के लिए, क्योंकि Docker image द्वारा अपेक्षित ownership को set कर देता है और permissions अपने आप काम करती हैं। Bind mounts का उपयोग उन files के लिए करें जिन्हें आप host से भी manage करते हैं: जैसे कि configs जिन्हें आप edit करते हैं, media जिसे आप upload करते हैं, या कोई भी ऐसी चीज़ जिसका path आप स्पष्ट रखना चाहते हैं। यदि कोई container bind mount पर permission denied के साथ start होने में विफल रहता है, तो host-vs-container UID mismatch सबसे पहली चीज़ है जिसे आपको जाँचने की आवश्यकता है।