Uppdatera utan dataförlust
Så uppdaterar ni ett program som körs i Docker utan att tappa data: läs vad som ändrats, ta en säkerhetskopia, lås versionen och ha en väg tillbaka om något går fel.
Vad ni får ut av det här
Program med öppen källkod får säkerhetsrättningar hela tiden. Ett system som aldrig uppdateras blir till slut en öppen dörr, särskilt om det nås från internet. Samtidigt är uppdateringen det tillfälle då flest installationer går sönder.
Båda sakerna är sanna. Lösningen är en fast rutin som gör uppdateringen tråkig: ni vet vilken version ni går till, ni har en kopia av datan innan ni börjar, och ni vet exakt vad ni gör om det inte fungerar.
Guiden gäller alla program som körs med Docker Compose. Exemplen använder Nextcloud och Postgres, men stegen är desamma för Vaultwarden, n8n, Paperless-ngx och de andra.
Det här behöver ni innan ni börjar
- En installation som startas med
docker compose up -dfrån en mapp medcompose.yaml. - En fungerande säkerhetskopia, och helst en som ni har provat att läsa tillbaka. Guiden Backup av en Docker-installation går igenom hur.
- En tidpunkt då ingen behöver systemet under en halvtimme.
- Tillgång till terminalen på datorn eller servern där programmet körs.
Varför latest är en dålig idé
Titta på raden image: i er compose.yaml. Står det nextcloud:latest, n8n:latest eller bara nextcloud utan något efter (vilket betyder samma sak) hämtar ni den senaste versionen varje gång ni uppdaterar. Det kan vara en liten rättning. Det kan också vara ett hopp över en hel huvudversion, med ändringar i databasen som inte går att backa.
Ni bestämmer inte själva när det händer, och det är problemet.
Lås i stället versionen med en tagg. De flesta projekt publicerar sina avbilder med taggar på flera nivåer, till exempel 31, 31.0 och 31.0.4. En tagg med bara huvudversionen ger er rättningar och småförbättringar inom den versionen, men aldrig ett hopp till nästa. Det är en rimlig nivå för ett litet företag:
services:
app:
image: nextcloud:31-apache
db:
image: postgres:16
Siffrorna är exempel. Vilka taggar som finns ser ni på avbildens sida på Docker Hub eller i projektets dokumentation; de skiljer sig mellan projekt, och en del publicerar bara fullständiga versionsnummer.
Databasen är den viktigaste att låsa. En Postgres-databas som skapats med version 16 går inte att starta med version 17 genom att bara byta taggen, eftersom huvudversionerna lagrar data på olika sätt. Byte av huvudversion kräver en dump och en återläsning. Inom samma huvudversion är det däremot aldrig något problem.
Läs vad som har ändrats
Innan ni byter version, läs versionsanteckningarna. På engelska heter de release notes eller changelog, och ni hittar dem nästan alltid under Releases på projektets GitHub-sida eller i dokumentationen under en rubrik om uppgradering.
Ni behöver inte förstå allt. Leta efter det här:
- Ord som breaking, migration, upgrade notes eller deprecated. De betyder att något fungerar annorlunda efteråt, eller att ni behöver göra något själva.
- Krav på att gå via en viss version. Nextcloud går till exempel bara att uppgradera en huvudversion i taget, så från 29 till 31 går vägen över 30.
- Ändrade miljövariabler eller inställningar i
compose.yaml. - Säkerhetsrättningar. Står det security eller CVE bland ändringarna är det ett skäl att inte vänta.
Är ni osäkra på om en ändring gäller er, vänta en vecka. De flesta allvarliga fel i en ny version hittas och rättas under de första dagarna.
Uppdateringen steg för steg
Ta en säkerhetskopia
Kör ert backupskript för hand och kontrollera att filerna finns och inte är tomma. Har ni ingen skriptad kopia, gör åtminstone en databasdump och en kopia av volymerna enligt guiden Backup av en Docker-installation. Hoppa aldrig över det här steget. Det är det enda som gör resten ofarligt.
Skriv också ner vilken version som körs nu:
docker compose images
Kolumnen med taggen visar vad ni har. Behöver ni rulla tillbaka är det den ni går tillbaka till.
Hämta och starta den nya versionen
Har ni ändrat taggen i compose.yaml, spara filen. Har ni en tagg som bara anger huvudversion räcker det att hämta på nytt. Stå i mappen och kör:
docker compose pull
docker compose up -d
pull hämtar de nya avbilderna men rör inte det som körs. up -d ser att avbilden har ändrats, stoppar de gamla containrarna och skapar nya. Volymerna följer med oförändrade; det är därför datan ligger kvar.
Följ loggen
Direkt efter starten, titta på vad programmet gör:
docker compose logs -f app
Många program kör sina databasändringar, så kallade migreringar, automatiskt vid start. Nextclouds avbild upptäcker själv att versionen har ändrats och uppgraderar. Det kan ta några minuter på en stor installation, och under tiden kan webbsidan svara med fel. Vänta tills loggen lugnar sig. Avbryt inte med att starta om. Tryck Ctrl+C för att sluta följa loggen; programmet fortsätter att köra.
Kör eventuella migreringssteg för hand
Vissa program kräver att ni kör ett kommando efter uppdateringen. Står det i versionsanteckningarna, kör det med docker compose exec och tjänstens namn. Ett exempel från Nextcloud, som är bra att köra efter varje större uppdatering för att lägga till index som den nya versionen vill ha:
docker compose exec -u www-data app php occ db:add-missing-indices
Står det ingenting om manuella steg finns det heller inga. Hitta inte på egna.
Kontrollera och städa
Logga in och prova det ni använder mest: öppna en fil, skapa en post, skicka ett mejl från systemet om det ska kunna göra det. Kör docker compose ps och se att allt står som running, och inte som restarting.
När allt fungerar kan ni ta bort de gamla avbilderna som ligger kvar och tar plats:
docker image prune
Utan flaggor tar kommandot bara bort avbilder som inte längre har något namn, vilket är de gamla versionerna efter en uppdatering. Vänta gärna några dagar med det. Så länge den gamla avbilden finns kvar går en återgång snabbare.
Om något går fel: rulla tillbaka
Det finns två lägen, och det är viktigt att veta vilket ni är i.
Programmet startar inte, men databasen har inte hunnit ändras. Ändra tillbaka taggen i compose.yaml till den version ni skrev ner, och kör:
docker compose up -d
Det här fungerar när felet uppstår direkt vid start, innan någon migrering har körts.
Migreringen har körts, helt eller delvis. Då har databasen ändrats till ett format som den gamla versionen inte nödvändigtvis förstår, och det räcker inte att byta tillbaka taggen. Ni behöver läsa tillbaka säkerhetskopian:
docker compose down
Ändra tillbaka taggen i compose.yaml. En volym som redan har migrerats ska inte packas upp ovanpå, eftersom filer från den nya versionen då blir liggande kvar bland de gamla. Ta först en extra kopia av den (ifall ni vill felsöka senare), radera den och låt Docker skapa en tom:
docker volume rm nextcloud_db_data
docker compose create
Läs sedan tillbaka arkivet enligt avsnittet om att läsa tillbaka i guiden Backup av en Docker-installation, och starta med docker compose up -d. Gäller det bara databasen kan ni i stället läsa in dumpen, som ersätter innehållet i databasen i stället för filerna.
docker compose down utan flaggor tar bort containrarna men behåller volymerna. Lägg aldrig till -v i det här läget. Den flaggan raderar volymerna, och då är det bara säkerhetskopian som finns kvar.
Osäkra på vilket läge ni är i? Utgå från det andra. En återläsning tar längre tid, men den ger ett känt läge.
Uppdatera databasen till en ny huvudversion
Förr eller senare slutar databasversionen att få säkerhetsrättningar och behöver bytas. För Postgres ser det ut så här:
- Gör en dump med
pg_dumpenligt backupguiden, och kontrollera att filen inte är tom. - Stoppa allt med
docker compose down. - Byt taggen, till exempel från
postgres:16tillpostgres:17, och byt namn på databasens volym icompose.yamlså att den nya versionen startar med en tom volym. Den gamla ligger kvar orörd under sitt gamla namn. - Starta bara databasen med
docker compose up -d dboch vänta tills loggen säger att den tar emot anslutningar. - Läs in dumpen med
pg_restoreenligt backupguiden. - Starta resten med
docker compose up -d.
Låt den gamla volymen ligga kvar några veckor innan ni raderar den. Den är er väg tillbaka.
För MariaDB är det enklare. Byt taggen och starta. Om miljövariabeln MARIADB_AUTO_UPGRADE=1 är satt kör den officiella avbilden själv de uppgraderingssteg som systemtabellerna behöver, och sparar en kopia av dem i datavolymen innan. Det gör det svårare att gå tillbaka till en äldre version efteråt, så även här gäller: säkerhetskopia först.
Glöm inte Docker och operativsystemet
Programmen i containrarna är en sak; Docker och datorn under dem är en annan.
På Linux Mint och en VPS med Ubuntu kommer Docker från Dockers eget arkiv och uppdateras tillsammans med resten av systemet:
sudo apt update
sudo apt upgrade
Containrar med restart: unless-stopped startar igen av sig själva när Docker har startats om.
På Windows säger Docker Desktop till när en ny version finns. Installera den när ingen använder systemen, och kontrollera efteråt att containrarna har startat. Volymerna ligger kvar vid en vanlig uppdatering. De försvinner däremot om ni avinstallerar Docker Desktop eller återställer det till fabriksinställningar, så ta en säkerhetskopia innan ni gör något av det.
Så här vet ni att det funkade
docker compose imagesvisar den nya versionen.docker compose psvisar alla tjänster som running, inte restarting.- Loggen har slutat skriva felmeddelanden, och ni har loggat in och sett data som fanns före uppdateringen.
- Säkerhetskopian från före uppdateringen ligger kvar, med datum.
Vanliga fel
Containern startar om i en slinga. Läs docker compose logs app. Oftast står det att databasen har fel version, att en miljövariabel saknas eller att en migrering misslyckades. Leta efter samma fras i versionsanteckningarna.
"database files are incompatible with server". Postgres har bytt huvudversion under en befintlig volym. Byt tillbaka taggen till den gamla versionen, starta, och följ avsnittet om att uppdatera databasen ovan.
Nextcloud säger att uppgradering från den här versionen inte stöds. Ni har hoppat över en huvudversion. Sätt taggen till versionen närmast ovanför den ni hade, starta, vänta tills uppgraderingen är klar, och ta nästa steg därefter.
Webbsidan visar underhållsläge och kommer aldrig tillbaka. Migreringen har avbrutits. Läs loggen innan ni gör något annat. I värsta fall är det nu säkerhetskopian behövs.
docker compose pull hämtar ingenting nytt. Taggen ni har låst till har inte fått någon ny version. Det är inget fel. Vill ni till nästa huvudversion måste ni byta taggen själva.
Nästa steg
Gör uppdateringen till en återkommande punkt i kalendern, en gång i månaden räcker för de flesta. Samma dag som ni kontrollerar att säkerhetskopiorna fungerar, så blir det en rutin i stället för två.
Nås systemet från internet och saknar HTTPS är det nästa sak att ta. Guiden HTTPS med Caddy eller Traefik visar hur.