Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf5157c496 | |||
| dffbe26423 | |||
| 732e7918af |
@@ -9,3 +9,6 @@ __pycache__/
|
|||||||
|
|
||||||
data/
|
data/
|
||||||
instance/
|
instance/
|
||||||
|
.cloudron-push.env
|
||||||
|
.env.local
|
||||||
|
.env.push.local
|
||||||
|
|||||||
+2
-1
@@ -11,7 +11,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
sqlite3 \
|
sqlite3 \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN useradd -r -m -d /home/cloudron cloudron
|
RUN groupadd --gid 1000 cloudron \
|
||||||
|
&& useradd --uid 1000 --gid 1000 --create-home --home-dir /home/cloudron cloudron
|
||||||
|
|
||||||
COPY requirements.txt /app/code/
|
COPY requirements.txt /app/code/
|
||||||
RUN pip install --no-cache-dir -r requirements.txt gunicorn
|
RUN pip install --no-cache-dir -r requirements.txt gunicorn
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Push-Setup für Nouri
|
||||||
|
|
||||||
|
## 1. VAPID-Schlüssel erzeugen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
. .venv/bin/activate
|
||||||
|
python scripts/generate_vapid_keys.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Das Script gibt drei Zeilen aus:
|
||||||
|
|
||||||
|
- `NOURI_VAPID_PUBLIC_KEY`
|
||||||
|
- `NOURI_VAPID_PRIVATE_KEY`
|
||||||
|
- `NOURI_VAPID_SUBJECT`
|
||||||
|
|
||||||
|
## 2. In Cloudron eintragen
|
||||||
|
|
||||||
|
In der bestehenden Nouri-App unter `Settings` → `Environment Variables` diese drei Werte anlegen:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NOURI_VAPID_PUBLIC_KEY=...
|
||||||
|
NOURI_VAPID_PRIVATE_KEY=...
|
||||||
|
NOURI_VAPID_SUBJECT=mailto:mail@hnz.io
|
||||||
|
```
|
||||||
|
|
||||||
|
Danach die App neu starten.
|
||||||
|
|
||||||
|
## 3. Auf dem iPhone aktivieren
|
||||||
|
|
||||||
|
1. `nouri.heinz.media` in Safari öffnen
|
||||||
|
2. `Teilen` → `Zum Home-Bildschirm`
|
||||||
|
3. die installierte Web-App öffnen
|
||||||
|
4. in Nouri `Optionen` öffnen
|
||||||
|
5. `Push erlauben` tippen
|
||||||
|
6. danach optional `Test-Mitteilung senden`
|
||||||
|
|
||||||
|
## 4. Bereits vorbereitete lokale Datei
|
||||||
|
|
||||||
|
Wenn lokal bereits eine Datei `.cloudron-push.env` liegt, kannst du deren Werte direkt nach Cloudron übernehmen.
|
||||||
|
|
||||||
|
Die Datei ist absichtlich in `.gitignore`, damit keine geheimen Schlüssel committed werden.
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
const CACHE_NAME = "nouri-v0-5-0";
|
const CACHE_NAME = "nouri-v0-5-1";
|
||||||
const APP_SHELL = [
|
const STATIC_ASSETS = [
|
||||||
"/",
|
|
||||||
"/static/css/styles.css",
|
"/static/css/styles.css",
|
||||||
"/static/js/theme.js",
|
"/static/js/theme.js",
|
||||||
"/static/js/ui.js",
|
"/static/js/ui.js",
|
||||||
@@ -13,7 +12,7 @@ const APP_SHELL = [
|
|||||||
|
|
||||||
self.addEventListener("install", (event) => {
|
self.addEventListener("install", (event) => {
|
||||||
event.waitUntil(
|
event.waitUntil(
|
||||||
caches.open(CACHE_NAME).then((cache) => cache.addAll(APP_SHELL)).then(() => self.skipWaiting())
|
caches.open(CACHE_NAME).then((cache) => cache.addAll(STATIC_ASSETS)).then(() => self.skipWaiting())
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -27,9 +26,32 @@ self.addEventListener("activate", (event) => {
|
|||||||
|
|
||||||
self.addEventListener("fetch", (event) => {
|
self.addEventListener("fetch", (event) => {
|
||||||
if (event.request.method !== "GET") return;
|
if (event.request.method !== "GET") return;
|
||||||
|
|
||||||
|
const requestUrl = new URL(event.request.url);
|
||||||
|
const isStaticAsset =
|
||||||
|
requestUrl.origin === self.location.origin &&
|
||||||
|
(
|
||||||
|
requestUrl.pathname.startsWith("/static/")
|
||||||
|
|| requestUrl.pathname === "/app.webmanifest"
|
||||||
|
|| requestUrl.pathname === "/service-worker.js"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event.request.mode === "navigate") {
|
||||||
|
event.respondWith(
|
||||||
|
fetch(event.request).catch(() => caches.match(event.request))
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isStaticAsset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.respondWith(
|
event.respondWith(
|
||||||
caches.match(event.request).then((cached) => {
|
caches.match(event.request).then((cached) => {
|
||||||
if (cached) return cached;
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
return fetch(event.request).then((response) => {
|
return fetch(event.request).then((response) => {
|
||||||
if (!response || response.status !== 200 || response.type !== "basic") {
|
if (!response || response.status !== 200 || response.type !== "basic") {
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from py_vapid import Vapid01, b64urlencode
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
vapid = Vapid01()
|
||||||
|
vapid.generate_keys()
|
||||||
|
|
||||||
|
public_key = b64urlencode(
|
||||||
|
vapid.public_key.public_bytes(
|
||||||
|
encoding=serialization.Encoding.X962,
|
||||||
|
format=serialization.PublicFormat.UncompressedPoint,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private_value = vapid.private_key.private_numbers().private_value
|
||||||
|
private_key = b64urlencode(private_value.to_bytes(32, "big"))
|
||||||
|
|
||||||
|
print(f"NOURI_VAPID_PUBLIC_KEY={public_key}")
|
||||||
|
print(f"NOURI_VAPID_PRIVATE_KEY={private_key}")
|
||||||
|
print("NOURI_VAPID_SUBJECT=mailto:mail@hnz.io")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -3,7 +3,6 @@ set -eu
|
|||||||
|
|
||||||
export NOURI_DATA_DIR="${NOURI_DATA_DIR:-/app/data}"
|
export NOURI_DATA_DIR="${NOURI_DATA_DIR:-/app/data}"
|
||||||
mkdir -p "${NOURI_DATA_DIR}"
|
mkdir -p "${NOURI_DATA_DIR}"
|
||||||
touch "${NOURI_DATA_DIR}/nouri.sqlite3"
|
|
||||||
mkdir -p "${NOURI_DATA_DIR}/uploads"
|
mkdir -p "${NOURI_DATA_DIR}/uploads"
|
||||||
|
|
||||||
exec gunicorn \
|
exec gunicorn \
|
||||||
|
|||||||
Reference in New Issue
Block a user