Kör Docker Compose som en Linux-tjänst med systemd

Docker Compose vid start, hanterad av systemd.

Sidinnehåll

Docker Compose på en Linux-server bör starta vid systemstart, stoppa smidigt vid avstängning och överleva omstarter utan manuell inblandning.

Docker Compose är inte Kubernetes, och det är bra för de arbetsbelastningar som denna guide riktar sig mot. För många verkliga system är ett Compose-projekt på en enda Linux-värd rätt mängd infrastruktur — enkelt, läsbar, lätt att backa upp och tillräckligt bra för interna verktyg, sidoprojekt, självhostade tjänster, staging-miljöer, små produktionsappar och utvecklarinfrastruktur.

docker compose config ont the table with laptop

Den saknade pusselbiten är oftast tjänstehantering. Att köra detta manuellt räcker inte:

docker compose up -d

Ett enda kommando startar stacken, men det dokumenterar inte hur stacken ska starta vid boot, stoppa vid avstängning, ladda om efter ändringar, skriva loggar, återhämta sig från fel eller uppdateras säkert. Det är där systemd hjälper till.

Denna guide går igenom hur man kör ett Docker Compose-projekt som en Linux-tjänst med systemd — enhetsfiler, startordning, uppdateringar, loggar och säkerhetskopior. Ansvarsfördelningen är medveten: Docker kör containrar, Compose definierar stacken och systemd startar och stoppar projektet på värden. Det är en del av Utvecklarverktyg - en guide till utvecklingsarbetsflöden.

När Docker Compose som en tjänst är meningsfullt

Att köra Compose under systemd är meningsfullt när du har:

  • En enda Linux-server
  • En liten självhostad applikation
  • En reverse proxy-stack
  • En monitoringsstack
  • En lokal utvecklingsplattform
  • Ett internt verktyg
  • En staging-miljö
  • En enkel produktionstjänst med kända begränsningar

Exempel:

  • Nginx Proxy Manager
  • Traefik
  • Gitea
  • Grafana och Prometheus
  • PostgreSQL plus en liten webbapp
  • Uptime Kuma
  • Home Assistant-hjälptjänster
  • Privat registry
  • Intern API plus worker plus Redis

Compose passar bra när det operativa modellen fortfarande är begriplig för en person som läser en katalog.

När Docker Compose inte räcker

Använd något annat när du behöver:

  • Multi-nod schemaläggning
  • Automatisk omplanering över värdar
  • Tjänstegenerering på kluster-nivå
  • Horisontell autoskalning
  • Rullande distributioner över många maskiner
  • Finmaskad arbetsbelastningsidentitet
  • Komplext nätverkspolicy
  • Stora plattformsoperationer för flera team

I det läget kan Kubernetes, Nomad, Swarm eller en hanterad plattform vara ett bättre val.

Min praktiska regel är att undvika att använda Kubernetes bara för att slippa lära sig systemd, och att undvika att använda Compose när arbetsbelastningen tydligt behöver orkestrering över flera värdar.

Den grundläggande arkitekturen

En ren installation separerar projektfiler, systemd-enheten och persistent data på värden. Compose-projektet ligger under /opt/myapp/ med compose.yaml, .env, data/, backups/ och valfria skript som scripts/update.sh. Systemd-enhetsfilen ligger på /etc/systemd/system/myapp.service.

flowchart TB subgraph host["Linux host"] systemd["systemd unit\n/etc/systemd/system/myapp.service"] compose["Docker Compose\n/opt/myapp/compose.yaml"] docker["Docker Engine"] fs["Persistent data\n/opt/myapp/data/"] end systemd -->|"ExecStart: docker compose up -d"| compose compose --> docker docker --> fs

Varje lager har ett tydligt uppdrag: Docker kör containrar, Compose definierar applikationsstacken, systemd startar och stoppar Compose-projektet vid start och avstängning, värdens filsystem sparar persistent data, säkerhetskopior förblir explicita och uppdateringar går genom skriptade, granskbara steg. Denna layout är medvetet tråkig, eftersom tråkig infrastruktur är lättare att reparera när något går sönder klockan 2 på natten.

Förbered Compose-projektkatalogen

Skapa en katalog under /opt:

sudo mkdir -p /opt/myapp
sudo chown -R "$USER":"$USER" /opt/myapp
cd /opt/myapp

Skapa en Compose-fil:

nano compose.yaml

Exempel:

services:
  web:
    image: nginx:stable
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    healthcheck:
      test: ["CMD-SHELL", "nginx -t || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

volumes: {}

Skapa innehållskatalogen:

mkdir -p html
echo "Hello from Docker Compose" > html/index.html

Testa manuellt först:

docker compose up -d
docker compose ps
docker compose logs --tail=50

Stoppa sedan den innan du överlämmer livscykeln till systemd:

docker compose down

Skapa inte en systemd-tjänst förrän Compose-projektet fungerar manuellt. Medan du testar, håll Docker Compose Cheatsheet nära för ps, logs, pull och projektstruktur.

Använd det moderna docker compose-kommandot

Docker Engine och Compose-pluginet måste vara installerade innan du skriver en enhetsfil. På Ubuntu, Installera Docker på Ubuntu går igenom APT, Snap, rootless-läge och säkerhet efter installation så att du slutar med ett fungerande docker compose-kommando.

Använd detta:

docker compose version

Inte detta:

docker-compose version

Den gamla docker-compose-binären finns fortfarande på många maskiner, men modern Docker använder Compose som ett Docker CLI-plugin.

I servicefiler och skript, föredra:

/usr/bin/docker compose

Du kan hitta Docker-sökvägen med:

command -v docker

Vanligtvis är det:

/usr/bin/docker

Skapa en systemd-tjänst för Docker Compose

Om enhetsfiler är nya för dig, Kör valfri exekverbar fil som en tjänst i Linux förklarar Type, ExecStart, systemctl och den generella systemd-arbetsflödet. Detta avsnitt tillämpar dessa mönster specifikt för en Compose-stack.

Skapa servicefilen:

sudo nano /etc/systemd/system/myapp.service

Använd denna enhet:

[Unit]
Description=MyApp Docker Compose stack
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
TimeoutStopSec=120

[Install]
WantedBy=multi-user.target

Ladda om systemd:

sudo systemctl daemon-reload

Starta tjänsten:

sudo systemctl start myapp.service

Aktivera den vid start:

sudo systemctl enable myapp.service

Kontrollera status:

systemctl status myapp.service

Kontrollera containrar:

cd /opt/myapp
docker compose ps

Varför Type=oneshot och RemainAfterExit=yes?

Detta är den del som många guider får subtilt fel.

docker compose up -d startar containrar i detached-läge och avslutas, så det finns ingen långvarig foreground Compose-process för systemd att övervaka. Systemd-enheten bör inte låtsas att docker compose up -d är en långvarig daemon.

Använd:

Type=oneshot
RemainAfterExit=yes

Detta säger till systemd:

  • Kör startkommandot.
  • Anså som enheten aktiv efter att kommandot avslutas framgångsrikt.
  • Kör ExecStop när tjänsten stoppas.

Detta matchar den faktiska beteendet hos detached Compose, vilket är varför Type=oneshot med RemainAfterExit=yes är rätt standard för de flesta stackar.

Varför inte Type=simple?

Med Type=simple förväntar sig systemd att ExecStart-processen ska fortsätta köra, men docker compose up -d avslutas efter att containrarna startat. Det kan få systemd att tro att tjänsten avslutades, vilket sedan kan kalla stop-logik eller markera enheten som inaktiv beroende på konfiguration.

Om du vill ha Type=simple, skulle du vanligtvis köra Compose i foreground:

ExecStart=/usr/bin/docker compose up

Det kan fungera, men jag föredrar det inte vanligtvis för Compose-stackar på servrar. Detached containrar plus explicit ExecStop är lättare att operera.

En mer produktionsvänlig enhet

För en riktig server föredrar jag en något striktare enhet:

[Unit]
Description=MyApp Docker Compose stack
Documentation=https://example.com/docs/myapp
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
EnvironmentFile=-/opt/myapp/.env.systemd
ExecStartPre=/usr/bin/docker compose config --quiet
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecReload=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
TimeoutStopSec=120

[Install]
WantedBy=multi-user.target

Viktiga detaljer:

  • WorkingDirectory pekar mot Compose-projektet.
  • ExecStartPre validerar Compose-konfigurationen.
  • ExecReload skapar om ändrade tjänster.
  • ExecStop stoppar och tar bort Compose-projektets containrar och standardnätverk.
  • EnvironmentFile=-... betyder att filen är valfri.

Skapa den valfria systemd-miljöfilen:

nano /opt/myapp/.env.systemd

Exempel:

COMPOSE_PROJECT_NAME=myapp

Ladda sedan om systemd:

sudo systemctl daemon-reload
sudo systemctl restart myapp.service

Compose .env kontra systemd EnvironmentFile

Compose och systemd har var sin egen miljömekanism, och att blanda ihop dem leder till förvirrande “variabel inte inställd”-fel vid start.

Compose läser automatiskt en .env-fil i projektkatalogen för variabelsubstitution i Compose-filen.

Exempel .env:

APP_TAG=1.2.3
WEB_PORT=8080

Exempel compose.yaml:

services:
  web:
    image: nginx:${APP_TAG}
    ports:
      - "${WEB_PORT}:80"

En systemd EnvironmentFile ställer in miljövariabler för själva docker compose-kommandot.

Exempel:

EnvironmentFile=-/opt/myapp/.env.systemd

För många projekt behöver du bara Compose .env.

Använd en systemd-miljöfil när du vill definiera saker som:

COMPOSE_PROJECT_NAME=myapp
COMPOSE_FILE=compose.yaml
DOCKER_HOST=unix:///var/run/docker.sock

Använd inte någon av filerna som en casual hemlighetsvalv. Om hemligheter är viktiga, använd Docker secrets, en extern secret manager, krypterade filer eller åtminstone strikta behörigheter.

Ställ in restriktiva behörigheter:

chmod 600 /opt/myapp/.env
chmod 600 /opt/myapp/.env.systemd

Startpolicy: Docker kontra systemd

Det finns två startlager — container startpolicy i Compose och systemd-tjänstens startpolicy — och de bör inte blandas ihop slarvigt.

För långvariga containrar, ställ in startpolicy i Compose:

services:
  web:
    image: nginx:stable
    restart: unless-stopped

Vanliga startvärden:

Policy Betydelse
no Starta inte om automatiskt
always Starta om efter exit och daemon restart
on-failure Starta om endast efter fel
unless-stopped Starta om om inte manuellt stoppat

För de flesta persistenta tjänster föredrar jag:

restart: unless-stopped

Det är förutsägbar och respekterar avsiktliga manuella stopp.

Systemd-enheten själv bör vanligtvis inte starta om upprepade gånger, eftersom docker compose up -d inte är den körande arbetsbelastningen. Det är containrarna.

Så undvik detta om du inte har en specifik anledning:

Restart=always

I de flesta Compose-as-service-enheter, låt Docker hantera container start.

Hälsokontroller

Startpolicy startar containrar när processer avslutas. De fixar inte magiskt varje ohälsosam applikation.

Lägg till hälsokontroller där de är användbara:

services:
  app:
    image: example/app:latest
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "curl -fsS http://localhost:8080/health || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s

Kontrollera hälsa:

docker compose ps

Inspektera en container:

docker inspect container-name

Hälsokontroller är särskilt användbara för:

  • Webbappar
  • Reverse proxies
  • Databaser
  • Köer
  • Interna APIs
  • Workers med en health endpoint

De är mindre användbara när de bara kontrollerar att en process existerar, eftersom en process som är levande men fastnat fortfarande ser frisk ut. En dålig hälsokontroll är bara en annan lögn i YAML.

Startordning och depends_on

Compose kan definiera beroenden:

services:
  app:
    image: example/app:latest
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

Detta kan hjälpa startordningen, men lita inte för mycket på det. Applikationer bör fortfarande hantera omförsök — databaser startar om, nätverk fluktuerar, DNS tar tid, och en resilient app försöker ansluta igen istället för att anta perfekt startordning.

Loggar: journalctl och docker compose logs

Två logvyer täcker de flesta felsökningsbehov: systemd fångar livscykeln för enheten själv, medan Compose fångar applikationsoutput från körande containrar.

systemd tjänsteloggar:

journalctl -u myapp.service -n 100 --no-pager

Följ systemd-loggar:

journalctl -u myapp.service -f

Compose tjänsteloggar:

cd /opt/myapp
docker compose logs --tail=100
docker compose logs -f
docker compose logs -f web

För de flesta app-felsökningar är docker compose logs mer användbar; för livscykel-felsökning — startfel, enhetskrascher, behörighetsfel — är journalctl mer användbar. Om systemctl start myapp misslyckas, kolla journalctl först. Om stacken startar men appen är trasig, kolla docker compose logs.

Logrotation

Docker-loggar kan växa för evigt om du inte konfigurerar dem.

För små servrar, konfigurera Docker logrotation i /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}

Starta om Docker:

sudo systemctl restart docker

Starta sedan om Compose-stacken:

sudo systemctl restart myapp.service

Detta gäller för nyskapade containrar. Skapa om containrar om nödvändigt:

cd /opt/myapp
docker compose up -d --force-recreate

Logrotation är inte glamourös, men det är ett av de enklaste sätten att förhindra en disk-full utmattning på en liten server.

Uppdatering av en Compose-tjänst

En enkel manuell uppdateringsflöde:

cd /opt/myapp
docker compose pull
docker compose up -d --remove-orphans
docker image prune -f

Om hanterad av systemd, kan du använda:

sudo systemctl reload myapp.service

Om din enhet har:

ExecReload=/usr/bin/docker compose up -d --remove-orphans

Men notera: ExecReload hämtar inte bilder om du inte inkluderar det steget.

För explicita uppdateringar, skapa ett skript.

mkdir -p /opt/myapp/scripts
nano /opt/myapp/scripts/update.sh

Skript:

#!/usr/bin/env bash
set -euo pipefail

cd /opt/myapp

docker compose config --quiet
docker compose pull
docker compose up -d --remove-orphans
docker image prune -f
docker compose ps

Gör det exekverbart:

chmod +x /opt/myapp/scripts/update.sh

Kör det:

/opt/myapp/scripts/update.sh

Då kan serviceenheten förbli fokuserad på livscykel, medan uppdateringsskriptet hanterar distribution.

Säkrare uppdateringsskript med backup-hook

För stateful tjänster, uppdatera endast efter backup.

#!/usr/bin/env bash
set -euo pipefail

APP_DIR="/opt/myapp"
BACKUP_DIR="/opt/myapp/backups"

cd "$APP_DIR"

mkdir -p "$BACKUP_DIR"

echo "Validerar compose-fil"
docker compose config --quiet

echo "Kör backup-hook"
if [ -x "$APP_DIR/scripts/backup.sh" ]; then
  "$APP_DIR/scripts/backup.sh"
else
  echo "Ingen backup-hook hittad"
fi

echo "Hämtar bilder"
docker compose pull

echo "Skapar om tjänster"
docker compose up -d --remove-orphans

echo "Rensar oanvända bilder"
docker image prune -f

echo "Aktuell status"
docker compose ps

Detta är fortfarande enkelt, men nu kodar det ett operativt vanemönster: backup före ändring.

Stoppa tjänsten

Stoppa stacken:

sudo systemctl stop myapp.service

Det kör:

docker compose down

Som standard, docker compose down tar bort:

  • Containrar för tjänster i Compose-filen
  • Nätverk definierade av Compose-filen
  • Standardnätverket

Det tar inte bort namngivna volymer om du inte ber den om det.

Använd inte casually:

docker compose down -v

Det tar bort namngivna volymer deklarerade i Compose-filen och anonyma volymer kopplade till containrar. För databaser och stateful appar kan det betyda att radera verklig data.

Använd down -v endast när du menar “destiera denna miljö”.

Starta om tjänsten

Starta om systemd-enheten:

sudo systemctl restart myapp.service

Detta kör stopp-kommandot och sedan startkommandot.

För endast att starta om containrar utan att skapa om dem:

cd /opt/myapp
docker compose restart

Viktig distinktion:

  • docker compose restart startar om existerande containrar.
  • docker compose up -d tillämpar konfigurations- eller bildändningar genom att skapa om containrar när det behövs.

Om du ändrade compose.yaml, använd:

docker compose up -d

Inte bara:

docker compose restart

Hantera orphan containrar

Om du byter namn eller tar bort en tjänst i compose.yaml, kan gamla containrar förbli som orphans.

Använd:

docker compose up -d --remove-orphans

Det är varför systemd-service-exemplen i denna guide använder:

ExecStart=/usr/bin/docker compose up -d --remove-orphans

Det håller stacken närmare den aktuella Compose-filen.

Säkerhetskopior

Säkerhetskopior beror på arbetsbelastningen, men principerna är stabila.

För bind mounts:

/opt/myapp/data/

Backupa den katalogen.

För namngivna volymer:

docker volume ls

Inspektera en volym:

docker volume inspect volume-name

För databaser är filsystemkopior inte alltid tillräckligt. Använd applikationsmedvetna säkerhetskopior:

PostgreSQL-exempel:

docker compose exec -T db pg_dump -U postgres appdb > backups/appdb.sql

MariaDB-exempel:

docker compose exec -T db mariadb-dump -u root -p appdb > backups/appdb.sql

Redis-exempel:

docker compose exec redis redis-cli BGSAVE

En Compose-stack utan en backupplan är inte en tjänst — det är ett tillfälligt experiment som råkar ha uptime.

Säkerhetsbaslinje

För en liten Compose-tjänst på Linux, börja med denna baslinje:

  • Håll Compose-projektet under /opt/appname.
  • Använd explicita bildtaggar, inte bara latest, när stabilitet är viktig.
  • Använd bind mounts eller namngivna volymer medvetet.
  • Exponera inte portar du inte behöver.
  • Placera publika tjänster bakom en reverse proxy.
  • Använd HTTPS vid kanten.
  • Håll hemligheter borta från Git.
  • Restriktiv .env-behörighet.
  • Undvik privilegierade containrar om inte verkligen nödvändigt.
  • Undvik att montera Docker-socketten i containrar.
  • Håll Docker och bilder uppdaterade.
  • Testa brandväggsbeteende från en annan maskin.

Ett farligt mönster:

volumes:
  - /var/run/docker.sock:/var/run/docker.sock

Detta ger containern kontroll över Docker. I praktiken kan det bli värd-nivå kontroll. Använd det endast när du förstår risken.

Resursbegränsningar

På små servrar kan en dålig container konsumera värden.

Compose stöder resursrelaterade inställningar, men beteendet kan bero på Docker Engine och Compose-version. För enkel skydd, börja med applikationsnivå-begränsningar och Docker loggbegränsningar.

För vissa arbetsbelastningar kan du lägga till minnesbegränsningar:

services:
  app:
    image: example/app:stable
    restart: unless-stopped
    mem_limit: 512m

Konfigurera också app-nivå worker-counts, köbegränsningar och cachestorlekar. Containerbegränsningar är användbara, men de är inte en ersättning för att förstå applikationen.

Exempel: En realistisk Compose-tjänst

Katalog:

/opt/whoami/
  compose.yaml
  .env

Compose-fil:

services:
  whoami:
    image: traefik/whoami:v1.10
    restart: unless-stopped
    ports:
      - "${WHOAMI_PORT}:80"
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3

.env-fil:

WHOAMI_PORT=8080
COMPOSE_PROJECT_NAME=whoami

systemd-enhet:

[Unit]
Description=Whoami Docker Compose stack
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/whoami
ExecStartPre=/usr/bin/docker compose config --quiet
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecReload=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
TimeoutStopSec=120

[Install]
WantedBy=multi-user.target

Installera den:

sudo systemctl daemon-reload
sudo systemctl enable --now whoami.service

Testa:

curl http://localhost:8080

Kontrollera status:

systemctl status whoami.service
cd /opt/whoami
docker compose ps

Felsökning

Tjänsten startar men containrarna körs inte

Kontrollera systemd:

journalctl -u myapp.service -n 100 --no-pager

Validera Compose:

cd /opt/myapp
docker compose config

Kontrollera Docker:

systemctl status docker
docker info

WorkingDirectory är fel

Om systemd inte kan hitta din Compose-fil, bekräfta:

WorkingDirectory=/opt/myapp

Kontrollera sedan:

ls -la /opt/myapp
ls -la /opt/myapp/compose.yaml

Tjänsten körs från WorkingDirectory, inte från din aktuella skal-katalog.

Docker Permission Denied

Om enheten körs som root, kan den normalt tillgå Docker.

Om du ställer in User=someuser, måste den användaren kunna tillgå Docker. Vanligtvis betyder det medlemskap i docker-gruppen, eller ett rootless Docker-setup.

Kontrollera:

groups someuser

Lägg till användaren om lämpligt:

sudo usermod -aG docker someuser

Var försiktig. Docker-gruppen är effektivt privilegierad.

Compose-kommandot hittades inte

Hitta Docker:

command -v docker

Använd fullständig sökväg i enheten:

ExecStart=/usr/bin/docker compose up -d --remove-orphans

Om Compose-pluginet saknas:

docker compose version

Installera det med din Docker-pakkällkälla.

Miljövariabler saknas

Kontrollera Compose-konfigurationen som systemd skulle se den:

cd /opt/myapp
docker compose config

Om systemd behöver extra miljövariabler, använd:

EnvironmentFile=-/opt/myapp/.env.systemd

Om Compose behöver variabler för substitution, använd:

/opt/myapp/.env

Dessa är relaterade, men inte identiska.

Containrarna startar inte efter omstart

Kontrollera om systemd-tjänsten är aktiverad:

systemctl is-enabled myapp.service

Aktivera den:

sudo systemctl enable myapp.service

Kontrollera Docker:

systemctl is-enabled docker
systemctl status docker

Kontrollera startloggar:

journalctl -u myapp.service -b --no-pager

Appen startar innan databasen är redo

Lägg till en databashälsokontroll och depends_on med service_healthy.

Fixa också applikationen. Den bör försöka ansluta till databasen igen. Infrastrukturstartordning är hjälpsam, men applikationsomförsökslogik är bättre.

Disk fylld med Docker-loggar

Kontrollera Docker diskanvändning:

docker system df

Kontrollera stora containerloggar:

sudo du -h /var/lib/docker/containers | sort -h | tail

Konfigurera Docker logrotation i /etc/docker/daemon.json.

Skapa sedan om containrarna.

Vanliga misstag

Misstag 1: Kör docker compose up i rc.local

Att köra docker compose up från rc.local eller ett login-skript fungerar tills det inte gör det — använd en korrekt systemd-enhet istället.

Misstag 2: Använder Restart=always i systemd och restart: always i Compose

Vanligtvis behöver du bara container startpolicy i Compose. Undvik att två supervisors strider mot varandra.

Misstag 3: Glömmer –remove-orphans

Tjänstnamnbyte och borttagningar kan lämna gamla containrar. Använd:

docker compose up -d --remove-orphans

Misstag 4: Använder docker compose restart efter konfigurationsändringar

restart startar om containrar. Det tillämpar inte alla konfigurationsändringar.

Använd:

docker compose up -d

Misstag 5: Kör down -v utan att tänka

Detta kan radera volymer. För stateful tjänster kan det betyda att radera data.

Misstag 6: Ingen backup före pull

Nya bilder kan gå sönder. Databaser kan migrera. Taggar kan flytta. Backupa först.

Misstag 7: Publicerar varje port

Publicera endast det som värden behöver exponera. Intern tjänst-till-tjänst trafik kan stanna på Compose-nätverket.

Avslutande rekommenderat mönster

För de flesta single-host Linux-tjänster, använd detta mönster:

Compose-fil:

services:
  app:
    image: example/app:stable
    restart: unless-stopped
    ports:
      - "8080:8080"
    env_file:
      - .env

systemd-enhet:

[Unit]
Description=MyApp Docker Compose stack
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStartPre=/usr/bin/docker compose config --quiet
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecReload=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
TimeoutStopSec=120

[Install]
WantedBy=multi-user.target

Aktivera den:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service

Operera den:

sudo systemctl status myapp.service
sudo systemctl restart myapp.service
journalctl -u myapp.service -f
cd /opt/myapp && docker compose logs -f

Detta mönster är inte fancy, och det är poängen. Docker Compose är utmärkt för små, begripliga system, systemd är utmärkt på att starta och stoppa värdtjänster, och tillsammans ger de dig en pålitlig single-server distributionsmodell utan att låtsas att varje projekt behöver ett kluster. För container-nivå kommandon utanför Compose — bilder, volymer, nätverk och rensning — se Docker Cheatsheet.

Prenumerera

Få nya inlägg om system, infrastruktur och AI-ingenjörskonst.