Kā izvietot lietotnes ar Docker Compose VPS serverī
Praktisks ražošanas ceļvedis Docker Compose v2 Ubuntu: instalējiet dzinēju, uzrakstiet Compose failu ar tīkliem un sējumiem, pārvaldiet noslēpumus, novietojiet reverso starpnieku priekšā, atjauniniet ar mierīgām izlaišanām un dublējiet nosauktos sējumus.

Docker Compose ir parastais veids, kā palaist nelielu steku vienā VPS: tīmekļa lietotne, datubāze, Redis kešatmiņa un reversais starpnieks, aprakstīti vienā YAML failā. Tas nav Kubernetes. Jūs nesaņemsiet vairāku mezglu pārslēgšanu. Jūs iegūsiet atkārtojamu, pārskatāmu iestatījumu, ko minūtēs varat atjaunot jaunā Hiddence VPS — tieši to vajag lielākajai daļai blakusprojektu un mazu produktu.
Šis raksts pieņem, ka vēlaties kaut ko tuvāk ražošanai nekā docker run piektdienas vakarā. Instalēsim Docker Engine un Compose spraudni, izveidosim izvietošanas lietotāju bez root, uzrakstīsim Compose failu ar healthcheck un restartēšanas politikām, noslēpumus turēsim ārpus Git, internetā publicēsim tikai reversā starpnieka portus un definēsim atjaunināšanas un dublēšanas rutīnu. Parauga steks ir tipiska tīmekļa lietotne plus PostgreSQL plus Caddy, bet tas pats raksts der Node, PHP, Python vai strādnieku kopai.
Kāpēc Compose vienā VPS joprojām ir jēga
Cilvēki lec pie Kubernetes, jo tas ir moderni, un tad nedēļas nogali pavada YAML vienai vietnei. Compose paliek lasāms. Versējiet failu, dokumentējiet vides mainīgos un varat diff izmaiņu pirms tās piemērošanas. Izolācija ir pietiekama: kompromitētam lietotnes konteineram nevajadzētu turēt datubāzes UNIX ligzdu, ja izmantojāt tīklus un vismazāko privilēģiju lietotājus. Resursu limiti aptur atmiņas noplūdi no visa VPS iesaldēšanas.
- Viens fails apraksta visu steku
- Nosauktie sējumi izdzīvo konteineru atkārtotu izveidi
- Iekšējie Docker tīkli tur Postgres prom no publiskā interneta
- restart: unless-stopped nosedz lielāko daļu restartēšanu
- Viegli nokopēt uz otru VPS, kad izaugat no pirmā
Prasības
Izmantojiet VPS ar pietiekami RAM lietotnei plus Postgres. 2 GB plāns ir reālistisks minimums lietotnei + datubāzei + starpniekam. Pieņemts Ubuntu 24.04. Neinstalējiet Docker no nejauša Snap, nelasot, ko tas dara ar cgroups; tālāk esošie soļi izmanto Docker oficiālo apt krātuvi.
- Ubuntu 22.04/24.04, root vai sudo
- Ieteicams 2 GB RAM (1 GB tikai sīkiem stekiem bez Postgres)
- Domēns, kas norāda uz VPS, ja vēlaties automātisku HTTPS
- Git vai cits veids, kā nokopēt projektu uz serveri
1. solis: instalējiet Docker Engine un Compose v2
Compose v2 ir spraudnis, ko izsauc kā docker compose (ar atstarpi), nevis vecais docker-compose Python binārs. Instalējiet abus no Docker krātuves, lai iegūtu aktuālos drošības ielāpus.
ssh root@YOUR_VPS_IP
apt update && apt -y install ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
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" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
docker version
docker compose version2. solis: izvietošanas lietotājs un katalogu izkārtojums
Compose palaišana kā root darbojas, bet veltīts lietotājs ar dalību docker grupā ir tīrāks. Projektu lieciet /opt vai /srv, ne /root, lai dublējumi un atļaujas būtu acīmredzamas. Nekad nedariet katalogu, kurā ir .env, rakstāmu visiem.
adduser --disabled-password --gecos '' deploy
usermod -aG docker deploy
mkdir -p /srv/app
chown deploy:deploy /srv/app
chmod 750 /srv/app
# Log in as deploy for the rest of the file editing:
# su - deploy
# cd /srv/app3. solis: uzrakstiet ražošanai paredzētu Compose failu
Tālāk esošais fails ir veidne. Aizstājiet lietotnes attēlu ar savu. Postgres netiek publicēts uz 0.0.0.0:5432 — tikai Caddy tiek publicēts 80 un 443. Healthcheck aptur reverso starpnieku no datplūsmas sūtīšanas lietotnei, kas joprojām migrē datubāzi. Piesieniet attēlu birkas; latest ir tas, kā notiek pārsteiguma kļūmes.
# /srv/app/compose.yaml
services:
caddy:
image: caddy:2.8-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
app:
condition: service_healthy
app:
image: ghcr.io/example/webapp:1.4.2
restart: unless-stopped
env_file: .env
environment:
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8000/health"]
interval: 10s
timeout: 3s
retries: 10
networks:
- frontend
- backend
db:
image: postgres:16-alpine
restart: unless-stopped
env_file: .env
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
networks:
- backend
networks:
frontend: {}
backend: {}
volumes:
pgdata:
caddy_data:
caddy_config:4. solis: noslēpumi, .env un Caddyfile
Paroles lieciet .env serverī, chmod 600, un nekad necommitējiet to failu. Ģenerējiet paroles ar openssl rand -base64 32. Caddyfile vajag tikai reverso starpnieku uz lietotnes pakalpojuma nosaukumu Docker tīklā.
# /srv/app/.env (permissions 600)
POSTGRES_USER=app
POSTGRES_PASSWORD=change-me-long-random
POSTGRES_DB=app
# plus any APP_SECRET / NEXTAUTH_SECRET your image needs
# /srv/app/Caddyfile
app.example.com {
encode gzip
reverse_proxy app:8000
}
chmod 600 /srv/app/.env
cd /srv/app
docker compose up -d
docker compose ps
docker compose logs -f --tail=1005. solis: ugunsmūris, žurnāli un resursu limiti
UFW jāatļauj tikai 22, 80 un 443. Docker dažreiz apej UFW publicētajiem portiem; ja vajag stingru saimnieka ugunsmūri, uzmeklējiet pašreizējo Docker + UFW mijiedarbību savai Ubuntu versijai vai publicējiet portus tikai 127.0.0.1 un priekšā novietojiet saimnieka Caddy. Compose iestatiet atmiņas limitus, lai Postgres nevarētu apēst VPS.
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
# Optional in compose.yaml under app or db:
# deploy:
# resources:
# limits:
# memory: 512M
# Logs (do not let json-file grow forever):
# { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }
# in /etc/docker/daemon.json then: systemctl restart docker6. solis: atjauninājumi un atcelšana
Garlaicīgais atjauninājums, kas darbojas: velciet jaunus attēlus, up -d, vērojiet healthcheck, saglabājiet iepriekšējo birku git, lai varētu piesiet atpakaļ. Nepalaižiet docker compose down ražošanas datubāzē, ja vien neplānojat pārtraukt datplūsmas pieņemšanu. down -v dzēš sējumus — tā ir izdzēšana, ne restartēšana.
cd /srv/app
git pull # if the Compose file lives in git
# Change the image tag in compose.yaml, then:
docker compose pull
docker compose up -d
docker compose ps
# Rollback: set the old tag, pull, up -d again
# NEVER: docker compose down -v # this deletes named volumesDublējiet nosauktos sējumus
VPS momentuzņēmums ir labs. Loģisks Postgres dump ir labāks, ja jāatjauno citā mašīnā. Ieplānojiet to ar cron. Reizi pārbaudiet atjaunošanu, citādi jums nav dublējumu — jums ir faili, par kuriem cerat, ka tie ir dublējumi.
# Postgres dump while the db container is running:
docker compose exec -T db pg_dump -U app app | gzip > /var/backups/app-$(date +%F).sql.gz
# Copy off-box
# scp /var/backups/app-*.sql.gz backup-host:~
# Restore sketch (maintenance window):
# gunzip -c app-2026-08-19.sql.gz | docker compose exec -T db psql -U app appProblēmu novēršana
Lasiet docker compose ps un docker compose logs service. Attēlu vilkšanas kļūmes parasti ir ghcr/docker hub ātruma limiti vai privāts attēls bez pieteikšanās. 502 no Caddy nozīmē, ka lietotne nav healthy vai starpnieka resursdatora nosaukums ir nepareizs (no Caddy konteinera izmantojiet Compose pakalpojuma nosaukumu, ne localhost). Atļauju kļūdas sējumos bieži nozīmē, ka attēls darbojas kā uid 1000, kamēr saimnieka katalogs ir root.
- compose: command not found — instalējāt veco binārā nosaukumu; izmantojiet docker compose
- port is already allocated — kaut kas cits pārvalda 80/443 (Apache, Nginx, cits Caddy)
- database connection refused — lietotne startēja pirms Postgres gatavības; izmantojiet healthcheck + depends_on condition
- disk full — docker system df, pēc tam uzmanīgi prune neizmantotos attēlus
- permission denied on docker.sock — lietotājs nav docker grupā vai vajag jaunu pieteikšanās sesiju
Drošība
Nepublicējiet datubāzes portus. Nepalaižiet privileged: true. Nemontējiet /var/run/docker.sock lietotnes konteinerā, ja vien apzināti nerakstāt konteineru pārvaldnieku. Turiet dzinēju atjauninātu. Skenējiet savus attēlus, ja tos būvējat. .env diskā joprojām ir slepens fails — ierobežojiet, kas var ssh uz kasti.
- Nav publiska 5432 / 3306 / 6379
- Piesieniet attēlu kopsavilkumus vai vismaz nemainīgas birkas
- chmod 600 .env
- Unattended-upgrades saimnieka OS joprojām ir svarīgi
- Viens Compose projekts lietotnei samazina sprādziena rādiusu
Padomi
- compose.yaml lieciet git; .env.example turiet bez īstiem noslēpumiem
- Izmantojiet profilus izvēles strādniekiem (docker compose --profile workers up -d)
- Sekojiet docker stats, kad izmērat VPS
- Avota koda bind mounts nav ražošanas raksts — izcepiet attēlu
- Ja steks izaug līdz vairākiem VPS, tad skatieties orķestrēšanu — ne agrāk
Ražošanai līdzīgs Compose iestatījums vienā VPS ir: oficiālas Docker pakotnes, noslēgts .env, YAML fails, kas nepublicē datubāzi, healthcheck, reversais starpnieks 80/443, UFW, attēlu birkas, ko varat atcelt, un Postgres dump, ko esat patiešām reizi atjaunojuši. Sāciet no šī raksta veidnes, aizstājiet lietotnes attēlu un izturieties pret docker compose down -v kā pret destruktīvu komandu ar tādu pašu cieņu kā pret rm -rf.