diff --git a/deploy/Caddyfile b/deploy/Caddyfile
new file mode 100644
index 0000000..73fc097
--- /dev/null
+++ b/deploy/Caddyfile
@@ -0,0 +1,67 @@
+{
+ # HTTP/1.1 + HTTP/2 + HTTP/3 (QUIC). Cloudflare serves h3 to browsers;
+ # origin↔CF is TCP, but enabling h3 here is harmless + future-proof.
+ servers {
+ protocols h1 h2 h3
+ }
+}
+
+# Shared security headers. (No strict CSP yet — the app uses inline
+# scripts; we'll add a nonce-based CSP later.)
+(sechdrs) {
+ header {
+ Strict-Transport-Security "max-age=31536000; includeSubDomains"
+ X-Content-Type-Options "nosniff"
+ X-Frame-Options "SAMEORIGIN"
+ Referrer-Policy "strict-origin-when-cross-origin"
+ -Server
+ }
+}
+
+# All sites use the Cloudflare Origin cert (valid to 2041, no ACME/renewal).
+(cfcert) {
+ tls /etc/ssl/cannabuddy/origin.crt /etc/ssl/cannabuddy/origin.key
+}
+
+# --- Marketing landing (apex) ---
+cannabuddy.eu, www.cannabuddy.eu {
+ import cfcert
+ import sechdrs
+ encode zstd gzip
+ root * /var/www/cannabuddy-landing
+ file_server
+}
+
+# --- App (PWA) --- tenant resolved by login, not subdomain
+app.cannabuddy.eu {
+ import cfcert
+ import sechdrs
+ encode zstd gzip
+ # MQTT-over-WebSocket → Mosquitto ws listener (localhost)
+ @mqtt path /mqtt /mqtt/*
+ reverse_proxy @mqtt 127.0.0.1:8083
+ # everything else → Astro SSR (Node/pm2)
+ reverse_proxy 127.0.0.1:7502
+}
+
+# --- Superadmin console (same app, host-routed; lock behind CF Access) ---
+admin.cannabuddy.eu {
+ import cfcert
+ import sechdrs
+ encode zstd gzip
+ reverse_proxy 127.0.0.1:7502
+}
+
+# --- Forgejo ---
+git.cannabuddy.eu {
+ import cfcert
+ import sechdrs
+ reverse_proxy 127.0.0.1:3000
+}
+
+# --- Status (Uptime Kuma) ---
+status.cannabuddy.eu {
+ import cfcert
+ import sechdrs
+ reverse_proxy 127.0.0.1:3001
+}
diff --git a/deploy/landing/index.html b/deploy/landing/index.html
new file mode 100644
index 0000000..bdcd7b1
--- /dev/null
+++ b/deploy/landing/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+ CannaBuddy
+
+
+
+
+
+
CannaBuddy
+
Hydroponik-Monitoring für Cannabis Social Clubs.
Die Plattform wird gerade aufgebaut.
+
→ Zur App
+
+
+
diff --git a/passwords.md b/passwords.md
index 2ee10be..57c0a0f 100644
--- a/passwords.md
+++ b/passwords.md
@@ -51,7 +51,8 @@ _Last updated: 2026-05-30 (new-VPS bring-up)._
- Uses: nightly encrypted `pg_dump` backups → R2; later image uploads (presigned URLs).
## App secrets — to generate fresh on the new box (do NOT reuse old)
-- `DATABASE_URL` (TimescaleDB role + password) — _TODO_
+- **`DATABASE_URL`** = `postgres://hbcloud:095bb2ad7b25355592243d10c46e1e39cc15129cd71c5d53@127.0.0.1:5432/cannabuddy`
+ (also in `/etc/cannabuddy/cloud.env` on the box, root 0600; TimescaleDB 2.27.1 ext enabled)
- Better-Auth secret (`BETTER_AUTH_SECRET`) — _TODO (openssl rand -hex 32)_
- NanoMQ ↔ cloud auth-hook shared secret / device-token signing — _TODO_
- Forgejo: admin creds + CI runner registration token + deploy SSH key — _TODO_
diff --git a/scripts/create-db.sh b/scripts/create-db.sh
new file mode 100644
index 0000000..483281a
--- /dev/null
+++ b/scripts/create-db.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+# Create the app DB + role + TimescaleDB extension, write the env file.
+set -euo pipefail
+DBPASS=$(openssl rand -hex 24)
+
+# role (create or reset password)
+sudo -u postgres psql -c "CREATE ROLE hbcloud LOGIN PASSWORD '$DBPASS';" 2>/dev/null \
+ || sudo -u postgres psql -c "ALTER ROLE hbcloud LOGIN PASSWORD '$DBPASS';"
+
+# database
+sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname='cannabuddy'" | grep -q 1 \
+ || sudo -u postgres createdb -O hbcloud cannabuddy
+
+# timescaledb extension
+sudo -u postgres psql -d cannabuddy -v ON_ERROR_STOP=1 -c "CREATE EXTENSION IF NOT EXISTS timescaledb;" >/dev/null
+
+# env file (root-only) — the app + go-auth read DATABASE_URL from here
+mkdir -p /etc/cannabuddy
+touch /etc/cannabuddy/cloud.env && chmod 600 /etc/cannabuddy/cloud.env
+grep -q '^DATABASE_URL=' /etc/cannabuddy/cloud.env 2>/dev/null \
+ && sed -i "s#^DATABASE_URL=.*#DATABASE_URL=postgres://hbcloud:$DBPASS@127.0.0.1:5432/cannabuddy#" /etc/cannabuddy/cloud.env \
+ || echo "DATABASE_URL=postgres://hbcloud:$DBPASS@127.0.0.1:5432/cannabuddy" >> /etc/cannabuddy/cloud.env
+
+echo "OK — DB cannabuddy + role hbcloud ready, timescaledb extension on"
+sudo -u postgres psql -d cannabuddy -tAc "SELECT extname, extversion FROM pg_extension WHERE extname='timescaledb';"
+echo "DATABASE_URL=postgres://hbcloud:$DBPASS@127.0.0.1:5432/cannabuddy"