Kör Docker Compose som en Linux-tjänst med systemd
Docker Compose vid start, hanterad av systemd.
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.

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.
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
ExecStopnä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:
WorkingDirectorypekar mot Compose-projektet.ExecStartPrevaliderar Compose-konfigurationen.ExecReloadskapar om ändrade tjänster.ExecStopstoppar 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 restartstartar om existerande containrar.docker compose up -dtillä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.