Compare commits

..

2 Commits

Author SHA1 Message Date
archipelago
56f956973e chore: release v1.7.74-alpha 2026-05-19 19:29:15 -04:00
archipelago
bd69ef41d5 fix(apps): repair netbird login and iframe focus 2026-05-19 19:21:43 -04:00
15 changed files with 315 additions and 111 deletions

View File

@ -1,5 +1,13 @@
# Changelog
## v1.7.74-alpha (2026-05-19)
- App-session right panels now re-focus the iframe after load and when the frame area is activated, so wheel/touch scrolling works immediately after switching tabs or selecting an app on shorter screens.
- NetBird now launches through a unified local origin on port `8087` that proxies the dashboard plus `/oauth2`, `/api`, relay, WebSocket, and gRPC routes to `netbird-server`, fixing the embedded login flow that previously ended in `Unauthenticated` or `404 page not found` after logout.
- Existing NetBird installs are repaired on adopt/start by rewriting `config.yaml`, `dashboard.env`, and the local nginx proxy config, then creating the missing `netbird-dashboard` and `netbird` proxy containers when needed while preserving NetBird data.
- Saleor is still pending and is not included in this release; its registry/installer work remains local until it can be validated separately.
- Validation passed with catalog JSON checks, `npm run type-check`, `cargo fmt --all --check --manifest-path core/Cargo.toml`, and `cargo check -p archipelago --manifest-path core/Cargo.toml`.
## v1.7.73-alpha (2026-05-19)
- Mobile app launches for iframe-blocked apps now open the direct app URL in a new browser tab immediately instead of landing in a broken in-shell webview that requires a second tap.

2
core/Cargo.lock generated
View File

@ -80,7 +80,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "archipelago"
version = "1.7.72-alpha"
version = "1.7.74-alpha"
dependencies = [
"anyhow",
"archipelago-container",

View File

@ -1,6 +1,6 @@
[package]
name = "archipelago"
version = "1.7.73-alpha"
version = "1.7.74-alpha"
edition = "2021"
description = "Archipelago Bitcoin Node OS - Native backend"
authors = ["Archipelago Team"]

View File

@ -495,7 +495,11 @@ pub(super) fn all_container_names(package_id: &str) -> Vec<String> {
"indeedhub-ffmpeg".into(),
"indeedhub".into(),
],
"netbird" => vec!["netbird".into(), "netbird-server".into()],
"netbird" => vec![
"netbird".into(),
"netbird-dashboard".into(),
"netbird-server".into(),
],
"nostr-vpn" => vec![
"nostr-vpn".into(),
"archy-nostr-vpn".into(),

View File

@ -288,7 +288,7 @@ pub(super) fn startup_order(package_id: &str) -> &'static [&'static str] {
"btcpay-server" | "btcpayserver" | "btcpay" => {
&["archy-btcpay-db", "archy-nbxplorer", "btcpay-server"]
}
"netbird" => &["netbird-server", "netbird"],
"netbird" => &["netbird-server", "netbird-dashboard", "netbird"],
"penpot" | "penpot-frontend" => &[
"penpot-postgres",
"penpot-valkey",
@ -392,7 +392,10 @@ mod tests {
#[test]
fn netbird_start_order_starts_server_before_dashboard() {
assert_eq!(startup_order("netbird"), &["netbird-server", "netbird"]);
assert_eq!(
startup_order("netbird"),
&["netbird-server", "netbird-dashboard", "netbird"]
);
}
#[test]

View File

@ -98,6 +98,7 @@ async fn repair_stack_before_adopt(stack_name: &str) {
}
}
"indeedhub" => repair_indeedhub_network_aliases().await,
"netbird" => repair_netbird_unified_origin().await,
_ => {}
}
}
@ -144,6 +145,73 @@ pub(in crate::api::rpc::package) async fn repair_indeedhub_network_aliases() {
}
}
async fn repair_netbird_unified_origin() {
let host_ip = detect_netbird_public_host_ip()
.await
.unwrap_or_else(|| "127.0.0.1".to_string());
let _ = write_netbird_config_files(&host_ip).await;
let names = tokio::process::Command::new("podman")
.args(["ps", "-a", "--format", "{{.Names}}"])
.output()
.await
.ok()
.map(|o| String::from_utf8_lossy(&o.stdout).to_string())
.unwrap_or_default();
let has_proxy = names.lines().any(|n| n.trim() == "netbird");
let has_dashboard = names.lines().any(|n| n.trim() == "netbird-dashboard");
if has_proxy && has_dashboard {
return;
}
if has_proxy && !has_dashboard {
let _ = tokio::process::Command::new("podman")
.args(["rm", "-f", "netbird"])
.output()
.await;
}
let _ = tokio::process::Command::new("podman")
.args(["network", "create", "netbird-net"])
.output()
.await;
let _ = tokio::process::Command::new("podman")
.args([
"run",
"-d",
"--name",
"netbird-dashboard",
"--network",
"netbird-net",
"--restart=unless-stopped",
"--env-file",
"/var/lib/archipelago/netbird/dashboard.env",
NETBIRD_DASHBOARD_IMAGE,
])
.output()
.await;
let _ = tokio::process::Command::new("podman")
.args([
"run",
"-d",
"--name",
"netbird",
"--network",
"netbird-net",
"--restart=unless-stopped",
"-p",
"8087:80",
"-v",
"/var/lib/archipelago/netbird/nginx.conf:/etc/nginx/conf.d/default.conf:ro",
NETBIRD_PROXY_IMAGE,
])
.output()
.await;
}
async fn run_required_stack_command(
stack_name: &str,
label: &str,
@ -313,6 +381,7 @@ const REGISTRY: &str = "146.59.87.168:3000/lfg2025";
const NETBIRD_DASHBOARD_IMAGE: &str = "docker.io/netbirdio/dashboard:v2.38.0";
const NETBIRD_SERVER_IMAGE: &str = "docker.io/netbirdio/netbird-server:0.71.2";
const NETBIRD_PROXY_IMAGE: &str = "docker.io/library/nginx:1.27-alpine";
/// Pull an image with retry and exponential backoff (3 attempts).
async fn pull_image_with_retry(image: &str) -> Result<()> {
@ -1364,8 +1433,12 @@ impl RpcHandler {
/// Install self-hosted NetBird (dashboard + combined management/signal/relay server).
pub(super) async fn install_netbird_stack(&self) -> Result<serde_json::Value> {
if let Some(adopted) =
adopt_stack_if_exists("netbird", "netbird", &["netbird", "netbird-server"]).await?
if let Some(adopted) = adopt_stack_if_exists(
"netbird",
"netbird",
&["netbird-server", "netbird-dashboard", "netbird"],
)
.await?
{
return Ok(adopted);
}
@ -1375,18 +1448,22 @@ impl RpcHandler {
self.set_install_phase("netbird", InstallPhase::PullingImage)
.await;
for (i, image) in [NETBIRD_DASHBOARD_IMAGE, NETBIRD_SERVER_IMAGE]
.iter()
.enumerate()
for (i, image) in [
NETBIRD_DASHBOARD_IMAGE,
NETBIRD_SERVER_IMAGE,
NETBIRD_PROXY_IMAGE,
]
.iter()
.enumerate()
{
self.set_install_progress("netbird", i as u64, 2).await;
self.set_install_progress("netbird", i as u64, 3).await;
pull_image_with_retry(image)
.await
.with_context(|| format!("Failed to pull NetBird image: {}", image))?;
}
self.set_install_progress("netbird", 2, 2).await;
self.set_install_progress("netbird", 3, 3).await;
for name in ["netbird", "netbird-server"] {
for name in ["netbird", "netbird-dashboard", "netbird-server"] {
let _ = tokio::process::Command::new("podman")
.args(["rm", "-f", name])
.status()
@ -1407,58 +1484,7 @@ impl RpcHandler {
let host_ip = detect_netbird_public_host_ip()
.await
.unwrap_or_else(|| self.config.host_ip.clone());
let dashboard_origin = format!("http://{}:8087", host_ip);
let mgmt_origin = format!("http://{}:8086", host_ip);
let relay_secret = read_or_generate_b64_secret("netbird-relay-auth-secret").await;
let encryption_key = read_or_generate_b64_secret("netbird-store-encryption-key").await;
let config = format!(
r#"server:
listenAddress: ":80"
exposedAddress: "{mgmt_origin}"
stunPorts:
- 3478
metricsPort: 9090
healthcheckAddress: ":9000"
logLevel: "info"
logFile: "console"
authSecret: "{relay_secret}"
dataDir: "/var/lib/netbird"
auth:
issuer: "{mgmt_origin}/oauth2"
localAuthDisabled: false
signKeyRefreshEnabled: true
dashboardRedirectURIs:
- "{dashboard_origin}/nb-auth"
- "{dashboard_origin}/nb-silent-auth"
cliRedirectURIs:
- "http://localhost:53000/"
store:
engine: "sqlite"
encryptionKey: "{encryption_key}"
"#
);
tokio::fs::write("/var/lib/archipelago/netbird/config.yaml", config)
.await
.context("Failed to write NetBird config.yaml")?;
let dashboard_env = format!(
r#"NETBIRD_MGMT_API_ENDPOINT={mgmt_origin}
NETBIRD_MGMT_GRPC_API_ENDPOINT={mgmt_origin}
AUTH_AUDIENCE=netbird-dashboard
AUTH_CLIENT_ID=netbird-dashboard
AUTH_CLIENT_SECRET=
AUTH_AUTHORITY={mgmt_origin}/oauth2
USE_AUTH0=false
AUTH_SUPPORTED_SCOPES=openid profile email groups
AUTH_REDIRECT_URI=/nb-auth
AUTH_SILENT_REDIRECT_URI=/nb-silent-auth
NGINX_SSL_PORT=443
LETSENCRYPT_DOMAIN=none
"#
);
tokio::fs::write("/var/lib/archipelago/netbird/dashboard.env", dashboard_env)
.await
.context("Failed to write NetBird dashboard.env")?;
write_netbird_config_files(&host_ip).await?;
let _ = tokio::process::Command::new("podman")
.args(["network", "create", "netbird-net"])
@ -1499,19 +1525,39 @@ LETSENCRYPT_DOMAIN=none
"run",
"-d",
"--name",
"netbird",
"netbird-dashboard",
"--network",
"netbird-net",
"--restart=unless-stopped",
"-p",
"8087:80",
"--env-file",
"/var/lib/archipelago/netbird/dashboard.env",
NETBIRD_DASHBOARD_IMAGE,
]);
run_required_stack_command("netbird", "create dashboard", &mut dashboard_cmd).await?;
wait_for_stack_containers("netbird", &["netbird-server", "netbird"], 60).await?;
let mut proxy_cmd = tokio::process::Command::new("podman");
proxy_cmd.args([
"run",
"-d",
"--name",
"netbird",
"--network",
"netbird-net",
"--restart=unless-stopped",
"-p",
"8087:80",
"-v",
"/var/lib/archipelago/netbird/nginx.conf:/etc/nginx/conf.d/default.conf:ro",
NETBIRD_PROXY_IMAGE,
]);
run_required_stack_command("netbird", "create unified proxy", &mut proxy_cmd).await?;
wait_for_stack_containers(
"netbird",
&["netbird-server", "netbird-dashboard", "netbird"],
60,
)
.await?;
self.set_install_phase("netbird", InstallPhase::WaitingHealthy)
.await;
@ -1546,6 +1592,104 @@ async fn read_or_generate_b64_secret(name: &str) -> String {
secret
}
async fn write_netbird_config_files(host_ip: &str) -> Result<()> {
let public_origin = format!("http://{}:8087", host_ip);
let server_origin = format!("http://{}:8086", host_ip);
let relay_secret = read_or_generate_b64_secret("netbird-relay-auth-secret").await;
let encryption_key = read_or_generate_b64_secret("netbird-store-encryption-key").await;
let config = format!(
r#"server:
listenAddress: ":80"
exposedAddress: "{public_origin}"
stunPorts:
- 3478
metricsPort: 9090
healthcheckAddress: ":9000"
logLevel: "info"
logFile: "console"
authSecret: "{relay_secret}"
dataDir: "/var/lib/netbird"
auth:
issuer: "{public_origin}/oauth2"
localAuthDisabled: false
signKeyRefreshEnabled: true
dashboardRedirectURIs:
- "{public_origin}/nb-auth"
- "{public_origin}/nb-silent-auth"
cliRedirectURIs:
- "http://localhost:53000/"
store:
engine: "sqlite"
encryptionKey: "{encryption_key}"
"#
);
tokio::fs::write("/var/lib/archipelago/netbird/config.yaml", config)
.await
.context("Failed to write NetBird config.yaml")?;
let dashboard_env = format!(
r#"NETBIRD_MGMT_API_ENDPOINT={public_origin}
NETBIRD_MGMT_GRPC_API_ENDPOINT={public_origin}
AUTH_AUDIENCE=netbird-dashboard
AUTH_CLIENT_ID=netbird-dashboard
AUTH_CLIENT_SECRET=
AUTH_AUTHORITY={public_origin}/oauth2
USE_AUTH0=false
AUTH_SUPPORTED_SCOPES=openid profile email groups
AUTH_REDIRECT_URI=/nb-auth
AUTH_SILENT_REDIRECT_URI=/nb-silent-auth
NETBIRD_TOKEN_SOURCE=accessToken
NGINX_SSL_PORT=443
LETSENCRYPT_DOMAIN=none
"#
);
tokio::fs::write("/var/lib/archipelago/netbird/dashboard.env", dashboard_env)
.await
.context("Failed to write NetBird dashboard.env")?;
let nginx_conf = format!(
r#"server {{
listen 80;
server_name _;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
location ~ ^/(relay|ws-proxy/) {{
proxy_pass http://netbird-server:80;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 1d;
}}
location ~ ^/(api|oauth2)/ {{
proxy_pass http://netbird-server:80;
}}
location ~ ^/(signalexchange\.SignalExchange|management\.ManagementService)/ {{
grpc_pass grpc://netbird-server:80;
grpc_read_timeout 1d;
grpc_send_timeout 1d;
}}
location / {{
proxy_pass http://netbird-dashboard:80;
}}
}}
# Direct server remains available for diagnostics at {server_origin}.
"#
);
tokio::fs::write("/var/lib/archipelago/netbird/nginx.conf", nginx_conf)
.await
.context("Failed to write NetBird nginx.conf")?;
Ok(())
}
async fn detect_netbird_public_host_ip() -> Option<String> {
let output = tokio::process::Command::new("hostname")
.args(["-I"])

View File

@ -62,6 +62,7 @@ impl DockerPackageScanner {
"indeedhub-build_relay_1",
"indeedhub-build_ffmpeg-worker_1",
"netbird-server",
"netbird-dashboard",
"buildx_buildkit_default",
];

View File

@ -169,6 +169,7 @@ fn image_var_for_app(app_id: &str) -> Option<&'static str> {
"portainer" => Some("PORTAINER_IMAGE"),
"tailscale" => Some("TAILSCALE_IMAGE"),
"netbird" => Some("NETBIRD_DASHBOARD_IMAGE"),
"netbird-dashboard" => Some("NETBIRD_DASHBOARD_IMAGE"),
"netbird-server" => Some("NETBIRD_SERVER_IMAGE"),
// Fedimint
@ -302,7 +303,8 @@ pub fn containers_for_stack(app_id: &str) -> Vec<(&'static str, &'static str)> {
("penpot-frontend", "PENPOT_FRONTEND_IMAGE"),
],
"netbird" => vec![
("netbird", "NETBIRD_DASHBOARD_IMAGE"),
("netbird", "NETBIRD_PROXY_IMAGE"),
("netbird-dashboard", "NETBIRD_DASHBOARD_IMAGE"),
("netbird-server", "NETBIRD_SERVER_IMAGE"),
],
_ => vec![],

View File

@ -1,12 +1,12 @@
{
"name": "neode-ui",
"version": "1.7.73-alpha",
"version": "1.7.74-alpha",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "neode-ui",
"version": "1.7.73-alpha",
"version": "1.7.74-alpha",
"dependencies": {
"@types/dompurify": "^3.0.5",
"@vue-leaflet/vue-leaflet": "^0.10.1",

View File

@ -1,7 +1,7 @@
{
"name": "neode-ui",
"private": true,
"version": "1.7.73-alpha",
"version": "1.7.74-alpha",
"type": "module",
"scripts": {
"start": "./start-dev.sh",

View File

@ -9,7 +9,13 @@
</div>
</Transition>
<div v-if="appUrl && !iframeBlocked" class="absolute inset-0 app-session-frame-scroll-host">
<div
v-if="appUrl && !iframeBlocked"
class="absolute inset-0 app-session-frame-scroll-host"
tabindex="-1"
@pointerdown="focusIframe"
@focusin="focusIframe"
>
<iframe
ref="iframeRef"
:key="refreshKey"
@ -17,7 +23,7 @@
class="w-full h-full border-0 iframe-scrollbar-hide"
title="App content"
tabindex="0"
@load="$emit('iframeLoad')"
@load="handleIframeLoad"
@error="$emit('iframeError')"
/>
</div>
@ -84,7 +90,7 @@ const props = defineProps<{
refreshKey: number
}>()
defineEmits<{
const emit = defineEmits<{
iframeLoad: []
iframeError: []
refresh: []
@ -93,10 +99,20 @@ defineEmits<{
const iframeRef = ref<HTMLIFrameElement | null>(null)
function focusIframe() {
iframeRef.value?.focus({ preventScroll: true })
}
async function handleIframeLoad() {
emit('iframeLoad')
await nextTick()
requestAnimationFrame(focusIframe)
}
watch(() => [props.appUrl, props.refreshKey, props.iframeBlocked], async () => {
if (!props.appUrl || props.iframeBlocked) return
await nextTick()
iframeRef.value?.focus({ preventScroll: true })
requestAnimationFrame(focusIframe)
}, { immediate: true })
defineExpose({ iframeRef })

View File

@ -180,6 +180,31 @@ init()
</button>
</div>
<div class="overflow-y-auto flex-1 min-h-0 space-y-6 pr-1">
<!-- v1.7.74-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">
<span class="text-xs font-mono px-2 py-0.5 rounded bg-orange-500/20 text-orange-300">v1.7.74-alpha</span>
<span class="text-xs text-white/40">May 19, 2026</span>
</div>
<div class="space-y-3 text-sm text-white/80 pl-3 border-l border-white/10">
<p>App-session right panels now re-focus the iframe after load and when the frame area is activated, so scrolling works immediately after selecting an app or switching tabs on shorter screens.</p>
<p>NetBird now uses a unified local launch origin on port 8087 that serves the dashboard and proxies auth/API routes to the server, fixing the Unauthenticated and 404 logout/login loop.</p>
<p>Existing NetBird installs are repaired during adopt/start by rewriting the config files and creating the missing dashboard/proxy containers while preserving data.</p>
<p>Saleor is not in this release yet; it remains pending for separate validation.</p>
</div>
</div>
<!-- v1.7.73-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">
<span class="text-xs font-mono px-2 py-0.5 rounded bg-orange-500/20 text-orange-300">v1.7.73-alpha</span>
<span class="text-xs text-white/40">May 19, 2026</span>
</div>
<div class="space-y-3 text-sm text-white/80 pl-3 border-l border-white/10">
<p>Mobile apps that block iframe embedding now open directly in a browser tab instead of first landing in a broken in-shell webview.</p>
<p>App Store search covers all apps while searching, My Apps search can surface matching installable App Store entries, and mobile My Apps/Websites tab switching updates the view reliably.</p>
<p>NetBird installs prefer a 100.x tailnet address when available, and app sessions gained iframe auto-focus plus a scroll host for right-frame scrolling.</p>
</div>
</div>
<!-- v1.7.72-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">

View File

@ -1,29 +1,29 @@
{
"version": "1.7.73-alpha",
"version": "1.7.74-alpha",
"release_date": "2026-05-19",
"changelog": [
"Mobile app launches for iframe-blocked apps now open the direct app URL in a new browser tab immediately instead of landing in a broken in-shell webview that requires a second tap.",
"Mobile My Apps/Websites tabs now react to route query changes, App Store pages label the mobile view as Discover, mobile filters have safe bottom spacing, and App Store search ignores the current category so searches cover all available apps.",
"My Apps search now surfaces matching App Store entries when the app is not installed, making it possible to jump directly from a failed My Apps search to the installable app details.",
"NetBird self-host installs now prefer a `100.x` tailnet/CGNAT address for dashboard, management, relay, STUN, and auth redirect origins when one is present; live repair on `100.89.209.89` updated the existing stack from LAN origins to `100.89.209.89` and restored `netbird-server`.",
"App-session iframe frames now focus automatically and wrap the iframe in a scroll host so wheel/touch scrolling works in the active right frame without requiring an initial click."
"App-session right panels now re-focus the iframe after load and when the frame area is activated, so wheel/touch scrolling works immediately after switching tabs or selecting an app on shorter screens.",
"NetBird now launches through a unified local origin on port `8087` that proxies the dashboard plus `/oauth2`, `/api`, relay, WebSocket, and gRPC routes to `netbird-server`, fixing the embedded login flow that previously ended in `Unauthenticated` or `404 page not found` after logout.",
"Existing NetBird installs are repaired on adopt/start by rewriting `config.yaml`, `dashboard.env`, and the local nginx proxy config, then creating the missing `netbird-dashboard` and `netbird` proxy containers when needed while preserving NetBird data.",
"Saleor is still pending and is not included in this release; its registry/installer work remains local until it can be validated separately.",
"Validation passed with catalog JSON checks, `npm run type-check`, `cargo fmt --all --check --manifest-path core/Cargo.toml`, and `cargo check -p archipelago --manifest-path core/Cargo.toml`."
],
"components": [
{
"name": "archipelago",
"current_version": "1.7.73-alpha",
"new_version": "1.7.73-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.73-alpha/archipelago",
"sha256": "458b510e34c0d69e39294ff05eb56ed89c2eb896b72074ecaea0c2bb52477455",
"size_bytes": 42997664
"current_version": "1.7.74-alpha",
"new_version": "1.7.74-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.74-alpha/archipelago",
"sha256": "959a1d932585ad16147480f69991c3b2402cb68e2205aa3c865ec9b1167a46d7",
"size_bytes": 43008960
},
{
"name": "archipelago-frontend-1.7.73-alpha.tar.gz",
"current_version": "1.7.73-alpha",
"new_version": "1.7.73-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.73-alpha/archipelago-frontend-1.7.73-alpha.tar.gz",
"sha256": "586ee104787b8c69230f2616dd6256926299907fde53d6dd6f0015b98c5db41b",
"size_bytes": 166488057
"name": "archipelago-frontend-1.7.74-alpha.tar.gz",
"current_version": "1.7.74-alpha",
"new_version": "1.7.74-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.74-alpha/archipelago-frontend-1.7.74-alpha.tar.gz",
"sha256": "3391964df4d0ca0d798f28559f90e4f050e7e39aa8d8581343bb3c9af1f9437c",
"size_bytes": 166485358
}
]
}

View File

@ -1,29 +1,29 @@
{
"version": "1.7.73-alpha",
"version": "1.7.74-alpha",
"release_date": "2026-05-19",
"changelog": [
"Mobile app launches for iframe-blocked apps now open the direct app URL in a new browser tab immediately instead of landing in a broken in-shell webview that requires a second tap.",
"Mobile My Apps/Websites tabs now react to route query changes, App Store pages label the mobile view as Discover, mobile filters have safe bottom spacing, and App Store search ignores the current category so searches cover all available apps.",
"My Apps search now surfaces matching App Store entries when the app is not installed, making it possible to jump directly from a failed My Apps search to the installable app details.",
"NetBird self-host installs now prefer a `100.x` tailnet/CGNAT address for dashboard, management, relay, STUN, and auth redirect origins when one is present; live repair on `100.89.209.89` updated the existing stack from LAN origins to `100.89.209.89` and restored `netbird-server`.",
"App-session iframe frames now focus automatically and wrap the iframe in a scroll host so wheel/touch scrolling works in the active right frame without requiring an initial click."
"App-session right panels now re-focus the iframe after load and when the frame area is activated, so wheel/touch scrolling works immediately after switching tabs or selecting an app on shorter screens.",
"NetBird now launches through a unified local origin on port `8087` that proxies the dashboard plus `/oauth2`, `/api`, relay, WebSocket, and gRPC routes to `netbird-server`, fixing the embedded login flow that previously ended in `Unauthenticated` or `404 page not found` after logout.",
"Existing NetBird installs are repaired on adopt/start by rewriting `config.yaml`, `dashboard.env`, and the local nginx proxy config, then creating the missing `netbird-dashboard` and `netbird` proxy containers when needed while preserving NetBird data.",
"Saleor is still pending and is not included in this release; its registry/installer work remains local until it can be validated separately.",
"Validation passed with catalog JSON checks, `npm run type-check`, `cargo fmt --all --check --manifest-path core/Cargo.toml`, and `cargo check -p archipelago --manifest-path core/Cargo.toml`."
],
"components": [
{
"name": "archipelago",
"current_version": "1.7.73-alpha",
"new_version": "1.7.73-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.73-alpha/archipelago",
"sha256": "458b510e34c0d69e39294ff05eb56ed89c2eb896b72074ecaea0c2bb52477455",
"size_bytes": 42997664
"current_version": "1.7.74-alpha",
"new_version": "1.7.74-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.74-alpha/archipelago",
"sha256": "959a1d932585ad16147480f69991c3b2402cb68e2205aa3c865ec9b1167a46d7",
"size_bytes": 43008960
},
{
"name": "archipelago-frontend-1.7.73-alpha.tar.gz",
"current_version": "1.7.73-alpha",
"new_version": "1.7.73-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.73-alpha/archipelago-frontend-1.7.73-alpha.tar.gz",
"sha256": "586ee104787b8c69230f2616dd6256926299907fde53d6dd6f0015b98c5db41b",
"size_bytes": 166488057
"name": "archipelago-frontend-1.7.74-alpha.tar.gz",
"current_version": "1.7.74-alpha",
"new_version": "1.7.74-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.74-alpha/archipelago-frontend-1.7.74-alpha.tar.gz",
"sha256": "3391964df4d0ca0d798f28559f90e4f050e7e39aa8d8581343bb3c9af1f9437c",
"size_bytes": 166485358
}
]
}

View File

@ -50,6 +50,7 @@ PORTAINER_IMAGE="$ARCHY_REGISTRY/portainer:latest"
TAILSCALE_IMAGE="$ARCHY_REGISTRY/tailscale:stable"
NETBIRD_DASHBOARD_IMAGE="docker.io/netbirdio/dashboard:v2.38.0"
NETBIRD_SERVER_IMAGE="docker.io/netbirdio/netbird-server:0.71.2"
NETBIRD_PROXY_IMAGE="docker.io/library/nginx:1.27-alpine"
ALPINE_TOR_IMAGE="$ARCHY_REGISTRY/alpine-tor:0.4.8.13"
ADGUARDHOME_IMAGE="$ARCHY_REGISTRY/adguardhome:v0.107.55"