Memos für Notizen selbst hosten
Folge dem auf deinem eigenen Server. Kostenlos starten, keine Karte nötig
Die meisten Notiz-Apps, die etwas taugen, verlangen irgendwann eine monatliche Gebühr, nur damit du deine eigenen Notizen nutzen kannst, oder sie sperren deine Daten in ein Format, das nur ihre eigene App lesen kann. Memos ist eine kleine, Open-Source-Alternative: ein einzelnes Go-Binary mit eingebetteter SQLite-Datenbank, gebaut für schnelle Notizen, Listen und eine persönliche Wissensdatenbank, die du auf Hardware betreibst, die du selbst kontrollierst. Am Ende dieser Anleitung läuft deine eigene Memos-Instanz auf einem 6-Dollar-Server pro Monat, erreichbar über HTTPS auf deiner eigenen Domain, mit einer Backup-Routine und einem Upgrade-Pfad, der dich nicht überrascht.
Was du brauchst
- Einen Server. DigitalOceans Basic Droplet für 6,00 $/Monat liefert 1 vCPU, 1 GB RAM und 25 GB SSD, was für Memos und einen Reverse Proxy zusammen auf einer einzigen Box reichlich ist. Memos ist ein schlankes Go-Binary mit SQLite im Hintergrund, kein Stapel aus mehreren Diensten, also ist das mehr Spielraum, als es eigentlich braucht. Jeder Ubuntu-24.04-VPS eines anderen Anbieters funktioniert genauso.
- Einen Domainnamen (oder eine Subdomain einer Domain, die du bereits besitzt), mit Zugriff auf die DNS-Einstellungen.
- Docker und das Docker-Compose-Plugin auf dem Server installiert (Schritt 2).
- Ein Terminal und SSH-Zugriff auf den Server.
Schritt 1: Server erstellen und eine Domain darauf zeigen lassen
Starte einen Ubuntu-24.04-Droplet im 6-Dollar-Basic-Plan von DigitalOcean (1 vCPU, 1 GB RAM, 25 GB SSD). Notiere die öffentliche IP-Adresse.
Füge in den DNS-Einstellungen deiner Domain einen A-Eintrag hinzu, der eine Subdomain, zum Beispiel memos.deinedomain.com, auf diese IP zeigt:
Type: A
Name: memos
Value: <IP deines Servers>
TTL: 300
Die DNS-Propagierung kann wenige Minuten bis einige Stunden dauern. Bevor du weitermachst, solltest du mit dig memos.deinedomain.com +short die IP deines Servers zurückbekommen, da die nächsten Schritte davon abhängen.
Schritt 2: Docker installieren
Verbinde dich per SSH mit dem Server und installiere Docker Engine samt Compose-Plugin:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
Melde dich ab und wieder an, damit die Gruppenänderung wirksam wird, und prüfe dann, ob beide Teile vorhanden sind:
docker --version
docker compose version
Du solltest eine Docker- und eine Compose-Version angezeigt bekommen, ohne “command not found”-Fehler.
Schritt 3: Projektverzeichnis anlegen
Memos braucht im Gegensatz zu manchen anderen selbst gehosteten Apps keinen vorab generierten Verschlüsselungsschlüssel oder sonstige Geheimnisse. Das Einzige, was es sich lohnt, außerhalb der Compose-Datei zu halten, ist die Domain, damit Caddy sie aufgreifen kann:
mkdir -p ~/memos && cd ~/memos
Erstelle .env mit deiner Domain:
# .env
DOMAIN=memos.deinedomain.com
Das ist die gesamte Geheimnis-Verwaltung für dieses Setup.
Schritt 4: Docker-Compose-Datei schreiben
Memos kommt standardmäßig mit einer eingebetteten SQLite-Datenbank, was die dokumentierte, offiziell unterstützte Art ist, es für persönliche Nutzung oder kleine Teams zu betreiben, kein Notbehelf, den man irgendwann hinter sich lassen soll. Es gibt hier keinen separaten Datenbank-Container, den man betreiben oder synchron halten müsste.
Erstelle docker-compose.yml:
services:
memos:
image: neosmemo/memos:0.31.0
restart: unless-stopped
volumes:
- memos_data:/var/opt/memos
networks:
- memos-net
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- DOMAIN=${DOMAIN}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- memos
networks:
- memos-net
networks:
memos-net:
volumes:
memos_data:
caddy_data:
caddy_config:
Ein paar Entscheidungen sind eine Erklärung wert:
- Das Image ist auf
neosmemo/memos:0.31.0festgepinnt statt auf den schwimmendenstable-Tag. Memos benennt seine ReleasesYY.MM.N(Release Candidates alsYY.MM.N-rc.K), undstablezeigt immer auf das jeweils neueste davon, was praktisch ist, aber bedeutet, dass ein einfachesdocker compose pulldich auf ein anderes Release verschieben könnte, ohne dass du das bewusst entschieden hast.0.31.0ist genau das Release, auf dasstableheute zeigt; es festzupinnen heißt, dass du bewusst upgradest, nach deinem eigenen Zeitplan, siehe Schritt 8. /var/opt/memosist der einzige Pfad im Container, an dem Memos alles ablegt: seine SQLite-Datenbank und alle hochgeladenen Dateien. Ein benanntes Volume, das dort gemountet ist, ist die gesamte Datenhaltung dieser App, weshalb der Backup-Schritt später auch so kurz ausfällt.- Nur Caddy veröffentlicht Ports zum Host. Memos selbst ist nur im internen Docker-Netzwerk erreichbar, nie direkt aus dem Internet.
Prüfe vor dem Weitermachen, dass die Datei sich korrekt parsen lässt:
docker compose config
Das sollte die vollständig aufgelöste Konfiguration ohne Fehler ausgeben.
Schritt 5: Caddyfile schreiben und alles starten
Caddy besorgt das TLS-Zertifikat automatisch von Let’s Encrypt, solange DNS bereits auf den Server zeigt und die Ports 80 und 443 aus dem Internet erreichbar sind. Erstelle Caddyfile im selben Verzeichnis:
{$DOMAIN} {
reverse_proxy memos:5230
}
Starte den Stack:
docker compose up -d
Beobachte den Start und prüfe, ob Caddy tatsächlich ein Zertifikat bekommen hat:
docker compose logs -f caddy
Du solltest eine Zeile sehen, die ein für deine Domain erhaltenes Zertifikat erwähnt, dann sollte der Besuch von https://memos.deinedomain.com im Browser Memos mit gültigem Schlosssymbol laden, ohne Zertifikatswarnung.
Schritt 6: Ersteinrichtung
Memos verlangt keine Registrierung irgendwo oder die Eingabe eines Lizenzschlüssels. Beim ersten Besuch deiner Instanz zeigt sie direkt ein Formular zum Anlegen des ersten Kontos, und dieses Konto wird zum Host der Instanz mit Admin-Rechten darüber. Erstelle es jetzt, mit einem echten Passwort, denn wer vor dir die Instanz erreicht, könnte sonst dieses erste Konto stattdessen für sich beanspruchen.
Schritt 7: Daten-Volume sichern
Alles, was Memos ablegt, seine Datenbank und alle hochgeladenen Dateien, liegt unter dem einzigen Pfad /var/opt/memos im Container, also dem benannten Volume memos_data. Dieses eine Volume zu sichern ist die gesamte Backup-Geschichte dieser App:
docker run --rm -v memos_memos_data:/data -v $(pwd):/backup alpine \
tar czf /backup/memos-data-backup-$(date +%F).tar.gz -C /data .
Lege das in einen Cronjob und kopiere das Ergebnis irgendwohin, das nicht dieser Server ist, einen Object-Storage-Bucket, eine andere Maschine, überallhin, nur nicht auf diesen Droplet. Ein Backup, das nur auf dem Server liegt, den es sichern soll, überlebt genau den Ausfall nicht, der einen Server tatsächlich zerstört.
Schritt 8: Memos upgraden
Prüfe die Version, die du derzeit betreibst, lies die Release-Notes von Memos für alles zwischen dieser Version und der, zu der du wechseln willst, und ändere dann den Tag in docker-compose.yml, sobald du dich zum Wechsel entschieden hast, zum Beispiel:
image: neosmemo/memos:<neue-version>
Ziehe und starte nur diesen Dienst neu:
docker compose pull memos
docker compose up -d memos
Prüfe die Logs auf einen sauberen Start:
docker compose logs -f memos
Memos sollte ohne Fehler starten, und deine bisherigen Notizen sollten noch da sein, wenn du dich wieder einloggst. Dein Volume-Backup aus Schritt 7 ist der Weg zurück, falls etwas nicht stimmt.
Die Abkürzung: mit Railyard
Alles oben Beschriebene, der einzelne Memos-Container mit einem persistenten Daten-Volume und bereits fertig eingerichtetem HTTPS, gibt es auch als Ein-Klick-Template:
https://app.railyard.run/deploy?template=memos
Das ist dieselbe Ein-Container-Struktur wie beim manuellen Setup dieser Anleitung: kein Postgres-Add-on, kein separater Datenbankdienst, Memos’ eigenes eingebettetes SQLite-Backend erledigt genau denselben Job wie hier. Das persistente Volume und HTTPS sind bereits für dich eingerichtet.
Wenn du lieber erst allgemein mit Railyard anfangen möchtest, bevor du dich konkret für Memos entscheidest, deckt der Quickstart die Grundlagen ab, und Datenbanken und Backups erklärt, wie Backups über alle Templates hinweg funktionieren, nicht nur bei diesem. Deploy-Button erklärt das ?template=-Linkformat selbst, falls du einen Link anderswo einbinden willst.
Railyards Free-Plan deckt einen Server plus einen Datenbankserver und 3 Apps ab, ohne Kreditkarte. Pro kostet 19 $/Monat pro Team, und Team kostet 49 $/Monat pro Team, für größere Limits und mehr Mitarbeiter.
Troubleshooting
Caddy bekommt nie ein Zertifikat, oder der Browser zeigt eine Zertifikatswarnung. Das liegt fast immer an DNS, nicht an Caddy. Führe dig memos.deinedomain.com +short auf deiner eigenen Maschine aus und prüfe, ob die IP deines Servers zurückkommt, nicht eine alte und nicht nichts. Let’s Encrypt braucht für die anfängliche Validierung auch Port 80 erreichbar aus dem Internet, also prüfe, ob die Firewall oder Security Group deines Cloud-Anbieters eingehenden Verkehr auf 80 und 443 erlaubt, nicht nur 443.
docker compose up schlägt fehl mit “port is already allocated”. Etwas anderes auf der Box ist schon an 80 oder 443 gebunden, häufig eine standardmäßig installierte Nginx- oder Apache-Instanz, die mit manchen Basis-Images mitgeliefert wird. Finde es mit sudo ss -tlnp | grep -E ':80|:443' und stoppe diesen Dienst.
Notizen scheinen nach einem Neustart zu verschwinden. Das bedeutet meist, dass ein Host-Verzeichnis statt eines benannten Docker-Volumes für /var/opt/memos gebunden wurde, und irgendetwas an diesem Pfad, Besitzrechten oder einem unabhängigen Container, der ihn wiederverwendet, hat die Daten woanders abgelegt, als du denkst. Benannte Volumes, wie in der Compose-Datei oben verwendet, vermeiden das, weil Docker sie unabhängig vom Host-Dateisystem konsistent verwaltet.
Der Container startet und beendet sich sofort wieder. Prüfe zuerst docker compose logs memos auf den tatsächlichen Fehler. Ein falscher oder fehlender Mount für /var/opt/memos, oder ein Volume mit Berechtigungsproblemen aus einer früheren manuellen Änderung, ist die übliche Ursache. Das Volume sauber neu anzulegen und, wenn echte Daten drauf waren, aus einem Backup wiederherzustellen, ist der schnellste Fix.
FAQ
Brauche ich Postgres oder MySQL statt SQLite für ein größeres Team? Nein. Memos’ eingebettetes SQLite-Backend ist der dokumentierte Standard und das, was diese Anleitung verwendet. Es ist für persönliche Nutzung oder ein kleines Team gebaut, und an diesem Setup ändert sich nichts, wenn dein Team innerhalb dieses Rahmens wächst. Falls du etwas betreibst, das groß genug ist, dass SQLites Single-Writer-Modell zu einem echten Engpass wird, ist das eine andere Größenordnung an Deployment, als diese Anleitung abdeckt.
Kann ich das ohne Domain betreiben, nur mit der IP des Servers? Caddys automatisches HTTPS braucht eine echte Domain; Let’s Encrypt stellt keine Zertifikate für bloße IP-Adressen aus. Du kannst Memos über einfaches HTTP auf einer IP zum schnellen Testen erreichen, indem du den Browser direkt auf Port 5230 des Servers richtest, aber verlass dich nicht darauf für irgendetwas, das du dauerhaft nutzen willst.
Was kostet das tatsächlich im Betrieb? Der Server kostet 6 $/Monat. Memos selbst ist kostenlose, Open-Source-Software, du zahlst also nur für die Box, auf der es läuft, sonst nichts.
Was genau wird in diesem einen Volume gesichert? Alles. Memos’ SQLite-Datenbank, die jede Notiz, jeden Tag und jede Einstellung enthält, und alle über die App hochgeladenen Dateien liegen unter /var/opt/memos. Es gibt keinen zweiten Datenspeicher, den man sich merken müsste, weshalb Schritt 7 so kurz ausfällt, wie er ist.
Ist Railyards Template die gleiche Architektur wie dieses manuelle Setup? Ja. Beide betreiben einen einzelnen Memos-Container gegen seine eigene eingebettete SQLite-Datenbank, ohne Postgres- oder MySQL-Add-on, und beide sichern dieses eine Volume persistent. Railyards Template nutzt den schwimmenden stable-Tag statt einer festgepinnten Version, da ein verwaltetes Deployment den Upgrade-Pfad für dich erledigt.
Beide Wege führen zum gleichen Ergebnis: eine Notiz-App ohne Abo, deine Daten an einem Ort, den du kontrollierst, und eine Serverrechnung, die sich nicht ändert, egal wie viele Notizen du schreibst.
Warum Leute sich dafür Railyard entscheiden
- Dein eigenes Cloud-Konto. Deploye auf DigitalOcean, Hetzner, Vultr, AWS, OVHcloud oder jedem Linux-Server per SSH, direkt von deinem Anbieter abgerechnet, ohne Aufschlag.
- Ein fester Preis pro Team. Free ist für immer kostenlos: ein Server plus ein Datenbankserver, drei Apps, keine Karte. Pro kostet 19 $ im Monat für bis zu fünf Server und unbegrenzte Apps. Team kostet 49 $ im Monat mit unbegrenzten Servern. Keine Kosten pro App, pro Deployment, pro Sitz oder pro Gigabyte.
- Templates mit einem Klick. Deploye Open-Source-Apps, wie Datenbanken, Analytics und Dev-Tools, mit einem Klick auf deinem eigenen Server.
- Verwaltete Datenbanken. Postgres, MySQL und Redis mit geplanten, wiederherstellungsgeprüften Backups und Point-in-Time-Recovery.
- Push-to-Deploy. Deploye von GitHub, GitLab oder der CLI, mit automatischem HTTPS und Releases ohne Ausfallzeit.