From 3c6f4dd67c8ae230515b381bfd9c22cbc1708a5f Mon Sep 17 00:00:00 2001 From: tomdebone Date: Wed, 9 Sep 2026 21:35:53 +0200 Subject: [PATCH] chore(config): Binaries laden .env selbst; .env.example korrigiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `cp .env.example .env && cargo run` — der im README dokumentierte Ablauf — schlug bisher mit `missing env: PDS_HOST` fehl: nichts im Prozess hat die Datei je gelesen. Beide Bins rufen jetzt als erstes `dotenvy::dotenv()` auf; echte Umgebungsvariablen gewinnen weiterhin. Dazu .env.example am Code verifiziert: * PDS_JWT_SECRET war weder Hex noch ein gültiger P-256-Skalar. jwt_issuer.rs macht hex::decode + p256::SecretKey::from_bytes; ein ungültiger Wert lässt den Server starten, aber jeder Pfad über server_p256_public_multibase antwortet 500 — also nicht nur create/refreshSession, sondern auch jeder Record-Write (repo.rs, feed.rs, blob.rs, profile.rs). * JETSTREAM_COLLECTIONS fehlten app.twi.post (das eigene 160-Zeichen-Lexicon) und app.bsky.actor.profile, obwohl der Indexer beide verarbeitet. * APP_ENV entfernt — wird nirgends gelesen. * PDS_INTERNAL_URL, APPVIEW_INTERNAL_URL, APPVIEW_HANDLE_SYNC_INTERVAL_SECS und die MAARCADETWEET_*-Overrides des Clients ergänzt. * S3_BUCKET_APPVIEW als das markiert, was es ist: Pflichtvariable ohne Leser. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_013HC9HLrUU1LNwkzp8nkDLX --- .env.example | 37 ++++++++++++++++++++++++++++++----- Cargo.lock | 2 ++ Cargo.toml | 1 + crates/appview/Cargo.toml | 1 + crates/appview/src/main.rs | 6 ++++++ crates/pds-server/Cargo.toml | 1 + crates/pds-server/src/main.rs | 6 ++++++ 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index ec2eccc..46ba8fb 100644 --- a/.env.example +++ b/.env.example @@ -1,26 +1,46 @@ # ===================================================== # maarcadetweet — environment # ===================================================== -# Copy to .env and adjust. +# Copy to .env and adjust. Beide Binaries laden `.env` beim Start +# selbst (dotenvy); echte Umgebungsvariablen haben Vorrang. # --- General --- RUST_LOG=info,maarcadetweet=debug,sqlx=warn -APP_ENV=dev # --- PDS server --- PDS_HOST=127.0.0.1 PDS_PORT=2583 PDS_PUBLIC_URL=http://127.0.0.1:2583 PDS_HANDLE_DNS_ZONE=.maarcadetweet.local -PDS_JWT_SECRET=change-me-to-a-32-byte-random-string-please +# MUSS Hex sein, >= 32 Bytes ergeben und ein gültiger P-256-Skalar +# sein (also nicht lauter Nullen) — `jwt_issuer.rs` macht hex::decode() +# und p256::SecretKey::from_bytes(). Ein ungültiger Wert lässt den +# Server zwar starten, aber alles, was den Serverschlüssel ableitet, +# antwortet mit 500: createAccount/createSession/refreshSession UND +# jeder Record-Write (repo.rs, feed.rs, blob.rs, profile.rs). +# Der Wert hier ist ein Zufallswert fürs Beispiel — für echte +# Instanzen einen eigenen erzeugen: +# openssl rand -hex 32 +PDS_JWT_SECRET=522084586f3d3abb835d43b7c4726735d78803dd58490f62a92571cd29033a95 +# Wohin die PDS ihre Commits pusht (POST /internal/ingest-commit). +# Default: APPVIEW_PUBLIC_URL. +# APPVIEW_INTERNAL_URL=http://127.0.0.1:2584 # --- AppView service --- APPVIEW_HOST=127.0.0.1 APPVIEW_PORT=2584 APPVIEW_PUBLIC_URL=http://127.0.0.1:2584 JETSTREAM_URL=wss://jetstream1.us-east.bsky.network/subscribe -# Collections the AppView will index -JETSTREAM_COLLECTIONS=app.bsky.feed.post,app.bsky.feed.like,app.bsky.feed.repost,app.bsky.graph.follow +# Collections, die die AppView indexiert. `app.twi.post` ist das +# eigene 160-Zeichen-Lexicon und muss mit rein, sonst tauchen eigene +# Posts nur über den PDS-Push auf; `app.bsky.actor.profile` füttert +# den Profil-Cache. +JETSTREAM_COLLECTIONS=app.twi.post,app.bsky.feed.post,app.bsky.feed.like,app.bsky.feed.repost,app.bsky.graph.follow,app.bsky.actor.profile +# Für den Handle-Sync-Worker: welche PDS nach lokalen Handles gefragt +# wird. Default: PDS_PUBLIC_URL. +# PDS_INTERNAL_URL=http://127.0.0.1:2583 +# Intervall des Handle-Sync-Workers in Sekunden (Default: 300). +# APPVIEW_HANDLE_SYNC_INTERVAL_SECS=60 # --- Databases --- DATABASE_URL_PDS=postgres://pds:pds@127.0.0.1:5434/pds @@ -32,6 +52,9 @@ S3_REGION=us-east-1 S3_ACCESS_KEY=minioadmin S3_SECRET_KEY=minioadmin S3_BUCKET_PDS=maarcadetweet-pds +# Pflichtvariable in AppConfig::from_env(), wird derzeit von keinem +# Code-Pfad gelesen — muss gesetzt sein, damit der Start nicht +# fehlschlägt. S3_BUCKET_APPVIEW=maarcadetweet-appview # --- PLC Directory (dev: leave default; can mock) --- @@ -40,3 +63,7 @@ PLC_DIRECTORY_URL=https://plc.directory # --- AppView ingest auth (optional, dev ok if unset) --- # APPVIEW_INGEST_SECRET=change-me-to-a-shared-secret-between-pds-and-appview + +# --- Tauri-Client (Build-/Laufzeit-Overrides des Desktop-Clients) --- +# MAARCADETWEET_PDS_URL=http://127.0.0.1:2583 +# MAARCADETWEET_APPVIEW_URL=http://127.0.0.1:2584 diff --git a/Cargo.lock b/Cargo.lock index cc55782..2d95a93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,6 +51,7 @@ dependencies = [ "axum", "base64", "chrono", + "dotenvy", "futures", "reqwest", "rustls", @@ -1882,6 +1883,7 @@ dependencies = [ "chrono", "ciborium", "cid", + "dotenvy", "hex", "k256", "p256", diff --git a/Cargo.toml b/Cargo.toml index 68c01e9..7644a79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ blake3 = "1" rand = "0.8" rand_core = "0.6" hex = "0.4" +dotenvy = "0.15" base64 = "0.22" parking_lot = "0.12" async-stream = "0.3" diff --git a/crates/appview/Cargo.toml b/crates/appview/Cargo.toml index 85e8050..bff2966 100644 --- a/crates/appview/Cargo.toml +++ b/crates/appview/Cargo.toml @@ -19,6 +19,7 @@ path = "src/main.rs" [dependencies] tokio = { workspace = true } +dotenvy = { workspace = true } axum = { workspace = true } tower = { workspace = true } tower-http = { workspace = true } diff --git a/crates/appview/src/main.rs b/crates/appview/src/main.rs index 1902ee6..885c80d 100644 --- a/crates/appview/src/main.rs +++ b/crates/appview/src/main.rs @@ -18,6 +18,12 @@ use state::AppState; #[tokio::main] async fn main() -> Result<()> { + // Load `.env` from the working directory (and upwards) if present. + // Nothing else in the process reads it, so without this + // `cp .env.example .env && cargo run` fails with `missing env: + // PDS_HOST`. Real environment variables always win over the file. + let _ = dotenvy::dotenv(); + // Install a rustls crypto provider before any TLS connection. `ring` // is the only one we currently support; using `aws_lc_rs` would // require a non-default feature on rustls. diff --git a/crates/pds-server/Cargo.toml b/crates/pds-server/Cargo.toml index 6d254ea..f56da4f 100644 --- a/crates/pds-server/Cargo.toml +++ b/crates/pds-server/Cargo.toml @@ -15,6 +15,7 @@ path = "src/main.rs" [dependencies] tokio = { workspace = true } +dotenvy = { workspace = true } axum = { workspace = true } tower = { workspace = true } tower-http = { workspace = true } diff --git a/crates/pds-server/src/main.rs b/crates/pds-server/src/main.rs index cf05462..525e436 100644 --- a/crates/pds-server/src/main.rs +++ b/crates/pds-server/src/main.rs @@ -17,6 +17,12 @@ use tracing_subscriber::EnvFilter; #[tokio::main] async fn main() -> anyhow::Result<()> { + // Load `.env` from the working directory (and upwards) if present. + // Nothing else in the process reads it, so without this + // `cp .env.example .env && cargo run` fails with `missing env: + // PDS_HOST`. Real environment variables always win over the file. + let _ = dotenvy::dotenv(); + tracing_subscriber::fmt() .with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"))) .init();