From 31ee828859bdc5c6bcd272554eae943a36c7b3a8 Mon Sep 17 00:00:00 2001 From: Taksh Date: Sat, 25 Jul 2026 08:00:46 +0300 Subject: [PATCH 1/3] fix(compose): chown git data volume for non-root relay Fresh named volumes are root-owned; the relay runs as uid 1000 and cannot create /data/git/.pack-cache without an init step. Closes #2814 Signed-off-by: Taksh --- deploy/compose/README.md | 4 ++++ deploy/compose/compose.yml | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/deploy/compose/README.md b/deploy/compose/README.md index bb0e63fe15..ccdde119bd 100644 --- a/deploy/compose/README.md +++ b/deploy/compose/README.md @@ -43,6 +43,10 @@ keypair. `.minio`. It is not configurable for an external S3 provider through `.env`; use the Helm chart or a custom Compose configuration for providers such as new Railway Storage Buckets that require `virtual` addressing. +- `git-data-init` chowns the `buzz-git-data` volume to uid/gid `1000` before + the relay starts. Fresh Docker named volumes are root-owned; without this + step the non-root relay cannot create `/data/git/.pack-cache` and + restart-loops. Run `./run.sh backup-hint` for the backup checklist. diff --git a/deploy/compose/compose.yml b/deploy/compose/compose.yml index 15337c92a2..3da531bb4d 100644 --- a/deploy/compose/compose.yml +++ b/deploy/compose/compose.yml @@ -33,6 +33,8 @@ services: condition: service_healthy minio-init: condition: service_completed_successfully + git-data-init: + condition: service_completed_successfully # Probe /_readiness over /dev/tcp because the runtime image has bash but no curl/wget/socat. healthcheck: test: @@ -121,6 +123,19 @@ services: networks: - buzz-net + # Named volumes are root-owned on first create; the relay runs as uid 1000 + # (Dockerfile USER buzz) and must create BUZZ_GIT_PACK_CACHE_PATH under + # /data/git. Mirror the minio-init pattern so a fresh stack reaches healthy. + git-data-init: + image: busybox:1.37.0 + user: "0:0" + volumes: + - buzz-git-data:/data/git + command: ["sh", "-ec", "chown -R 1000:1000 /data/git"] + restart: "no" + networks: + - buzz-net + volumes: buzz-postgres-data: labels: From 732ee1c5ba919d79d6e25c90bfe7d0511f5ee6c8 Mon Sep 17 00:00:00 2001 From: Taksh Date: Sat, 25 Jul 2026 08:03:07 +0300 Subject: [PATCH 2/3] fix(admin): print nsec/npub from generate-key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Self-hosters paste the printed secret into desktop onboarding, which expects nsec1 — hex-only output left that path stuck. Closes #2815 Signed-off-by: Taksh --- crates/buzz-admin/src/main.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/buzz-admin/src/main.rs b/crates/buzz-admin/src/main.rs index bb30ddfae4..d6ec6ecd88 100644 --- a/crates/buzz-admin/src/main.rs +++ b/crates/buzz-admin/src/main.rs @@ -28,7 +28,7 @@ use buzz_core::tenant::{relay_url_authority, TenantContext}; use buzz_db::{Db, DbConfig}; use buzz_pubsub::{EventTopic, PubSubManager}; use clap::{Parser, Subcommand}; -use nostr::{EventBuilder, Keys, Kind, Tag}; +use nostr::{EventBuilder, Keys, Kind, Tag, ToBech32}; use tracing::warn; #[derive(Parser)] @@ -131,9 +131,21 @@ async fn run(cli: Cli) -> Result { match cli.command { Command::GenerateKey => { let keys = Keys::generate(); - println!("Public key: {}", keys.public_key().to_hex()); - println!("Secret key: {}", keys.secret_key().display_secret()); - println!("\nSet BUZZ_PRIVATE_KEY to the secret key to use this identity."); + let npub = keys + .public_key() + .to_bech32() + .map_err(|e| anyhow::anyhow!("encode npub: {e}"))?; + let nsec = keys + .secret_key() + .to_bech32() + .map_err(|e| anyhow::anyhow!("encode nsec: {e}"))?; + println!("Public key (hex): {}", keys.public_key().to_hex()); + println!("Public key (npub): {npub}"); + println!("Secret key (hex): {}", keys.secret_key().display_secret()); + println!("Secret key (nsec): {nsec}"); + println!( + "\nSet BUZZ_PRIVATE_KEY to the hex or nsec secret. Desktop onboarding accepts nsec." + ); Ok(0) } Command::Migrate => { From eb76289802f9265474e9ece5c900efa0cbe9a9e4 Mon Sep 17 00:00:00 2001 From: Taksh Date: Sat, 25 Jul 2026 08:03:07 +0300 Subject: [PATCH 3/3] fix(desktop): offer self-hosted relay on owner onboarding "I own the community" previously only opened Builderlab. Self-hosters need a relay URL path; keep hosted sign-in as a second choice. Closes #2816 Signed-off-by: Taksh --- .../features/communities/ui/WelcomeSetup.tsx | 81 ++++++++++++++++++- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/desktop/src/features/communities/ui/WelcomeSetup.tsx b/desktop/src/features/communities/ui/WelcomeSetup.tsx index bde1458222..f924648817 100644 --- a/desktop/src/features/communities/ui/WelcomeSetup.tsx +++ b/desktop/src/features/communities/ui/WelcomeSetup.tsx @@ -21,7 +21,13 @@ import { Button } from "@/shared/ui/button"; import { Card } from "@/shared/ui/card"; import { StartupWindowDragRegion } from "@/shared/ui/StartupWindowDragRegion"; -type WelcomeSetupPage = "welcome" | "existing" | "join" | "member" | "owned"; +type WelcomeSetupPage = + | "welcome" + | "existing" + | "owner" + | "join" + | "member" + | "owned"; type WelcomeTransitionMode = "initial" | OnboardingTransitionDirection; type WelcomeSetupProps = { @@ -41,6 +47,11 @@ export function WelcomeSetup({ const [page, setPage] = React.useState(initialPage); const [transitionMode, setTransitionMode] = React.useState(initialTransitionMode); + // Where "member" (relay URL) was entered from, so Back returns correctly + // for both "I'm a member" and "Connect a self-hosted relay". + const [memberBackPage, setMemberBackPage] = React.useState< + "existing" | "owner" | "welcome" + >("existing"); // While true, the Builderlab sign-in modal floats over the current page — // we only navigate to the hosted stage once sign-in completes, so the page // behind the modal never changes out from under the user. @@ -199,7 +210,7 @@ export function WelcomeSetup({ > + ) : page === "owner" ? ( + +
+

+ Connect the community you own +

+

+ Self-hosted relays connect by URL. Hosted communities use + Builderlab sign-in. +

+
+
+ + + + + + +
+ + + +
) : page === "owned" ? ( - showPage(page === "member" ? "existing" : "welcome") + showPage(page === "member" ? memberBackPage : "welcome") } onConnect={startConnection} onRedeem={redeemInvite}