WhatsApp ejes af Meta, Signal kræver et telefonnummer, og selv en åben protokol som Matrix bruges i praksis oftest gennem servere, som andre driver og kontrollerer på dine vegne. Hvis du vil eje din egen krypterede chatinfrastruktur helt fra bunden, findes der en løsning, du selv kan drive: en Matrix-homeserver bygget på Synapse med Element som klient. Det kræver ingen abonnement til en tredjepart og ingen anden virksomheds servere. Til gengæld kræver det, at du selv sætter det op korrekt, holder det opdateret og forstår, hvordan federation fungerer. Denne guide tager dig gennem hele processen: fra valg af VPS til en fuldt krypteret, federeret chatserver med TLS, PostgreSQL og en reverse proxy foran. Du ender med et komplet, kørende projekt og en liste over de fejl, der oftest sender nybegyndere tilbage til trin et.
Hvorfor selvhoste krypteret chat i 2026?
Matrix er en åben protokol til realtidskommunikation, og Synapse er den mest udbredte serverimplementering af den. Ifølge Element selv er “Synapse is an open source Matrix homeserver implementation, written and maintained by Element” (Element på GitHub). Det centrale ord er “open source”: du kan læse koden, du kan køre den lokalt, og du kan lade den tale med resten af Matrix-netværket uden at bede nogen om lov.
Matrix.org Foundations årsrapport for 2025 opgjorde 1,15 millioner månedligt aktive brugere på den åbne federation. Det er ikke Signal- eller WhatsApp-tal, men det er heller ikke en dødsdømt niche-protokol. Fordelen ved at selvhoste frem for at bruge en gratis konto på en offentlig server er kontrol: du bestemmer, hvem der kan oprette konti, hvor lang tid beskeder opbevares, og om din server overhovedet skal federere med det åbne netværk. Element beskriver selv den samme logik for virksomhedskunder: “Element is a completely new type of messaging and collaboration which allows organisations to keep control and ownership of their messaging and collaboration data”, og videre at “This means they choose where, when and how to host” (Element, “Who Owns Your Conversations”).
For danske og nordiske brugere er argumentet ofte det samme, som driver interessen for hærdet Signal-brug eller selvhostede password managers: du vil ikke lægge følsom kommunikation hos en amerikansk skytjeneste, du ikke selv kontrollerer. En selvhostet Matrix-server løser det problem for chat, filer og, med lidt ekstra arbejde, tale og video.
Interessen er ikke kun teoretisk. Foreninger, mindre kommuner, IT-sikkerhedsfolk og teknisk interesserede familier i Danmark og resten af Norden efterspørger i stigende grad kommunikationsværktøjer, der ikke lægger beskeder hos en enkelt amerikansk platform. Det samme mønster ses i debatten om digital suverænitet i EU generelt, hvor både myndigheder og private brugere leder efter alternativer, de selv kan drive og revidere. En Matrix-server er ikke den letteste vej dertil sammenlignet med at downloade en app, men den er en af de få veje, der giver fuld kontrol over, hvor data fysisk ligger, hvem der har adgang til serveren, og hvor længe beskeder opbevares.
Hvad er Matrix, Synapse og Element helt konkret?
Tre begreber blandes ofte sammen, så lad os rydde op først. Matrix er selve protokollen og specifikationen, offentliggjort og vedligeholdt af Matrix.org Foundation: reglerne for, hvordan beskeder, rum og brugere synkroniseres mellem servere. Synapse er den mest anvendte homeserver-software, der implementerer protokollen. Element er klientapplikationen (web, desktop og mobil), som almindelige brugere rent faktisk skriver beskeder i.
Forskellen mellem protokol og software er vigtig at forstå, fordi den er selve pointen med Matrix. Modsat Signal og WhatsApp, hvor protokol og server er ét og samme lukkede system ejet af én virksomhed, er Matrix-specifikationen åben og offentligt dokumenteret på spec.matrix.org. Det betyder, at flere uafhængige teams kan bygge kompatible servere og klienter, og at ingen enkelt virksomhed kan lukke protokollen ned eller ændre vilkårene ensidigt for alle brugere på tværs af netværket.
I praksis mærker du det som slutbruger sådan: din konto lever på din server, ikke i en app-butik eller hos en enkelt udbyder. Mister du adgangen til Element-appen af en eller anden grund, kan du logge ind med en helt anden klient, der understøtter Matrix, og fortsætte, hvor du slap. Den fleksibilitet har en pris i kompleksitet, hvilket er præcis, hvad resten af denne guide handler om at håndtere.
Federation forklaret på fem linjer
Federation betyder, at din server kan tale med andre Matrix-servere, ligesom din mailserver kan sende post til en Gmail-adresse. En bruger på din server (@dig:dinserver.dk) kan chatte med en bruger på matrix.org uden at nogen af jer skifter tjeneste. Det er også her, den største beslutning ligger: du kan køre helt lukket, kun med interne brugere, eller åbent mod resten af netværket. Til et privat familie- eller virksomhedsmiljø vælger de fleste at lukke federation helt fra, i det mindste i starten.
Synapse eller Continuwuity?
Synapse er skrevet i Python og er den mest testede og dokumenterede implementering, hvilket er grunden til, at denne guide bruger den. Der findes alternativer skrevet i Rust, hvoraf Continuwuity er den mest aktive videreførelse af det tidligere Conduwuit-projekt. Continuwuity 0.5.8 blev udgivet 24. april 2026 ifølge projektets eget changelog, og softwaren bruger markant mindre RAM end Synapse ved samme brugerantal. Til gengæld har den færre funktioner og en mindre moden administrationsflade. Denne guide holder sig til Synapse, fordi den er bedst dokumenteret og har den bredeste kompatibilitet med bridges og administrationsværktøjer, men vend tilbage til afsnittet om avancerede tips, hvis du senere vil skifte.
Forudsætninger: dette skal du bruge før du starter
Du behøver ikke være systemadministrator til daglig, men du skal kunne bruge en terminal, redigere en YAML-fil uden at rode indrykningen til, og forstå, hvad et DNS-opslag er. Har du tidligere sat en WireGuard-server op eller konfigureret et TLS-certifikat manuelt, har du allerede de fleste af de nødvendige færdigheder. Har du ikke, er ingen af de enkelte trin svære i sig selv, men de kræver, at du følger rækkefølgen og ikke springer verifikationsskridtene over undervejs. Tabellen herunder viser, hvad du skal bruge, og hvorfor.
| Krav | Minimum / anbefaling | Hvorfor |
|---|---|---|
| Server (VPS) | 2 vCPU, 4 GB RAM, 40 GB SSD | Synapse er tung ved opstart og databasevækst, og 2 GB RAM er absolut bundgrænse |
| Styresystem | Ubuntu 24.04 LTS eller nyere | Bedst understøttet af Docker og de fleste guider |
| Docker | Nyeste stabile version | Isolerer Synapse, PostgreSQL og proxy i separate containere |
| Docker Compose | V2-pluginet (kommandoen docker compose) | Styrer hele stakken med én konfigurationsfil |
| Domæne | Eget domæne, du kontrollerer DNS for | Din Matrix-identitet (@bruger:domæne.dk) er bundet permanent til domænet |
| PostgreSQL | Version 16 eller 17 | Synapse kræver mindst version 11, men nye installationer bør vælge en nyere understøttet udgave |
| Reverse proxy | Caddy (nyeste stabile version) | Automatisk Let’s Encrypt-fornyelse uden manuel konfiguration |
Læg mærke til domæne-kravet: din server_name i Synapse-konfigurationen bliver en del af hver eneste brugers identitet og kan ikke ændres bagefter uden at genopbygge hele serveren. Tænk dig grundigt om, før du skriver den værdi ned.
Hvad koster det at drive din egen Matrix-server?
Prisen afhænger primært af, hvor mange brugere serveren skal betjene, og hvor meget medie- og filhistorik de genererer over tid. En lille installation til en husstand eller en håndfuld venner koster typisk det samme som en billig streamingtjeneste om måneden. En mellemstor installation til en forening eller lille virksomhed kræver mere RAM, fordi Synapse holder aktive forbindelser og cache i hukommelsen for hver samtidig bruger. Tabellen herunder giver et realistisk billede af, hvad du skal budgettere med.
| Størrelse | Antal brugere | Anbefalet VPS | Typisk månedspris |
|---|---|---|---|
| Lille (privat) | 1-10 aktive brugere | 2 vCPU, 4 GB RAM, 40 GB SSD | 5-10 EUR |
| Mellem (forening/lille firma) | 10-50 aktive brugere | 4 vCPU, 8 GB RAM, 80 GB SSD | 15-30 EUR |
| Stor (organisation med federation) | 50-300 aktive brugere | 8 vCPU, 16 GB RAM, 160+ GB SSD, separat databaseserver | 50-120 EUR |
Bemærk, at prisen stiger langsommere end brugerantallet i starten, men accelererer, hvis du tillader åben federation med resten af Matrix-netværket. Federation betyder, at din server løbende udveksler beskedhistorik og medier med tusindvis af andre servere, og det medie-caching alene kan æde diskplads hurtigere end antallet af dine egne brugere skulle tilsige.
Trin 1-2: Vælg server og sæt DNS op
Skaf en VPS med mindst de specifikationer, tabellen ovenfor viser. En europæisk udbyder er et fornuftigt valg, hvis dataopbevaring i EU er vigtig for dig, på samme måde som mange vælger europæiske alternativer, når de sætter en egen WireGuard VPN-server op.
Opret derefter to DNS-poster hos dit domæneudbyder:
- Et A- eller AAAA-opslag for
matrix.dinserver.dk, der peger på serverens IP-adresse. - Valgfrit, men anbefalet: et A-opslag for
element.dinserver.dk, hvis du vil have Element Web på et separat underdomæne.
Vent, til DNS-opslaget er slået igennem (typisk 5-30 minutter), før du går videre. Test det med dig matrix.dinserver.dk fra din egen maskine.
Trin 3: Installer Docker og Docker Compose
Log ind på serveren via SSH og installer Docker efter den officielle metode for din distribution. På en frisk Ubuntu-installation ser det typisk sådan ud:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
docker --version
docker compose version
Begge de sidste to kommandoer skal returnere et versionsnummer uden fejl. Hvis docker compose version fejler, mangler du sandsynligvis compose-pluginet og skal installere pakken docker-compose-plugin separat.
Trin 4: Byg mappestruktur og docker-compose.yml
Opret en projektmappe med separate undermapper til Synapse-data, PostgreSQL-data og Caddy-konfiguration. Adskillelsen gør backup og fejlfinding markant nemmere senere.
mkdir -p ~/matrix/{synapse-data,postgres-data,caddy-data,caddy-config}
cd ~/matrix
nano docker-compose.yml
Indsæt følgende i docker-compose.yml. Bemærk, at kun Caddy-containeren eksponerer porte direkte til internettet. Synapse og PostgreSQL taler kun sammen på det interne Docker-netværk.
services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: synapse
POSTGRES_PASSWORD: SKIFT_DENNE_ADGANGSKODE
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- matrix-internal
synapse:
image: matrixdotorg/synapse:latest
restart: unless-stopped
depends_on:
- postgres
volumes:
- ./synapse-data:/data
networks:
- matrix-internal
- matrix-public
caddy:
image: caddy:latest
restart: unless-stopped
ports:
- "443:443"
- "8448:8448"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy-data:/data
- ./caddy-config:/config
depends_on:
- synapse
networks:
- matrix-public
networks:
matrix-internal:
internal: true
matrix-public:
Skift adgangskoden i miljøvariablen med det samme, og noter den et sikkert sted, gerne i en selvhostet password manager. Brug aldrig latest-tagget i en produktionsserver i længden: fastlås til et konkret versionsnummer, så snart opsætningen kører stabilt, og opgradér bevidst efter at have læst release notes.
Trin 5: Generér og tilpas homeserver.yaml
Synapse kan selv generere en startkonfiguration. Kør containeren én gang med et genereringsflag:
docker run -it --rm \
-v ~/matrix/synapse-data:/data \
-e SYNAPSE_SERVER_NAME=matrix.dinserver.dk \
-e SYNAPSE_REPORT_STATS=no \
matrixdotorg/synapse:latest generate
Kommandoen opretter en homeserver.yaml og signeringsnøgler i synapse-data-mappen. Åbn filen og verificér mindst disse felter:
server_name: "matrix.dinserver.dk"
database:
name: psycopg2
args:
user: synapse
password: SKIFT_DENNE_ADGANGSKODE
database: synapse
host: postgres
port: 5432
cp_min: 5
cp_max: 10
registration_shared_secret: "generer-en-lang-tilfaeldig-streng-her"
enable_registration: false
Sæt enable_registration til false, medmindre du bevidst vil lade fremmede oprette konti på din server. Al brugeroprettelse foregår i stedet via kommandolinjeværktøjet med den delte hemmelige nøgle, du satte i registration_shared_secret.
Trin 6: Sæt PostgreSQL op som produktionsdatabase
Synapse leveres med SQLite som standard i test-scenarier, men det er ikke egnet til reel brug. SQLite låser hele databasen ved skrivning og bryder sammen, så snart mere end en håndfuld brugere er aktive samtidig. PostgreSQL skal derfor være databasen fra dag ét, ikke noget du migrerer til senere, når det bliver et problem.
Med docker-compose.yml fra trin 4 starter PostgreSQL automatisk, når du kører docker compose up -d. Bekræft, at databasen kører korrekt, og at collation-indstillingerne er sat rigtigt, før Synapse rører den. PostgreSQL-projektet udgiver løbende nye major-versioner, og valget mellem version 16 og 17 handler mest om, hvilken version din distributions pakkearkiv understøtter bedst i skrivende stund.
docker compose up -d postgres
docker compose logs postgres --tail=20
docker compose exec postgres psql -U synapse -c "SHOW server_version;"
Collation skal være C, som sat i POSTGRES_INITDB_ARGS ovenfor. Forkert collation opdages ofte først, når Synapse fejler med kryptiske databasefejl uger senere, og det kan ikke rettes uden at genskabe databasen fra bunden. Årsagen er, at PostgreSQL sorterer og sammenligner tekst forskelligt afhængigt af collation, og Synapses indekser forudsætter den simple, sprogneutrale C-sortering frem for en lokalitetsafhængig collation som da_DK eller en_US. Skifter du collation efter, at databasen allerede er fyldt med data, risikerer du subtile fejl i søgning og sortering, som er langt sværere at spore end en fejl, der rammer med det samme.
Trin 7-8: Reverse proxy og TLS med Caddy
Caddy henter og fornyer Let’s Encrypt-certifikater automatisk, hvilket gør den til det enkleste valg for en enkelt homeserver. Hvis du allerede driver en kompleks nginx-opsætning med mange virtuelle hosts, kan du bruge den i stedet, men Caddy kræver færre linjer konfiguration og færre steder at lave fejl, efter samme principper som beskrevet i vores gennemgang af gratis TLS-certifikater med Certbot.
Opret en Caddyfile i projektmappen:
matrix.dinserver.dk {
reverse_proxy synapse:8008
}
matrix.dinserver.dk:8448 {
reverse_proxy synapse:8008
}
Den første blok håndterer klienttrafik, almindelig HTTPS på port 443. Den anden blok håndterer federation-trafik på port 8448, som er den port, andre Matrix-servere som standard bruger til at finde din server. Genstart Caddy, når filen er gemt:
docker compose up -d caddy
docker compose logs caddy --tail=30
Log-outputtet bør vise, at Caddy har hentet et certifikat uden fejl. Hvis det fejler her, er årsagen næsten altid, at DNS-opslaget fra trin 2 endnu ikke er slået igennem, eller at port 80 og 443 ikke er åbne i din firewall.
Trin 9: Federation og .well-known delegation
Vil du undgå at eksponere port 8448 direkte, kan du i stedet bruge en .well-known-fil, så federation-trafik omdirigeres til standard-HTTPS-porten. Det kræver en lille JSON-fil, som Synapse selv kan servere, eller som du lægger i Caddyfilen:
matrix.dinserver.dk {
respond /.well-known/matrix/server `{"m.server": "matrix.dinserver.dk:443"}` 200 {
header Content-Type application/json
}
reverse_proxy synapse:8008
}
Test derefter federation med en offentlig federationstest-tjeneste, som viser certifikatkæde, DNS-opslag og well-known-svar samlet på én side. Kør testen, hver gang du ændrer domænekonfiguration, ikke kun ved den første opsætning.
Federation betyder også, at din server automatisk følger specifikationens regler for rum-versioner. Efter sikkerhedsopdateringen i august 2025 blev rum-version 12 den anbefalede standard for nye rum, fordi den retter de svagheder i den ældre state-resolution-logik, som lå til grund for hændelsen. Ældre rum, oprettet før opdateringen, kan opgraderes manuelt af en rumadministrator, men opgraderer sig ikke automatisk. Tjek derfor rum-versionen på dine vigtigste kanaler, hvis serveren har kørt i længere tid, i stedet for at antage, at den nyeste sikkerhed gælder alle steder.
Trin 10: Start Synapse og opret din første admin-bruger
Med database og proxy klar kan du starte hele stakken:
docker compose up -d
docker compose ps
docker compose logs synapse --tail=50
Når Synapse kører uden fejl i loggen, opretter du din første administratorkonto med kommandolinjeværktøjet register_new_matrix_user, som følger med billedet:
docker compose exec synapse register_new_matrix_user \
-c /data/homeserver.yaml \
http://localhost:8008
Værktøjet spørger interaktivt om brugernavn, adgangskode og om kontoen skal have administratorrettigheder. Svar ja til admin på din første konto, ellers kan du ikke administrere serveren bagefter.
Trin 11: Installer og forbind Element Web
Element Web er den mest brugte klient til Matrix, og den kan køre som en separat statisk container. Tilføj den til docker-compose.yml:
element:
image: vectorim/element-web:latest
restart: unless-stopped
volumes:
- ./element-config.json:/app/config.json
networks:
- matrix-public
Opret element-config.json med et minimalt indhold, der peger klienten på din homeserver:
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.dinserver.dk",
"server_name": "dinserver.dk"
}
},
"brand": "Element"
}
Tilføj en tilsvarende blok i Caddyfilen for element.dinserver.dk, der peger på element-containeren, og genstart stakken. Åbn derefter element.dinserver.dk i din browser og log ind med den admin-konto, du oprettede i forrige trin.
Skal serveren også bruges fra mobilen, installerer du Element fra App Store eller Google Play som en helt almindelig app. Ved første login vælger du “Andet” i stedet for de foreslåede offentlige servere, og indtaster derefter dit eget domæne, matrix.dinserver.dk, som homeserver-adresse. Herefter fungerer login med samme brugernavn og adgangskode, som du brugte på webklienten, og appen synkroniserer automatisk beskedhistorik og krypteringsnøgler til den nye enhed, forudsat at du bekræfter enhedsverifikationen beskrevet i næste trin.
Trin 12: Verificér end-to-end-kryptering
Selve serveropsætningen giver dig transportkryptering via TLS, men den ende-til-ende-kryptering, der beskytter selve beskederne, er noget klienten håndterer via Matrix’ Olm/Megolm-protokoller. Element beskriver princippet sådan: “End-to-end encryption means your messages and files are encrypted before they leave your device, and stay encrypted until they reach the other participants’ devices” (Element hjælpecenter).
Opret et testrum, inviter en anden konto (eller en ven med en konto på en anden Matrix-server), og bekræft, at rummet er markeret som krypteret med et hængelås-ikon i Element. Gennemfør derefter en enhedsverifikation mellem to enheder: Element sammenligner en kort nøglestreng eller emoji-sekvens, som begge parter skal bekræfte er ens. Uden den verifikation kan kryptering stadig modvirke aflytning på nettet, men den beskytter ikke mod, at en ukendt enhed sniger sig ind på en konto.
Trin 13-14: Backup, hærdning og GDPR-compliance
En chatserver uden backup er en tidsindstillet fejl. Tag som minimum daglig backup af to ting: PostgreSQL-databasen og mediemappen i synapse-data. Et enkelt script kan klare begge dele:
#!/bin/bash
set -e
DATO=$(date -I)
BACKUP_DIR=~/matrix-backups/$DATO
mkdir -p "$BACKUP_DIR"
docker compose exec -T postgres pg_dump -U synapse synapse | gzip > "$BACKUP_DIR/synapse-db.sql.gz"
tar -czf "$BACKUP_DIR/synapse-media.tar.gz" -C ~/matrix/synapse-data media_store
find ~/matrix-backups -maxdepth 1 -mtime +14 -exec rm -rf {} \;
Sæt scriptet i cron til at køre hver nat, og send de komprimerede filer et andet sted hen end selve serveren, for eksempel til objektlager i et andet datacenter. Krypter backup-filerne, før de forlader serveren, hvis de skal ligge hos en ekstern lagringsudbyder, så en kompromitteret lagerkonto ikke i sig selv afslører hele din beskedhistorik. Test gendannelsen mindst én gang: en backup, du aldrig har prøvet at genskabe fra, er ikke en verificeret backup, den er blot en fil, du håber virker.
Gendannelse foregår i praksis ved at stoppe Synapse-containeren, gendanne PostgreSQL-dumpet til en tom database, pakke media_store-arkivet tilbage på plads og derefter starte Synapse igen. Øv processen på en separat testserver, mens alt kører normalt, i stedet for at improvisere den for første gang midt i en reel nedbrudssituation.
På hærdningssiden bør du som minimum begrænse admin API’et til localhost eller et VPN, holde Synapse opdateret straks ved sikkerhedsudgivelser, og sætte en rimelig retention-politik, hvis GDPR-krav om dataminimering gælder for din organisation. Matrix-projektet gennemførte i august 2025 en koordineret sikkerhedsopdatering på tværs af større homeserver-implementeringer, herunder rettelser relateret til protokollens state-resolution-logik og en efterfølgende specifikationsopdatering til Matrix 1.16 med rum-version 12. En separat sårbarhed gjorde det muligt for en ondsindet bruger at sende specialdesignede beskeder til Synapse-instanser før version 1.105.1 og derved udløse unødvendigt højt CPU-forbrug og databasevækst. Konsekvensen er enkel: kør ikke en gammel Synapse-version på en offentligt federeret server, og opdatér straks ved sikkerhedsudgivelser fra projektet.
GDPR og opbevaringspligt: hvad en dansk administrator skal vide
Driver du en Matrix-server for en forening, en virksomhed eller en gruppe, der ikke kun er din egen husstand, bliver du dataansvarlig i GDPR-forstand for de personoplysninger, brugerne udveksler. Det betyder ikke, at selvhosting er farligt, men det betyder, at du skal tage nogle beslutninger bevidst i stedet for at lade dem være standardindstillinger, du aldrig kiggede på.
Tre punkter er særligt relevante. For det første: sæt en eksplicit retention-politik for, hvor lang tid beskeder og medier opbevares, i stedet for at lade dem ligge for evigt som standard. For det andet: dokumentér, hvilke tredjeparter der har adgang til data, hvis du bruger bridges til Discord, Telegram eller andre tjenester, fordi hver bridge reelt er endnu en aktør, der ser dine brugeres beskeder. For det tredje: hvis du tillader federation, forlader nogle beskeder din egen infrastruktur og lander på andre servere, du ikke kontrollerer. Det svarer juridisk til at sende almindelig e-mail og bør beskrives tydeligt over for dine brugere, ligesom princippet også gælder, når man vurderer forskellen mellem Signal og Matrix som kommunikationsplatform for en organisation.
Ingen af disse punkter kræver, at du opgiver selvhosting. De kræver bare, at du behandler serveren som den dataansvarlige infrastruktur, den faktisk er, fremfor et teknisk fritidsprojekt uden konsekvenser. Skriv beslutningerne ned et sted, du kan finde igen, for eksempel i en kort intern note om retention-politik og bridge-brug, så du ikke skal genopfinde svarene, næste gang nogen spørger, hvor længe deres beskeder egentlig gemmes.
Overvågning: hold øje med serverens sundhedstilstand
En Matrix-server, der bare kører, uden nogen form for overvågning, er en server, hvor det første tegn på problemer er en klage fra en bruger. Tre metrikker er værd at holde øje med fra dag ét: diskforbrug i synapse-data/media_store, som vokser hurtigst ved åben federation, antallet af aktive databaseforbindelser, som kan afsløre en connection-pool, der er sat for lavt, og containernes hukommelsesforbrug over tid, som ofte stiger gradvist, hvis der er en lækage i en bridge eller et plugin.
docker stats --no-stream
du -sh ~/matrix/synapse-data/media_store
docker compose exec postgres psql -U synapse -c \
"SELECT count(*) FROM pg_stat_activity;"
Kør disse tre kommandoer ugentligt i starten, indtil du har en fornemmelse for, hvad normal drift ser ud som på præcis din server. Herfra kan du sætte simple alarmer op, for eksempel et cron-job, der sender dig en besked, hvis diskforbruget krydser en given grænse.
Sådan undgår du de mest almindelige faldgruber
De fleste, der opgiver en Matrix-selvhosting halvvejs, rammer en af disse fem fejl. Ingen af dem er svære at rette, hvis du opdager dem tidligt, men flere af dem bliver markant dyrere at rette, jo længere tid serveren har kørt med fejlen aktiv.
- At blive på SQLite for længe. Det virker fint med to testbrugere og bryder sammen, den dag et rigtigt rum med ti aktive brugere synkroniserer historik.
- At vælge et forkert server_name i første forsøg. Feltet kan reelt ikke ændres uden at genopbygge hele installationen og miste alle eksisterende bruger-id’er.
- At glemme .well-known-delegationen eller port 8448. Serveren virker fint til lokale brugere, men kan ikke federere, fordi eksterne servere ikke kan finde den.
- At bruge
latest-tags i produktion uden version-pinning. En automatisk opdatering en tilfældig nat kan introducere en breaking change, du først opdager, når brugerne klager. - At springe backup-testen over. Et pg_dump-script, der aldrig er blevet gendannet, er ikke en sikkerhedsforanstaltning, det er et håb.
Fejlfinding: typiske problemer og løsninger
Tabellen herunder samler de fejl, du med størst sandsynlighed rammer i løbet af de første uger. De fleste kan diagnosticeres med samme tre kommandoer: docker compose logs, en manuel curl mod den relevante endpoint, og et kig i homeserver.yaml efter tastefejl. Bliv ikke fristet til at genstarte hele stakken blindt, før du har læst loggen, for den peger næsten altid direkte på årsagen.
| Problem | Sandsynlig årsag | Løsning |
|---|---|---|
| 502 Bad Gateway fra Caddy | Synapse-containeren er ikke oppe endnu, eller porten er forkert | Kør docker compose logs synapse og bekræft, at containeren lytter på 8008 |
| Federationstest fejler med “well-known ikke fundet” | Ingen svar fra .well-known/matrix/server, eller forkert Content-Type | Bekræft JSON-svaret manuelt med curl, og tjek at Content-Type er application/json |
| Containeren crasher straks ved opstart | Forkert indrykning eller syntaksfejl i homeserver.yaml | Kør docker compose logs synapse, YAML-fejl står altid øverst i loggen |
| Uventet høj CPU-belastning eller databasevækst | Gammel Synapse-version ramt af kendte protokolfejl | Opdatér til nyeste stabile version og genstart |
| Kan ikke registrere ny bruger | Forkert registration_shared_secret mellem konfiguration og kommando | Bekræft, at værdien i homeserver.yaml matcher nøjagtigt det, du bruger i register_new_matrix_user |
| Element viser “kan ikke oprette forbindelse til server” | Forkert base_url i element-config.json | Bekræft, at base_url peger på https://matrix.dinserver.dk uden afsluttende skråstreg |
| TLS-certifikat fornyes ikke | Port 80 blokeret af firewall under fornyelsesforsøg | Åbn port 80 og 443 permanent, ikke kun ved første opsætning |
| “too many connections” fra PostgreSQL | For lav max_connections i forhold til Synapses connection pool | Hæv cp_max i homeserver.yaml eller max_connections i PostgreSQL |
| Filupload fejler for store filer | Standard max_upload_size er for lav til dine behov | Hæv max_upload_size i homeserver.yaml og genstart Synapse |
| Federation virker lokalt, men ikke udefra | Firewall eller udbyder blokerer indgående port 8448 | Bekræft med en ekstern federationstest og åbn porten i cloud-firewallen, ikke kun i serverens egen |
Avancerede tips: bridges, TURN-server og alternative servere
Når grundopsætningen kører stabilt, er der tre naturlige næste skridt. Det første er bridges: værktøjer, der forbinder din Matrix-server med andre netværk som Discord, Telegram eller SMS, så du kan samle flere kanaler i én klient. Hver bridge kører typisk som sin egen container ved siden af Synapse og kræver sin egen adgangstoken til det eksterne netværk, så tilføj kun de bridges, du reelt har brug for, i stedet for at aktivere dem alle på forhånd. Det andet er en TURN-server til tale og video. Element Call kan fungere direkte på Element X, men NAT-traversal for stemme- og videoopkald kræver typisk en separat coturn-container, fordi HTTPS alene ikke løser den slags forbindelsesproblemer, når begge samtaleparter sidder bag hver sin router uden en offentlig IP-adresse.
Det tredje skridt er at overveje Continuwuity som erstatning for Synapse, hvis din server primært kører på begrænset hardware. Continuwuity er skrevet i Rust og bruger typisk markant mindre RAM end Synapse ved samme antal brugere, og kan installeres via Docker, NixOS eller traditionelle pakker. Modenheden er stadig lavere end Synapses, så vurder det som et skifte til en mindre, mere sparsommelig server snarere end en universel opgradering.
Overvej også, hvordan din opsætning forholder sig til andre dele af din privatlivsstack. Har du allerede sat en WireGuard-server op, kan du lade admin API’et for Synapse kun være tilgængeligt over VPN-tunnelen i stedet for det åbne internet. Det fjerner en hel klasse af angrebsflader uden at gå på kompromis med, at almindelige brugere stadig kan chatte normalt udefra.
Et sidste, ofte overset punkt handler om enheder, ikke servere. Cross-signing i Element lader dig verificere alle dine egne enheder én gang og derefter stole på dem automatisk fremover, i stedet for at bekræfte hver ny samtalepartner manuelt hver gang. Sæt en 4-cifret sikkerhedskode op under kryptering i Element-indstillinger, og gem den et sikkert sted uden for din telefon. Mister du adgangen til alle dine enheder samtidig, er den kode den eneste vej til at gendanne krypteringsnøglerne til din beskedhistorik, fordi hverken du eller Element gemmer en kopi af selve nøglerne på serveren.
Sikkerhedstjekliste efter installation
Før du regner opsætningen for færdig og begynder at invitere rigtige brugere, bør du gå listen herunder igennem én gang fra ende til anden. Hvert punkt tager få minutter, men samlet lukker de de mest almindelige huller i en fersk installation.
- Admin API’et på Synapse er ikke tilgængeligt fra det åbne internet, kun fra localhost eller et internt netværk.
enable_registrationstår til false, medmindre du bevidst driver en offentlig server med åben tilmelding.- PostgreSQL-porten (5432) er ikke eksponeret i docker-compose.yml, kun tilgængelig internt via
matrix-internal-netværket. - Alle container-images er pinnet til et konkret versionsnummer, ikke
latest. - Et backup-script kører automatisk hver nat, og du har testet gendannelsen mindst én gang.
- Federationstesten viser grøn status uden advarsler, hvis du har valgt at tillade federation.
- Du har noteret dig, hvornår Synapse-projektet typisk udsender sikkerhedsopdateringer, og har en plan for at opdatere hurtigt.
Komplet arbejdende projekt: den samlede opsætning
Her er hele projektet samlet, så du kan kopiere det direkte og tilpasse domænenavn og adgangskoder. Mappestrukturen er:
matrix/
├── docker-compose.yml
├── Caddyfile
├── element-config.json
├── backup.sh
├── synapse-data/
│ └── homeserver.yaml
├── postgres-data/
├── caddy-data/
└── caddy-config/
# docker-compose.yml (samlet version)
services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: synapse
POSTGRES_PASSWORD: SKIFT_DENNE_ADGANGSKODE
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks: [matrix-internal]
synapse:
image: matrixdotorg/synapse:latest
restart: unless-stopped
depends_on: [postgres]
volumes:
- ./synapse-data:/data
networks: [matrix-internal, matrix-public]
element:
image: vectorim/element-web:latest
restart: unless-stopped
volumes:
- ./element-config.json:/app/config.json
networks: [matrix-public]
caddy:
image: caddy:latest
restart: unless-stopped
ports:
- "443:443"
- "8448:8448"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy-data:/data
- ./caddy-config:/config
depends_on: [synapse, element]
networks: [matrix-public]
networks:
matrix-internal:
internal: true
matrix-public:
Med disse filer på plads er hele opstartssekvensen tre kommandoer: generér homeserver.yaml, kør docker compose up -d, og opret din admin-bruger med register_new_matrix_user. Herfra er serveren din, uden løbende licensbetaling og uden en tredjeparts vilkår mellem dig og dine beskeder.
Ofte stillede spørgsmål
Er det gratis at selvhoste en Matrix-server?
Softwaren er gratis og open source. Den eneste faste udgift er en VPS, typisk fra omkring 5-10 euro om måneden afhængigt af udbyder og specifikationer.
Skal jeg tillade federation, eller kan jeg køre helt lukket?
Begge dele er understøttet. Sæt enable_registration til false, og undlad federation-konfigurationen, hvis serveren kun skal bruges internt af dig og nære kontakter.
Er Matrix lige så sikkert som Signal?
Kryptografisk bruger begge stærke, moderne protokoller til ende-til-ende-kryptering. Forskellen ligger i, at Matrix er decentraliseret og federeret, mens Signal kører på én central infrastruktur. Vil du sammenligne de to i dybden, har vi en separat gennemgang af Signal versus Matrix.
Kan jeg migrere fra Synapse til Continuwuity senere?
Der findes ingen officiel, garanteret migreringssti mellem de to implementeringer i dag. Betragt valget som en beslutning, du tager tidligt, ikke noget du flytter frem og tilbage mellem.
Virker det på mobilen?
Ja. Element findes til både iOS og Android og forbinder til din server på samme måde som webklienten, blot med din egen server_name i stedet for matrix.org.
Skal jeg have en fast IP-adresse?
Ikke nødvendigvis, men DNS-opslaget skal pege på den IP-adresse, serveren aktuelt har. En dynamisk IP kræver enten et opdateringsscript til DNS eller en udbyder med statisk IP inkluderet.
Hvad sker der, hvis serveren går ned?
Dine brugere kan ikke sende eller modtage beskeder, mens serveren er nede, men beskeder, der allerede er leveret til andre servere via federation, forbliver tilgængelige der. Det er endnu en grund til at have en testet backup klar.
Kan jeg køre flere domæner på samme server?
Ja, men hvert domæne kræver sin egen Synapse-instans eller en mere avanceret multi-tenant opsætning, da server_name er bundet én til én med en given Synapse-proces. Den enkleste løsning er at køre flere docker-compose-projekter side om side på samme VPS, hver med sit eget sæt containere og sin egen database, og lade Caddy dirigere trafik til den rigtige instans baseret på domænenavnet.
Hvor lang tid tager hele opsætningen i praksis?
Regn med omkring halvanden time første gang, hvis du følger trinene i denne guide uden at støde ind i de faldgruber, listen ovenfor beskriver. Størstedelen af tiden går med at vente på DNS-opslag og TLS-certifikater, ikke med selve konfigurationsarbejdet. Anden gang, du sætter en server op, typisk på en ny maskine eller for en anden organisation, tager det under en halv time, fordi filerne fra dette projekt kan genbruges direkte.




