Update README.md

This commit is contained in:
dbildhauer committed 2026-08-08 21:17:57 +02:00
1 parent 8d7bc82fef
commit 0b52c0cde4
1 file changed
+578
+578
View File
@@ -0,0 +1,578 @@
# 🌐 Joplin Web – Self-Hosted Docker
Eine selbst gehostete **Joplin Web App**, die den offiziellen Joplin-Web-Client aus dem Joplin-Quellcode baut und anschließend über einen schlanken nginx-Container bereitstellt.
Die Web-App kann mit einem vorhandenen **Joplin Server** synchronisiert werden und ermöglicht den Zugriff auf Joplin-Notizen direkt über den Browser.
> ⚠️ Joplin Web befindet sich noch in Entwicklung/Beta. Vor produktivem Einsatz sollten Backups der Joplin-Daten vorhanden sein.
---
## ✨ Features
- 🌐 Joplin direkt im Webbrowser
- 🐳 Vollständig über Docker betreibbar
- 🔄 Synchronisation mit einem eigenen Joplin Server
- 🔐 Betrieb über HTTPS / Reverse Proxy
- 🗄️ Browserbasierter lokaler Speicher
- 📎 Unterstützung der Joplin-Synchronisation
- 🚀 Fertiges Docker-Image kann über eine Container Registry verteilt werden
- 🛡️ Zusätzlicher Zugriffsschutz über den Reverse Proxy möglich
---
## 🏗️ Aufbau
```text
┌──────────────────────┐
│ Browser │
│ Firefox / Chrome ... │
└──────────┬───────────┘
│
HTTPS
│
▼
┌──────────────────────┐
│ Reverse Proxy │
│ nginx / NPM / etc. │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Joplin Web │
│ nginx + Web App │
│ Port 3000 │
└──────────┬───────────┘
│
HTTPS / API
│
▼
┌──────────────────────┐
│ Joplin Server │
│ Sync + Benutzer │
└──────────────────────┘
```
---
# 📁 Projektstruktur
```text
joplin-web/
├── Dockerfile
├── docker-compose.yml
├── nginx.conf
├── README.md
└── .gitignore
```
---
# 🚀 Installation
## Variante 1 – Fertiges Container-Image
Wenn das Image bereits in einer Container Registry vorhanden ist, wird auf dem Zielserver kein Joplin-Build benötigt.
Beispiel:
```yaml
services:
joplin-web:
image: gitea.example.com/username/joplin-web:latest
container_name: joplin-web
restart: unless-stopped
ports:
- "3000:80"
security_opt:
- no-new-privileges:true
```
Container starten:
```bash
docker compose pull
docker compose up -d
```
Status prüfen:
```bash
docker compose ps
```
Logs anzeigen:
```bash
docker logs -f joplin-web
```
Die Web-App ist anschließend lokal unter folgendem Port erreichbar:
```text
http://SERVER-IP:3000
```
> Für den produktiven Betrieb sollte Joplin Web über **HTTPS** bereitgestellt werden.
---
# 🔨 Variante 2 – Image selbst bauen
Repository klonen:
```bash
git clone https://gitea.example.com/username/joplin-web.git
cd joplin-web
```
Image bauen:
```bash
docker compose build --no-cache --progress=plain
```
Anschließend starten:
```bash
docker compose up -d
```
Status prüfen:
```bash
docker compose ps
```
---
# 🐳 Docker Image
Das Docker-Image wird in mehreren Stufen gebaut.
## Builder
Im ersten Schritt wird der offizielle Joplin-Quellcode geladen und die Web-App gebaut.
Dabei werden unter anderem verwendet:
- Devbox
- Nix
- Node.js
- Yarn
- Joplin Source
- Joplin Mobile Web Build
Der Web-Build wird anschließend aus folgendem Verzeichnis übernommen:
```text
packages/app-mobile/web/dist
```
## Runtime
Der eigentliche produktive Container benötigt die Build-Umgebung nicht mehr.
Das fertige Web-Frontend wird über:
```text
nginx
```
bereitgestellt.
Dadurch bleibt der laufende Container wesentlich kleiner als die Build-Umgebung.
---
# 🔐 HTTPS
Joplin Web sollte nicht dauerhaft über eine unverschlüsselte HTTP-Verbindung verwendet werden.
Bestimmte Browser-APIs, die Joplin Web benötigt, stehen nur in einem **Secure Context** zur Verfügung.
Empfohlen:
```text
https://joplin-web.example.com
```
Der Reverse Proxy kann intern weiterhin auf:
```text
http://JOPLIN-WEB-IP:3000
```
weiterleiten.
---
# 🧠 Cross-Origin Isolation
Für bestimmte Browser-Funktionen werden folgende HTTP-Header ausgeliefert:
```text
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
```
Überprüfen:
```bash
curl -I http://127.0.0.1:3000
```
Beispiel:
```text
HTTP/1.1 200 OK
Server: nginx
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
```
Im Browser kann zusätzlich geprüft werden:
```javascript
window.isSecureContext
```
und:
```javascript
crossOriginIsolated
```
---
# 🔄 Verbindung mit Joplin Server
In Joplin Web unter der Synchronisationskonfiguration als Ziel **Joplin Server** auswählen.
Als Server-URL wird ausschließlich die Basis-URL verwendet:
```text
https://joplin.example.com
```
Nicht:
```text
https://joplin.example.com/api
```
und nicht:
```text
https://joplin.example.com/login
```
Anschließend die Zugangsdaten des Joplin-Benutzers eintragen.
---
# 🌍 CORS bei eigenem Joplin Server
Wenn Joplin Web und Joplin Server unterschiedliche Domains verwenden, muss der Browser Cross-Origin-Anfragen zulassen.
Beispiel:
```text
Joplin Web:
https://joplin-web.example.com
Joplin Server:
https://joplin.example.com
```
Ohne entsprechende Konfiguration können Fehler auftreten wie:
```text
Blocked by CORS policy
```
oder:
```text
Cross-Origin Request Blocked
```
## Beispiel für nginx / Nginx Proxy Manager
Auf dem Reverse Proxy des **Joplin Servers**:
```nginx
proxy_hide_header Access-Control-Allow-Origin;
proxy_hide_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
more_set_headers "Access-Control-Allow-Origin: https://joplin-web.example.com";
more_set_headers "Access-Control-Allow-Methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS";
more_set_headers "Access-Control-Allow-Headers: Content-Type, Authorization, X-API-MIN-VERSION, X-API-AUTH";
more_set_headers "Vary: Origin";
```
> Die Domain muss an die eigene Joplin-Web-Adresse angepasst werden.
---
## CORS testen
Preflight-Anfrage:
```bash
curl -i -X OPTIONS \
-H "Origin: https://joplin-web.example.com" \
-H "Access-Control-Request-Method: PUT" \
-H "Access-Control-Request-Headers: content-type,x-api-min-version,x-api-auth" \
https://joplin.example.com/api/items/root:/testing.txt:/content
```
Die Antwort sollte unter anderem enthalten:
```text
Access-Control-Allow-Origin: https://joplin-web.example.com
Access-Control-Allow-Methods:
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers:
Content-Type, Authorization, X-API-MIN-VERSION, X-API-AUTH
```
---
# 🔒 Zusätzlicher Zugriffsschutz
Da die Web-App grundsätzlich über ihre URL erreichbar ist, empfiehlt sich ein zusätzlicher Schutz auf Reverse-Proxy-Ebene.
Mögliche Lösungen:
- HTTP Basic Authentication
- Nginx Proxy Manager Access Lists
- Authelia
- Authentik
- VPN / WireGuard / NetBird
Die Architektur sieht dann beispielsweise so aus:
```text
Internet
│
▼
Reverse Proxy
│
├── Authentifizierung
│
▼
Joplin Web
│
▼
Joplin Server
```
Die eigentlichen Joplin-Zugangsdaten werden weiterhin für die Synchronisation mit dem Joplin Server verwendet.
---
# 🔄 Update
## Bei Verwendung eines fertigen Images
```bash
docker compose pull
docker compose up -d
```
Nicht mehr verwendete Images können anschließend entfernt werden:
```bash
docker image prune
```
---
## Bei lokalem Build
Repository aktualisieren:
```bash
git pull
```
Danach neu bauen:
```bash
docker compose build --no-cache
docker compose up -d
```
---
# 📦 Image in eine Gitea Container Registry pushen
Zunächst anmelden:
```bash
docker login gitea.example.com
```
Image taggen:
```bash
docker tag joplin-web-joplin-web:latest \
gitea.example.com/username/joplin-web:latest
```
Danach:
```bash
docker push gitea.example.com/username/joplin-web:latest
```
Auf einem anderen Docker-Server genügt anschließend:
```bash
docker login gitea.example.com
docker compose pull
docker compose up -d
```
Damit muss Joplin auf dem Zielserver **nicht erneut aus dem Quellcode gebaut werden**.
---
# 🧹 Nützliche Docker-Befehle
Container anzeigen:
```bash
docker compose ps
```
Logs:
```bash
docker logs -f joplin-web
```
Container neu starten:
```bash
docker compose restart
```
Container stoppen:
```bash
docker compose down
```
Container starten:
```bash
docker compose up -d
```
Image neu bauen:
```bash
docker compose build --no-cache
```
---
# 🛠️ Fehlerbehebung
## Web-App lädt nicht
Container prüfen:
```bash
docker compose ps
```
Logs:
```bash
docker logs joplin-web --tail 100
```
Webserver lokal testen:
```bash
curl -I http://127.0.0.1:3000
```
---
## Synchronisation schlägt fehl
Browser-Entwicklertools öffnen und unter **Console** bzw. **Network** nach Fehlern suchen.
Häufige Ursachen:
- falsche Joplin-Server-URL
- CORS
- fehlender `X-API-AUTH` Header
- Reverse-Proxy-Konfiguration
- Zertifikatsprobleme
---
## Browser zeigt alten Stand
Joplin Web verwendet Browser-Speicher und Service Worker.
Bei Problemen:
1. Alle Joplin-Web-Tabs schließen.
2. Website-Daten der Joplin-Web-Domain löschen.
3. Browser vollständig schließen.
4. Browser neu starten.
5. Joplin Web erneut öffnen.
---
# ⚠️ Hinweise
Joplin Web speichert lokale Client-Daten im Browser.
Daher gilt:
- Browserdaten nicht unüberlegt löschen.
- Synchronisation vor größeren Änderungen vollständig durchführen.
- Regelmäßige Backups des Joplin Servers erstellen.
- Die Web-App möglichst nur über HTTPS betreiben.
- Für öffentlich erreichbare Installationen zusätzlichen Zugriffsschutz verwenden.
---
# 🔗 Links
- Joplin: https://joplinapp.org/
- Joplin GitHub: https://github.com/laurent22/joplin
- Joplin Build Documentation: https://joplinapp.org/help/dev/BUILD/
- Docker: https://www.docker.com/
- Gitea: https://about.gitea.com/
---
# 📜 Lizenz
Dieses Repository enthält die Docker-/Deployment-Konfiguration für Joplin Web.
Joplin selbst ist ein eigenständiges Open-Source-Projekt. Für Joplin gelten die Lizenzbedingungen des offiziellen Joplin-Projekts.
---
## ❤️ Credits
[Joplin](https://joplinapp.org/) wird von Laurent Cozic und der Joplin-Community entwickelt.
Dieses Repository stellt lediglich eine Docker-basierte Möglichkeit bereit, den Joplin-Web-Client selbst zu bauen und zu hosten.