Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Docker 22.08.2026 · 8 min Lesezeit

Memos mit Docker installieren: Leichtgewichtiger Self-Hosted Memo-Hub für Schnellnotizen

Memos 0.31 mit Docker Compose selbst hosten: schlanker Notizdienst mit SQLite, festem Image-Tag, Zugriff über HTTPS-Reverse-Proxy, gesperrter Registrierung und konsistentem Backup.

Geprüft am 30.09.2026 · für Memos 0.31.0

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Symbolbild zur Anleitung: Memos mit Docker installieren

Memos ist ein schlanker, selbst gehosteter Notizdienst für kurze Einträge, Code-Snippets und Tagesnotizen. Das Image ist rund 26 MB groß, läuft als einzelner Container und speichert Daten standardmäßig in einer SQLite-Datei; eine separate Datenbank ist nicht nötig. Diese Anleitung richtet Memos 0.31 mit Docker Compose auf einem Linux-Server ein, mit festem Image-Tag, Zugriff nur über einen Reverse Proxy mit HTTPS und konsistentem Backup.

Voraussetzungen

  1. Docker Engine 20.10+ und das Docker Compose Plugin v2 (docker compose, nicht das alte docker-compose) müssen installiert sein, siehe Docker und Docker Compose auf Linux installieren.
  2. Linux-Host, VM oder NAS mit Docker-Unterstützung (amd64, arm64 oder arm/v7, z. B. Raspberry Pi 4/5).
  3. Mindestens 256 MB freier RAM und 1 GB Speicherplatz für Daten.
  4. Für den Zugriff von anderen Geräten: Domain mit DNS-Eintrag und Reverse Proxy (Caddy, Traefik oder Nginx Proxy Manager), siehe Schritt 5.

Schritt 1: Projektordner anlegen

Alle Dateien für den Memos-Stack liegen in einem eigenen Verzeichnis:

mkdir -p /opt/memos
cd /opt/memos

Legen Sie das Datenverzeichnis an. Der Container startet als root, setzt den Eigentümer von /var/opt/memos auf UID/GID 10001 und arbeitet danach als dieser Benutzer. Das chown vorab schadet nicht und vermeidet Probleme auf Dateisystemen, auf denen der Container keine Rechte ändern darf:

mkdir -p /opt/memos/memos-data
sudo chown -R 10001:10001 /opt/memos/memos-data

Verifizieren: ls -la /opt/memos/ zeigt memos-data mit Eigentümer 10001.

ls -la /opt/memos/
# Erwartete Ausgabe (gekürzt):
# drwxr-xr-x  2 10001 10001  ... memos-data

Schritt 2: .env-Datei anlegen

Für SQLite sind keine Pflichtvariablen nötig. MEMOS_INSTANCE_URL ist die öffentliche Adresse, die Memos für Links verwendet. Seit 0.31 ist sie unabhängig vom Zugriffsmodus; auf einer neuen Instanz setzt eine gesetzte URL den Modus beim ersten Start aber auf öffentlich (Schritt 4):

# /opt/memos/.env
# Oeffentliche URL der Instanz (absolute https-URL ohne Pfadparameter)
MEMOS_INSTANCE_URL=https://memos.example.com
# Log-Level: debug, info, warn, error (Standard: info)
MEMOS_LOG_LEVEL=info
# Datenbanktyp: sqlite (Standard), mysql, postgres
MEMOS_DRIVER=sqlite

Passen Sie MEMOS_INSTANCE_URL an Ihre Domain an oder kommentieren Sie die Zeile aus, solange kein Reverse Proxy existiert. Setzen Sie die Rechte: chmod 600 /opt/memos/.env.

Verifizieren: Die Datei enthält nur KEY=Wert-Zeilen und Kommentare:

cat /opt/memos/.env
# Ausgabe: drei KEY=Wert-Zeilen, keine Leerzeichen um das =

Schritt 3: compose.yaml erstellen

Die folgende compose.yaml startet Memos mit SQLite, Healthcheck und festem Versions-Tag. Port 5230 ist nur auf 127.0.0.1 gebunden:

services:
  memos:
    image: neosmemo/memos:0.31.0
    container_name: memos
    restart: unless-stopped
    ports:
      - "127.0.0.1:5230:5230"
    volumes:
      - ./memos-data:/var/opt/memos
    env_file:
      - .env
    environment:
      MEMOS_PORT: "5230"
      MEMOS_DRIVER: sqlite
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5230/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 20s

Zum Image-Tag: 0.31.0 ist fest und reproduzierbar; Updates erfolgen bewusst durch Ändern des Tags (Schritt 6). stable folgt automatisch der neuesten stabilen Version, latest und canary sind Entwicklungsstände und für den Produktivbetrieb ungeeignet.

Verifizieren: Syntax prüfen:

docker compose -f /opt/memos/compose.yaml config
# Keine Fehlermeldungen; gibt die geparste Konfiguration aus

Schritt 4: Memos starten und Ersteinrichtung

Starten Sie den Stack aus dem Projektverzeichnis:

cd /opt/memos
docker compose up -d

Nach etwa 20 Sekunden (start_period des Healthchecks) meldet der Container healthy:

docker compose ps
# Erwartete Ausgabe:
# NAME    IMAGE                    COMMAND   SERVICE  STATUS           PORTS
# memos   neosmemo/memos:0.31.0    ...       memos    Up X min (healthy)  127.0.0.1:5230->5230/tcp

Logs auf Fehler prüfen:

docker compose logs memos
# Erwartete Ausgabe (Auszug):
# memos  | Data directory: /var/opt/memos
# memos  | Database driver: sqlite
# memos  | Server running on port 5230

Erreichbarkeit per curl testen:

curl -I http://localhost:5230
# HTTP/1.1 200 OK  (oder 302 Found bei Weiterleitung auf /auth)

Ersteinrichtung im Browser: Ohne Reverse Proxy erreichen Sie die Oberfläche per SSH-Tunnel: ssh -L 5230:127.0.0.1:5230 benutzer@server, dann http://localhost:5230. Der erste angelegte Account erhält Administratorrechte. Prüfen Sie danach in den Einstellungen unter Instanz zwei Punkte: den Zugriffsmodus (privat oder öffentlich lesbar) und ob neue Benutzer sich selbst registrieren dürfen. Für eine interne Notizablage wählen Sie privat und deaktivieren die Registrierung.

Verifizieren: docker compose ps zeigt (healthy), ss -tlnp | grep 5230 zeigt nur 127.0.0.1:5230. In einem privaten Browserfenster erscheint nach der Umstellung keine Registrierungsmöglichkeit mehr.

Schritt 5: HTTPS und Reverse Proxy (optional, empfohlen)

Memos bringt kein TLS mit. Für den Zugriff von anderen Geräten schalten Sie einen Reverse Proxy auf demselben Host vor, der die Header Host, X-Forwarded-Proto und X-Forwarded-For weiterreicht. Caddy holt Let's-Encrypt-Zertifikate automatisch, siehe Caddy als Reverse Proxy einrichten.

Bei mehreren Docker-Diensten eignet sich Traefik: Traefik als Docker-Reverse-Proxy mit automatischem HTTPS.

Minimales Caddy-Beispiel (Caddyfile-Auszug):

memos.example.com {
    reverse_proxy localhost:5230
}

Setzen Sie in der .env MEMOS_INSTANCE_URL=https://memos.example.com und erstellen Sie den Container neu:

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

Verifizieren: curl -I https://memos.example.com liefert HTTP/2 200; der Browser zeigt ein gültiges Zertifikat, und von Memos erzeugte Links beginnen mit https://memos.example.com.

Schritt 6: Updates und Backup

Memos führt Datenbankmigrationen beim Start automatisch aus; ein Downgrade danach ist nicht möglich, die Sicherung ist der einzige Rückweg. Sichern Sie deshalb vor jedem Update. Für eine konsistente SQLite-Sicherung stoppen Sie den Container kurz:

cd /opt/memos
sudo mkdir -p /backup/memos
docker compose stop memos
sudo tar -czf /backup/memos/memos-$(date +%Y%m%d).tar.gz -C /opt/memos memos-data .env compose.yaml
docker compose start memos

memos-data enthält die Datenbank memos_prod.db und den Ordner assets mit hochgeladenen Dateien. Für eine automatisierte Sicherung außer Haus eignet sich Restic mit automatischer Cron-Sicherung.

Lesen Sie vor dem Update die Release Notes der übersprungenen Versionen, besonders bei einem Wechsel der Minor-Version (0.x auf 0.y). Setzen Sie dann in der compose.yaml den neuen Tag, z. B. neosmemo/memos:0.31.1, und starten Sie neu:

docker compose pull
docker compose up -d
docker image prune -f

Verifizieren: docker compose ps zeigt den neuen Tag und (healthy), docker compose logs memos enthält keine Migrationsfehler, und bisherige Memos sind vorhanden. tar -tzf auf die Sicherungsdatei listet memos-data/memos_prod.db.

Eckdaten auf einen Blick

EigenschaftWert
Offizielles Imageneosmemo/memos (Docker Hub)
Aktuelle stabile Version0.31.0 (19. September 2026)
Image-Größerund 26 MB (Go-Binary auf Alpine)
Architekturenlinux/amd64, linux/arm64, linux/arm/v7
Web-UI / API-Port5230
Daten-Volume im Container/var/opt/memos
Standard-DatenbankSQLite (memos_prod.db) – kein Begleitcontainer nötig
Alternativen DBsMySQL 8+, PostgreSQL
Container-User (UID/GID)10001 / 10001 (Non-Root)
LizenzMIT

Wichtige Umgebungsvariablen

VariableStandardBeschreibung
MEMOS_PORT5230 (Image), sonst 8081Interner Listener-Port
MEMOS_ADDR(leer = alle)Bind-Adresse im Container
MEMOS_DATA/var/opt/memosDatenpfad im Container
MEMOS_DRIVERsqliteDatenbanktyp: sqlite, mysql, postgres
MEMOS_DSN(leer)Verbindungsstring (Pflicht bei MySQL/PG)
MEMOS_INSTANCE_URL(leer)Öffentliche URL für Links; unabhängig vom Zugriffsmodus
MEMOS_LOG_LEVELinfodebug, info, warn, error
MEMOS_UID / MEMOS_GID10001Container-User-IDs

Troubleshooting / Typische Fehler

  1. „permission denied“ beim Start: Memos arbeitet als UID 10001, und der Container konnte den Eigentümer nicht ändern (z. B. NFS-Freigabe, rootless Docker). Lösung: sudo chown -R 10001:10001 /opt/memos/memos-data oder MEMOS_UID/MEMOS_GID passend setzen, danach docker compose restart memos.
  2. „bind: address already in use“ auf Port 5230: Ein anderer Dienst belegt diesen Port. Lösung: Host-Port ändern, z. B. "127.0.0.1:5231:5230", und den Reverse Proxy anpassen.
  3. Share-Links und Webhooks zeigen falsche URLs: MEMOS_INSTANCE_URL fehlt oder ist falsch. HTTPS-URL in der .env eintragen, docker compose up -d --force-recreate.
  4. Instanz ungewollt öffentlich lesbar: Auf einer neuen Instanz mit gesetzter MEMOS_INSTANCE_URL startet Memos 0.31 im öffentlichen Zugriffsmodus. Lösung: in den Instanz-Einstellungen auf privat umstellen.
  5. Daten nach Neustart weg: Das Volume-Mapping fehlt in der compose.yaml. Ohne ./memos-data:/var/opt/memos schreibt Memos in den ephemeralen Container-Layer. Volume-Zeile ergänzen, docker compose up -d.
  6. MySQL-Verbindungsfehler beim Start: Bei MEMOS_DRIVER=mysql muss MEMOS_DSN exakt im Format user:pass@tcp(host:3306)/dbname gesetzt sein. Ein fehlendes tcp() führt zu „invalid DSN“. Zusätzlich depends_on mit condition: service_healthy ergänzen.
  7. Browser zeigt veraltetes Layout nach Update: Harter Reload mit Strg+Umschalt+R (Windows/Linux) oder Cmd+Umschalt+R (macOS) erzwingt das Nachladen aller Assets.

Häufige Fragen

Brauche ich eine externe Datenbank?

Nein. SQLite genügt für eine Instanz mit Einzelpersonen und kleinen Teams. MySQL 8+ oder PostgreSQL sind sinnvoll, wenn Sie einen bestehenden Datenbankserver nutzen möchten.

Welches Image-Tag soll ich verwenden?

Einen festen Versions-Tag wie 0.31.0, siehe Schritt 3. canary und latest nur auf Testsystemen.

Wie sichere ich meine Memos-Daten?

Bei gestopptem Container als Archiv von ./memos-data, siehe Schritt 6. Im laufenden Betrieb kopiert cp die SQLite-Datei nicht konsistent. Für automatisierte, versionierte Sicherungen siehe Restic Backup auf Linux automatisieren.

Wie aktiviere ich HTTPS?

Über einen Reverse Proxy, der an 127.0.0.1:5230 weiterleitet, und MEMOS_INSTANCE_URL mit der HTTPS-Adresse, siehe Schritt 5.

Läuft Memos auf einem Raspberry Pi?

Ja. Das Image gibt es für linux/arm64 und linux/arm/v7; dieselbe compose.yaml funktioniert ohne Änderungen.

Wie aktualisiere ich Memos auf eine neue Version?

Sichern, Tag in der compose.yaml anpassen, docker compose pull und docker compose up -d, siehe Schritt 6. Ein Downgrade nach der Migration ist nicht möglich.

Kann ich Memos mit MySQL oder PostgreSQL betreiben?

Ja. Setzen Sie MEMOS_DRIVER=mysql oder postgres und MEMOS_DSN, für MySQL im Format user:pass@tcp(host:3306)/dbname, für PostgreSQL postgres://user:pass@host:5432/memos?sslmode=disable. Das Datenvolume bleibt für Anhänge nötig.

Fazit

Memos ist mit einem Container und SQLite schnell eingerichtet und einfach zu betreiben. Für den Produktivbetrieb entscheidend sind ein fester Image-Tag, Zugriff nur über HTTPS, ein bewusst gewählter Zugriffsmodus mit gesperrter Registrierung und konsistente Sicherungen vor jedem Update. Für umfangreiche Dokumentation eignet sich ein Wiki wie BookStack oder AFFiNE besser.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren – die Self-Hosting-Grundlage
  2. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS
  3. Restic Backup auf Linux und Windows einrichten und automatisieren
  4. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only
  5. AFFiNE mit Docker installieren: All-in-One-Notion-Alternative

Offizielle Quellen: Memos Docker-Dokumentation (usememos.com) · Memos GitHub Repository · neosmemo/memos auf Docker Hub