Ubuntu 24.04 లో Docker Compose ఎలా సెటప్ చేయాలి?
Ubuntu 24.04 లో Docker Engine మరియు Compose v2 ఇన్స్టాల్ చేయడం ఎలాగో తెలుసుకోండి. ufw ఫైర్వాల్ సమస్యలను దాటవేస్తూ, రెండు సర్వీసుల compose.yml ఫైల్ను సురక్షితంగా రాయడం నేర్చుకోండి.
మీరు ఏమి నిర్మిస్తున్నారు
ఈ సైట్లోని దాదాపు అన్నింటికీ Docker Compose పునాదిగా ఉంటుంది. Nextcloud, Vaultwarden, n8n, Immich, Rocket.Chat, వంటి ప్రతి గైడ్ "ఈ compose ఫైల్ను రాయండి" అని మొదలవుతుంది, ఆ ఫైల్ అసలు అర్థం ఏమిటో వివరించే పేజీ ఇదే. మీరు Ubuntu 24.04 లో Docker యొక్క అధికారిక apt రిపోజిటరీ నుండి Docker Engine మరియు Compose v2 ప్లగిన్ను ఇన్స్టాల్ చేస్తారు. ఆ తర్వాత, ఒక చిన్న RSS రీడర్ అయిన Miniflux మరియు PostgreSQL లతో కూడిన రెండు సర్వీసుల స్టాక్ను సిద్ధం చేస్తారు. ఎందుకంటే ఈ జంట పెద్ద అప్లికేషన్లు ఉపయోగించే ప్రతి పద్ధతిని కలిగి ఉంటుంది: పిన్ చేసిన ఇమేజ్లు, హెల్త్చెక్ ఉన్న డేటాబేస్, నేమ్డ్ వాల్యూమ్, .env ఫైల్లో రహస్యాలు (secrets), మరియు localhost కు మాత్రమే పరిమితం చేసిన పోర్ట్.
ఈ ఇన్స్టాలేషన్ ఐదు నిమిషాల్లో పూర్తవుతుంది. ఈ గైడ్లోని మిగిలిన భాగం తర్వాత ఇబ్బంది కలిగించే అంశాలను వివరిస్తుంది: docker గ్రూప్ అనేది మరొక పేరుతో ఉన్న root అని, పబ్లిష్ చేసిన పోర్ట్లు మీ ufw నియమాలను దాటి నేరుగా ఎలా వెళ్తాయో, మరియు docker compose down లోని ఒక ఫ్లాగ్ ఎటువంటి నిర్ధారణ అడగకుండానే మీ డేటాబేస్ను ఎలా తొలగిస్తుందో ఇందులో తెలుసుకోవచ్చు.
ముందస్తు అవసరాలు: కొత్తగా ఉన్న Ubuntu 24.04 KVM VPS, sudo అనుమతులు ఉన్న వినియోగదారు, మరియు ఒక గిగాబైట్ లేదా అంతకంటే ఎక్కువ RAM. ఇప్పటికే Docker ఇన్స్టాల్ అయి ఉన్నా పర్వాలేదు, మొదటి విభాగంలో దేనిని తొలగించాలో వివరించబడింది.
Ubuntu రిపోజిటరీ నుండి కాకుండా Docker రిపోజిటరీ నుండి ఇన్స్టాల్ చేయండి
మొదటి కమాండ్ అమలు చేయడానికి ముందు రెండు తప్పుడు పద్ధతులను నివారించాలి. Ubuntu అందించే docker.io ప్యాకేజీ పనిచేస్తుంది, కానీ ఇది Docker యొక్క తాజా releases కంటే వెనుకబడి ఉంటుంది మరియు ఇతర అప్లికేషన్లు ఆశించే plugin లేఅవుట్ను కలిగి ఉండదు. అలాగే, హైఫన్ ఉన్న standalone docker-compose బైనరీ అనేది Compose v1: ఇది Python ఆధారితమైనది, 2023 నుండి దీని మద్దతు నిలిపివేయబడింది, పాత ట్యుటోరియల్స్ పనిచేయకపోవడానికి ఇదే కారణం. ప్రస్తుత Compose అనేది docker compose (స్పేస్తో), ఇది ఒక CLI plugin, దీనిని Docker engine ఉన్న రిపోజిటరీ నుండే ఇన్స్టాల్ చేయాలి.
ఒకవేళ వీటిలో ఏవైనా ఇప్పటికే సర్వర్లో ఉంటే, వాటిని ముందుగా తొలగించండి. Ubuntu అందించే plugin ప్యాకేజీ అయిన docker-compose-v2 ను కూడా తొలగించండి, తద్వారా అన్నీ ఒకే రిపోజిటరీ నుండి వస్తాయి:
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మూడు పొరలను (layers) ధృవీకరించండి:
docker --version
docker compose version
sudo docker run --rm hello-worldమొదటి రెండు కమాండ్లు version strings ను ప్రింట్ చేస్తాయి, Docker Compose version v2.x.x అనేది మీరు పాత v1 బైనరీని కాకుండా plugin ను కలిగి ఉన్నారని నిర్ధారిస్తుంది. hello-world కమాండ్ రన్ చేసినప్పుడు చివరగా Hello from Docker! అని రావాలి. ఈ ప్యాకేజీ సర్వర్ను బూట్ అయినప్పుడు ఆటోమేటిక్గా ప్రారంభమయ్యేలా చేస్తుంది; systemctl is-enabled docker కమాండ్ enabled అని ప్రింట్ చేస్తుంది.
docker గ్రూప్ అంటే root, కాబట్టి జాగ్రత్తగా నిర్ణయం తీసుకోండి
ప్రస్తుతం ప్రతి docker కమాండ్కు sudo అవసరం, ఎందుకంటే /var/run/docker.sock వద్ద ఉన్న డెమోన్ సాకెట్ (daemon's socket) యాజమాన్యం 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గ్రూప్ సభ్యత్వం లాగిన్ అయినప్పుడు వర్తిస్తుంది, కాబట్టి మీరు ప్రస్తుతం వాడుతున్న షెల్ (shell) లో ఈ ఎర్రర్ అలాగే కనిపిస్తుంది. ఈ సెషన్ కోసం newgrp docker రన్ చేయండి, లేదా లాగ్ అవుట్ చేసి మళ్ళీ లాగిన్ అవ్వండి; అప్పుడు id కమాండ్ మీ గ్రూపుల జాబితాలో docker ను చూపించాలి.
ఇక అసలు విషయం, స్పష్టంగా చెప్పాలంటే: docker గ్రూపులో సభ్యత్వం ఉండటం అంటే హోస్ట్ మెషీన్ మీద root పర్మిషన్లు ఉండటమే. ఇది "root లాంటిది" లేదా "కొంచెం ఎక్కువ పవర్" కాదు, ఇది పూర్తిగా root. ఈ గ్రూపులో ఉన్న ఎవరైనా docker run --rm -it -v /:/host alpine chroot /host కమాండ్ను రన్ చేసి, పాస్వర్డ్ అడగకుండానే మొత్తం ఫైల్సిస్టమ్ను తమ ఆధీనంలోకి తీసుకోవచ్చు. ఈ గ్రూప్ కేవలం సౌలభ్యం కోసం మాత్రమే ఉంది, భద్రత (containment) కోసం కాదు.
Docker యొక్క rootless మోడ్ దీనికి సరైన ప్రత్యామ్నాయం, ఇందులో డెమోన్ మీ unprivileged యూజర్ ఖాతాతోనే రన్ అవుతుంది. దీనివల్ల కొన్ని పరిమితులు ఉన్నాయి: 1024 కంటే తక్కువ ఉన్న పోర్ట్లకు అదనపు సెటప్ అవసరం, నెట్వర్కింగ్ ఒక userspace shim ద్వారా జరుగుతుంది కాబట్టి కొంత పనితీరు తగ్గుతుంది, మరియు కొన్ని ఇమేజ్లు నిజమైన root లేకుండా సరిగ్గా పనిచేయవు. ఒకే అడ్మిన్ ఉన్న 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:పైన ఉన్న ప్రతి లైన్ ఒక నిర్ణయం. వాటిని ఒక్కొక్కటిగా అమలు చేయండి.
ఇమేజ్ వెర్షన్లను పిన్ చేయండి, :latest మరియు pull అనేది unattended upgrade తో సమానం
postgres:16-alpine వాడండి, postgres:latest వద్దు. ఒక tag అనేది స్థిరమైనది కాదు: మీరు pull చేసిన ప్రతిసారీ :latest అనేది మెయింటైనర్ చివరగా పంపిన ఇమేజ్ కు మారుతుంది. దీన్ని మీరు నేర్చుకోబోయే సాధారణ అప్గ్రేడ్ అలవాటు docker compose pull && docker compose up -d తో కలిపితే, :latest వల్ల మీరు కోరుకోకపోయినా అప్స్ట్రీమ్ వారు కొత్త వెర్షన్ విడుదల చేసినప్పుడల్లా మేజర్ వెర్షన్ అప్గ్రేడ్లు జరిగిపోతాయి. PostgreSQL విషయంలో ఇది ఊహ మాత్రమే కాదు: 16 నుంచి 17కి అకస్మాత్తుగా మారితే, డేటా డైరెక్టరీ సరిపోక కంటైనర్ crash-loop లో పడుతుంది. ఎందుకంటే Postgres మేజర్ అప్గ్రేడ్లకు కేవలం restart సరిపోదు, dump మరియు restore అవసరం.
కనీసం మేజర్ వెర్షన్ను పిన్ చేయండి (postgres:16-alpine అనేది 16.x ప్యాచ్ రిలీజ్లను అనుసరిస్తుంది), మరియు అప్లికేషన్లను miniflux/miniflux:2.2.9 వంటి ఖచ్చితమైన రిలీజ్లకు పిన్ చేయండి. ప్రాజెక్ట్ యొక్క రిలీజ్ పేజీని తనిఖీ చేసి, ఫైల్ రాసేటప్పుడు ఏది కరెంట్ వెర్షన్ అయితే దాన్ని వాడండి. అప్పుడు అప్గ్రేడ్ అనేది మీరు ఉద్దేశపూర్వకంగా చేసే ఒక లైన్ మార్పుగా మారుతుంది, ఇది git diff లో కనిపిస్తుంది.
127.0.0.1 కు పబ్లిష్ చేయండి, ఎందుకంటే Docker ufw ను దాటవేస్తుంది
"127.0.0.1:8080:8080", హోస్ట్ అడ్రస్, హోస్ట్ పోర్ట్, కంటైనర్ పోర్ట్. చాలా ట్యుటోరియల్స్ "8080:8080" అని రాస్తాయి, ఇది 0.0.0.0:8080:8080 కి సంక్షిప్త రూపం: అంటే పబ్లిక్ ఇంటర్ఫేస్తో సహా ప్రతి ఇంటర్ఫేస్పై వింటుంది.
ఇక్కడే అసలైన చిక్కు ఉంది, ఇది దాదాపు అందరికీ ఒక్కసారైనా ఎదురవుతుంది. Docker ఒక పోర్ట్ను పబ్లిష్ చేసేటప్పుడు, ఫిల్టరింగ్కు ముందే ప్యాకెట్ గమ్యాన్ని కంటైనర్ యొక్క అంతర్గత IPకి మార్చే DNAT రూల్ను రాస్తుంది. కాబట్టి ప్యాకెట్ FORWARD మార్గంలో వెళ్తుంది మరియు మీ ufw రూల్స్ ఉన్న INPUT ని ఎప్పటికీ తాకదు. sudo ufw deny 8080 సక్సెస్ అని చూపిస్తుంది, ufw status పోర్ట్ డినై అయినట్లు చూపిస్తుంది, కానీ ఆ సేవ మొత్తం ఇంటర్నెట్కు సమాధానం ఇస్తూనే ఉంటుంది. మీ ఫైర్వాల్ పాడవ్వలేదు; అది డిజైన్ ప్రకారమే దాటవేయబడుతోంది. Docker ఎందుకు ufw ను దాటవేస్తుంది మరియు కంటైనర్ ట్రాఫిక్ను ఎలా ఫిల్టర్ చేయాలి అనే గైడ్ ఈ విధానాన్ని మరియు పబ్లిక్గా ఉండాల్సిన పోర్ట్ల కోసం DOCKER-USER పరిష్కారాన్ని వివరిస్తుంది.
ఈ సమస్యను పూర్తిగా తొలగించే అలవాటు: పబ్లిష్ చేసిన పోర్ట్లను 127.0.0.1 కి బైండ్ చేయండి (ప్రత్యేక కారణం ఉంటే తప్ప), మరియు ప్రపంచానికి కనిపించాల్సిన వాటి కోసం ముందు ఒక reverse proxy ని ఉంచండి. ఈ పేజీ తర్వాత వచ్చే Traefik reverse proxy గైడ్ సరిగ్గా ఇదే చేస్తుంది. ఇది 80 మరియు 443 పోర్ట్లను కలిగి ఉండి, TLS తో హోస్ట్నేమ్ ఆధారంగా మిగిలిన వాటికి ట్రాఫిక్ను పంపుతుంది. (పాత Traefik v2 సెటప్ నుంచి వస్తున్నారా? Traefik v2 to v3 మైగ్రేషన్ గైడ్ లో మార్పులు మరియు రూల్స్ గురించి చూడవచ్చు.)
స్టాక్ ప్రారంభించిన తర్వాత బైండింగ్ను సరిచూసుకోండి: sudo ss -tlnp | grep 8080 అనేది 127.0.0.1:8080 ని చూపాలి, 0.0.0.0:8080 లేదా *:8080 ని కాదు.
Named volumes vs bind mounts
db-data:/var/lib/postgresql/data అనేది ఒక named volume: Docker ఒక డైరెక్టరీని /var/lib/docker/volumes/ కింద సృష్టించి, దాన్ని కంటైనర్లోకి మౌంట్ చేస్తుంది. దీనికి ప్రత్యామ్నాయం bind mount, ./data:/var/lib/postgresql/data, ఇది హోస్ట్పై మీరు ఎంచుకున్న పాత్ను మ్యాప్ చేస్తుంది.
ఆచరణలో పనికొచ్చే విభజన ఇది: కంటైనర్లు మాత్రమే తాకే డేటా కోసం named volumes వాడండి, ముఖ్యంగా డేటాబేస్ల కోసం. ఎందుకంటే ఇమేజ్ ఆశించే ownership తో Docker వాల్యూమ్ను సిద్ధం చేస్తుంది, కాబట్టి ఫైల్ పర్మిషన్లు సరిగ్గా పనిచేస్తాయి. మీరు హోస్ట్ నుంచి తాకే ఫైల్స్ కోసం bind mounts వాడండి, అంటే మీరు ఎడిట్ చేసే కాన్ఫిగరేషన్ ఫైల్స్, మీరు rsync చేసే మీడియా లైబ్రరీ, లేదా పాత్ స్పష్టంగా ఉండాలనుకునే ఏదైనా సరే. Bind-mount లో వచ్చే సాధారణ సమస్య ownership: కంటైనర్ UID 999 తో రన్ అవుతుంది, మీ హోస్ట్ డైరెక్టరీ UID 1000 తో ఉంటుంది, అప్పుడు యాప్ స్టార్టప్ లో permission denied ఎర్రర్తో ఆగిపోతుంది. Named volumes ఈ తరహా బగ్లను దాదాపు తొలగిస్తాయి, అయితే డేటా Docker-managed పాత్లో ఉంటుంది.
environment మరియు .env, secrets ను git లో ఉంచకండి
${POSTGRES_PASSWORD} మీ షెల్ నుంచి చదవబడదు; Compose దీన్ని compose.yml పక్కన ఉన్న .env అనే ఫైల్ నుంచి తీసుకుంటుంది. దీన్ని సృష్టించండి:
cat > .env <<'EOF'
POSTGRES_PASSWORD=change-me-to-something-long
ADMIN_PASSWORD=change-me-too
EOF
chmod 600 .env
echo ".env" >> .gitignoreopenssl rand -hex 24 తో నిజమైన విలువలను జనరేట్ చేయండి. ఉద్దేశపూర్వకంగానే Hex వాడండి, base64 వద్దు: ఈ పాస్వర్డ్ DATABASE_URL కనెక్షన్ స్ట్రింగ్లోకి వెళ్తుంది, మరియు base64 ఉత్పత్తి చేసే /, +, మరియు = అక్షరాలు URL పార్సింగ్ను పాడు చేస్తాయి. ఇది సింటాక్స్ ఎర్రర్ లా కాకుండా అథెంటికేషన్ ఎర్రర్ లా కనిపిస్తుంది, దీనివల్ల సమయం వృథా అవుతుంది. మొదటి commit కి ముందే .gitignore లైన్ జోడించండి: compose ఫైల్ పబ్లిష్ చేయడానికి సురక్షితం, కానీ .env ఫైల్ ఎప్పటికీ కాదు. ఒకవేళ git హిస్టరీలోకి సీక్రెట్ వెళ్తే, దాన్ని మార్చాల్సిందే. ఒకవేళ వేరియబుల్ లేకుండా స్టాక్ స్టార్ట్ చేస్తే, Compose గట్టిగా హెచ్చరించి ఖాళీ స్ట్రింగ్తో కొనసాగుతుంది, Postgres పాస్వర్డ్ విషయంలో ఇది డిప్లాయ్మెంట్ విఫలమవ్వడానికి దారితీస్తుంది:
WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string.docker compose config అనేది పూర్తిగా ఇంటర్పోలేట్ చేయబడిన ఫైల్ను ప్రింట్ చేస్తుంది, కంటైనర్లు ఏమి అందుకుంటాయో చూడటానికి ఇది వేగవంతమైన మార్గం; దీని అవుట్పుట్లో మీ సీక్రెట్స్ ఉంటాయని గుర్తుంచుకోండి.
depends_on దేనికోసం ఆగదు, healthcheck జోడిస్తే తప్ప
సాధారణ depends_on: [db] కేవలం ప్రారంభ క్రమాన్ని మాత్రమే నియంత్రిస్తుంది: Compose మొదట Postgres ను, ఆ తర్వాత యాప్ను లాంచ్ చేస్తుంది, కానీ Postgres కనెక్షన్లను స్వీకరించడానికి ఇంకా సెకన్ల సమయం పడుతుంది. యాప్ డేటాబేస్ను సంప్రదించి, విఫలమై, క్రాష్ అవుతుంది లేదా మళ్ళీ ప్రయత్నిస్తుంది.
నమ్మదగిన వెర్షన్ పైన ఉన్న ఫైల్లో ఉంది: db సర్వీస్ ఒక healthcheck ని నిర్వచిస్తుంది (Postgres దీని కోసం pg_isready ని అందిస్తుంది), మరియు యాప్ condition: service_healthy తో depends_on ని డిక్లేర్ చేస్తుంది. Compose డేటాబేస్ను స్టార్ట్ చేసి, ప్రతి 10 సెకన్లకు చెక్ చేస్తుంది, ఆ చెక్ పాస్ అయిన తర్వాతే Miniflux ను స్టార్ట్ చేస్తుంది. ఒకవేళ డేటాబేస్ ఎప్పటికీ హెల్తీగా మారకపోతే (తప్పు పాస్వర్డ్, పాడైన వాల్యూమ్), యాప్ స్టార్ట్ అవ్వదు మరియు ఏ డిపెండెన్సీ విఫలమైందో Compose మీకు చెబుతుంది:
dependency failed to start: container miniflux-db-1 is unhealthyఆ మెసేజ్ మిమ్మల్ని docker compose logs db వైపు చూపిస్తుంది, అక్కడే అసలైన ఎర్రర్ ఉంటుంది.
restart: unless-stopped
రెండింటిలో restart: unless-stopped ఉండటం అంటే, క్రాష్ అయిన తర్వాత లేదా VPS రీబూట్ అయిన తర్వాత కంటైనర్లు తిరిగి వస్తాయి, కానీ మీరు ఉద్దేశపూర్వకంగా docker compose stop రన్ చేస్తే అవి ఆగిపోతాయి. ప్రత్యామ్నాయమైన always మాన్యువల్గా ఆపిన తర్వాత కూడా కంటైనర్లను తిరిగి తెస్తుంది, ఇది సాధారణంగా మనం కోరుకునేది కాదు. రీస్టార్ట్ పాలసీ లేకపోతే, ఉదయం 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 ను పదేపదే రన్ చేయడం సురక్షితం, ఇది ఫైల్ను వాస్తవ స్థితితో పోల్చి (diff), కాన్ఫిగరేషన్ లేదా ఇమేజ్ మారిన సర్వీసులను మాత్రమే ప్రభావితం చేస్తుంది. అప్గ్రేడ్ జంట (pair) మీరు పిన్ చేసిన ట్యాగ్లు ప్రస్తుతం దేనిని సూచిస్తున్నాయో వాటిని పొందుతుంది: postgres:16-alpine కింద ప్యాచ్ రిలీజ్లు వస్తాయి, మీరు ఎడిట్ చేసే వరకు ఖచ్చితమైన పిన్ (exact pin) కోసం ఏమీ మారదు, అదే దీని ముఖ్య ఉద్దేశ్యం. అప్గ్రేడ్ల తర్వాత పాత ఇమేజ్లు పేరుకుపోతాయి; docker image prune -f తో డిస్క్ స్థలాన్ని తిరిగి పొందండి.
ఇక ప్రమాదకరమైన కమాండ్ గురించి, గట్టిగా చెప్పాలంటే: docker compose down సురక్షితమైనది, కంటైనర్లు మరియు నెట్వర్క్ తాత్కాలికమైనవి, మీ డేటా వాల్యూమ్లో ఉంటుంది. docker compose down -v పేరున్న వాల్యూమ్లను కూడా తొలగిస్తుంది. అంటే మీ డేటాబేస్ తక్షణమే పోతుంది, ఎటువంటి నిర్ధారణ అడగదు మరియు దీనిని వెనక్కి తీసుకోవడం (undo) సాధ్యం కాదు. -v ఫ్లాగ్ ప్రయోగాల కోసం మాత్రమే; నిజమైన డేటా ఉన్న స్టాక్పై, దీనిని మీరు rm -rf ని ఎలా చూస్తారో అలాగే చూడండి. /var/lib/docker/volumes/ కింద ఎటువంటి ట్రాష్ క్యాన్ (trash can) ఉండదు.
రన్ అవుతున్న కంటైనర్ లోపల ఒకసారి షెల్ పొందడానికి: docker compose exec db psql -U miniflux మిమ్మల్ని డేటాబేస్లోకి తీసుకెళ్తుంది, మరియు docker compose exec miniflux sh మీకు యాప్లో షెల్ ఇస్తుంది.
మీ డేటా వాస్తవానికి ఎక్కడ నిల్వ చేయబడుతుంది
Named volumes కు ప్రాజెక్ట్ ప్రిఫిక్స్ ఉంటుంది, కాబట్టి 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-owned గా ఉంటుంది మరియు ఇది down, అప్గ్రేడ్లు, మరియు కంటైనర్ రీబిల్డ్ల తర్వాత కూడా అలాగే ఉంటుంది. మీ బ్యాకప్లు ఖచ్చితంగా దేనిని కాపీ చేయాలో అదే ఈ డైరెక్టరీ.
Named volume ను బ్యాకప్ చేయడం
దీనికి ప్రామాణిక పద్ధతి ఏమిటంటే, ఒక తాత్కాలిక (throwaway) కంటైనర్ను ఉపయోగించి, ఆ వాల్యూమ్ను read-only మోడ్లో హోస్ట్ డైరెక్టరీకి మౌంట్ చేసి, 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 కమాండ్ను ఉపయోగించి ఖాళీ వాల్యూమ్లోకి డేటాను పంపవచ్చు.
డేటాబేస్ల విషయంలో ఒక ముఖ్యమైన జాగ్రత్త: Postgres డేటా డైరెక్టరీ రన్ అవుతున్నప్పుడు tar చేయడం వల్ల, డేటా మధ్యలో ఆగిపోయిన స్థితిలో (mid-write state) కాపీ అయ్యే ప్రమాదం ఉంది, దీనివల్ల తర్వాత అది సరిగ్గా స్టార్ట్ అవ్వదు. కాబట్టి tar జరిగే కొన్ని సెకన్ల పాటు docker compose stop చేయాలి, లేదా అంతకంటే మంచి పద్ధతి ఏమిటంటే logical dump తీసుకోవడం, ఇది ఎల్లప్పుడూ స్థిరంగా (consistent) ఉంటుంది:
docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gz-T ఫ్లాగ్, Compose డిఫాల్ట్గా కేటాయించే pseudo-terminal ను నిలిపివేస్తుంది; dump అవుట్పుట్ను TTY ద్వారా పంపడం వల్ల అది పాడయ్యే అవకాశం ఉంది. వీటిలో ఒకదానిని cron లో ఉంచి, ఫలితాన్ని VPS నుండి బయటకు కాపీ చేయండి; డేటా ఉన్న అదే డిస్క్లో బ్యాకప్ ఉంచడం అనేది కేవలం కాపీ మాత్రమే, అది అసలైన బ్యాకప్ కాదు. Nextcloud guide లో ఈ రెండు పద్ధతులను ఉపయోగించి పూర్తి స్థాయి షెడ్యూల్డ్ బ్యాకప్ రొటీన్ను ఎలా నిర్మించాలో వివరించబడింది.
వైఫల్య రీతులు మరియు మీరు చూసే సందేశాలు
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, పేర్కొన్న లైన్ వద్ద లేదా దానికి పైన ఇండెంటేషన్ లోపం ఉంది. Compose ఫైళ్లు YAML ఫార్మాట్లో ఉంటాయి: రెండు స్పేస్ల ఇండెంటేషన్ మాత్రమే వాడాలి, కేవలం స్పేస్లు మాత్రమే ఉండాలి, ఎక్కడైనా tab క్యారెక్టర్ ఉంటే అది పనిచేయదు. docker compose config ఏ సేవను ప్రారంభించకుండానే ఫైల్ను సరిచూస్తుంది, ప్రతి ఎడిట్ తర్వాత దీన్ని రన్ చేయడం మంచి అలవాటు.
ufw ఆశ్చర్యం ఎటువంటి ఎర్రర్ చూపదు, అందుకే ఇది ప్రమాదకరం: డిప్లాయ్ విజయవంతమవుతుంది, ufw status అంతా సరిగ్గా ఉన్నట్లు కనిపిస్తుంది, కానీ బయటి నుంచి పోర్ట్ స్కాన్ చేస్తే మీ డేటాబేస్ కనిపిస్తుంది. పైన ఉన్న పోర్ట్స్ విభాగాన్ని మళ్ళీ చదవండి, ప్రతి ports: ఎంట్రీలో 127.0.0.1: ప్రిఫిక్స్ ఉందో లేదో తనిఖీ చేయండి, మరియు వేరొక మెషిన్ నుంచి curl http://your-vps-ip:8080 తో కనెక్ట్ అవ్వడానికి ప్రయత్నించండి, connection refused అని వస్తేనే మీరు సురక్షితంగా ఉన్నట్లు.
ఇక్కడి నుంచి, Traefik గైడ్ ఈ సింగిల్ స్టాక్ను ఒకే HTTPS ఎంట్రీ పాయింట్ వెనుక అనేక అప్లికేషన్లుగా మారుస్తుంది, మరియు 2026లో self-host చేయడానికి విలువైనవి అనే జాబితా ద్వారా మీరు మరిన్ని సేవలను రన్ చేయవచ్చు. ఇలాంటి స్టాక్లు కొన్ని రన్ అవుతున్నప్పుడు, ప్రతిదానికి విడివిడిగా లాగిన్ ఫారమ్లు కాకుండా, Authentik వంటి self-hosted SSO సర్వర్ ద్వారా వాటన్నింటినీ ఒకే అకౌంట్ కిందకు తీసుకురావచ్చు.
VPSలో Minecraft server వంటి game server ఒక Compose ప్రాజెక్ట్గా సాధన చేయడానికి అనుకూలమైన మొదటి ఎంపిక. మీరు ప్రతిరోజూ ఉపయోగించే దానితో నేర్చుకోవాలనుకుంటే, self-hosted workout tracker అయిన openGym ఒక చిన్న stack. ఇది image tag కు బదులుగా git tag కు pin చేయబడుతుంది. మొదటి passkey నమోదు చేయడానికి ముందు దీనికి ముందు TLS అమర్చాలి. ఇతరుల cloud నుంచి తిరిగి స్వయంగా నిర్వహించుకోవాలనుకునే వాటిలో photos సాధారణంగా మొదటివి. PhotoPrism మరియు Immich ను పోల్చడం ద్వారా ఏదైనా ఒకదానికి volume కేటాయించే ముందు అవసరమయ్యే కనిష్ఠ RAM మరియు మీరు అనుసరించాల్సిన backup విధానం స్పష్టమవుతుంది. రెండు services సరిపోవడం లేదనిపించినప్పుడు, Notion-style workspaceగా AFFiNEను ప్రారంభించడం అదే patterns ను నాలుగు containers వద్ద ప్రయోగించడానికి అవకాశం ఇస్తుంది. పై పేర్కొన్న pinned tags, healthchecks, named volumes అలవాటుగా మారాయో లేదో పరీక్షించడానికి ఇది సరైన సందర్భం.
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 డేటాను తొలగించదు, ఇది కేవలం కంటైనర్లను మరియు ప్రాజెక్ట్ నెట్వర్క్ను మాత్రమే తొలగిస్తుంది; named volumes అలాగే ఉంటాయి మరియు తదుపరి up -d వాటిని తిరిగి కనెక్ట్ చేస్తుంది. docker compose down -v అనేది డేటాను తొలగించే కమాండ్: ఇది named volumes ను, అంటే మీ డేటాబేస్ను, ఎటువంటి నిర్ధారణ లేకుండా మరియు తిరిగి పొందే అవకాశం లేకుండా తొలగిస్తుంది. మీ వద్ద ధృవీకరించబడిన బ్యాకప్ లేకపోతే, నిజమైన డేటా ఉన్న stack పై ఎప్పుడూ -v రన్ చేయవద్దు.
docker-compose మరియు docker compose మధ్య తేడా ఏమిటి?
docker-compose (హైఫన్) అనేది Compose v1, ఇది 2023లో ముగిసిన (end of life) స్వతంత్ర Python బైనరీ, దీన్ని కొత్త సర్వర్లలో ఇన్స్టాల్ చేయకూడదు. 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 మార్గంలో వెళ్తాయి, ఇవి ufw రూల్స్ వర్తించే INPUT చైన్ను తాకవు. అందువల్ల ufw deny 8080 పబ్లిష్ చేసిన కంటైనర్ పోర్ట్పై ఎటువంటి ప్రభావం చూపదు. దీన్ని మూలంలోనే సరిచేయండి: 127.0.0.1: కు మాత్రమే పబ్లిష్ చేయండి మరియు సేవలను రివర్స్ ప్రాక్సీ ద్వారా ఎక్స్పోజ్ చేయండి.
నేను named volume వాడాలా లేక bind mount వాడాలా?
కంటైనర్ మాత్రమే ఉపయోగించే డేటా కోసం, ముఖ్యంగా డేటాబేస్ల కోసం named volumes వాడండి, ఎందుకంటే ఇమేజ్ ఆశించే విధంగా Docker యాజమాన్యాన్ని (ownership) మరియు అనుమతులను సెట్ చేస్తుంది. మీరు హోస్ట్ నుండి కూడా నిర్వహించే ఫైళ్ల కోసం bind mounts వాడండి: మీరు ఎడిట్ చేసే కాన్ఫిగరేషన్లు, మీరు అప్లోడ్ చేసే మీడియా, లేదా పాత్ స్పష్టంగా ఉండాలనుకునే ఏదైనా ఫైల్ కోసం ఇది ఉపయోగపడుతుంది. ఒకవేళ bind mount పై కంటైనర్ స్టార్టప్ సమయంలో permission denied తో విఫలమైతే, హోస్ట్ మరియు కంటైనర్ మధ్య UID సరిపోలకపోవడం (mismatch) మొదటిగా తనిఖీ చేయాల్సిన అంశం.