From d129b354b5cc40db99a362a3e531b56e8a9f23a6 Mon Sep 17 00:00:00 2001 From: "Marcelo M. Maciel" <4993482+marcelo-maciel@users.noreply.github.com> Date: Sat, 26 Sep 2026 15:49:39 -0300 Subject: [PATCH 1/3] docs: frontend containers re-render config.json on every start --- src/content/docs/changelog/index.mdx | 6 +++++- src/content/docs/frontend/development.mdx | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/content/docs/changelog/index.mdx b/src/content/docs/changelog/index.mdx index f01d8a12..38670753 100644 --- a/src/content/docs/changelog/index.mdx +++ b/src/content/docs/changelog/index.mdx @@ -1,6 +1,6 @@ --- title: Overview -lastUpdated: 2026-09-25 +lastUpdated: 2026-09-26 description: Release notes and version history for fullstackhero. sidebar: order: 1 @@ -11,6 +11,10 @@ seo: Notable changes to the kit, newest first. +## 2026-09-26 + +- **Frontend containers: admin and dashboard survive a restart (fix).** Both images rendered `/config.json` from `/usr/share/nginx/html/config.json.template` at startup and then deleted the template so it wouldn't be served. A container's filesystem outlives a restart, so the next start of the same container - `docker restart`, a Docker daemon restart, or a host reboot under `restart: unless-stopped` - found no template, failed with `can't open /usr/share/nginx/html/config.json.template: no such file` under `set -e`, and crash-looped forever. The template now lives at `/etc/fsh/config.json.template`, outside the web root, so it is still never served, and `config.json` is re-rendered from it on every start. **Upgrade note:** rebuild the admin and dashboard images. A container already stuck in the loop is fixed by recreating it (`docker compose up -d --force-recreate admin dashboard`), even before you upgrade - a fresh container gets the template back until its next restart. See [#PRNUM](https://github.com/fullstackhero/dotnet-starter-kit/pull/PRNUM). + ## 2026-09-25 - **Dependencies: .NET Aspire 13.5.4 and every NuGet package to latest.** The AppHost SDK and `Aspire.Hosting.*` move 13.4.0 → 13.5.4 together (mixing 13.4 and 13.5 packages fails at runtime). The .NET 10 platform packages (ASP.NET Core, EF Core, Extensions, SignalR) go 10.0.8 → 10.0.12, OpenTelemetry 1.15 → 1.19, Asp.Versioning 10.2, Npgsql EF 10.0.3, Scalar 2.17, QuestPDF 2026.9, Hangfire 1.8.25, MailKit/MimeKit 4.18, Testcontainers 4.15, and the rest to latest stable. Three majors: **StackExchange.Redis 3.3** (the same API as 2.13.17 on a rewritten IO core, now **RESP3 by default** - Valkey and ElastiCache both speak it; `Execute("FLUSHALL")`-style admin commands now need `AllowAdmin`), **NSubstitute 6** and **xunit.runner.visualstudio 4** (still runs xUnit v2). `Microsoft.OpenApi` and `MessagePack` stay on their 2.x lines on purpose. The new SonarAnalyzer adds **S8969** (redundant null-forgiving `!`), which is fatal under warnings-as-errors: the kit's own code is cleaned up, but **if you've added code, expect S8969 build errors after pulling** - delete the flagged `!`, and the compiler will tell you if one was actually needed. Asp.Versioning 10.2's `AV0029`/`AV0030` advisories and Aspire's `ASPIRE010` (CLI bundle) are suppressed; the kit keeps one OpenAPI document per version and runs Aspire via `dotnet run`. On the first launch Aspire 13.5 recreates the persistent Postgres and Valkey containers; data volumes are kept and the Postgres image stays on 18, so no wipe is needed. See [#1396](https://github.com/fullstackhero/dotnet-starter-kit/pull/1396). diff --git a/src/content/docs/frontend/development.mdx b/src/content/docs/frontend/development.mdx index cec4b12b..c2741bb2 100644 --- a/src/content/docs/frontend/development.mdx +++ b/src/content/docs/frontend/development.mdx @@ -1,6 +1,6 @@ --- title: Local development -lastUpdated: 2026-09-25 +lastUpdated: 2026-09-26 description: Running the React frontends with Vite HMR, building for production, deploying to static hosts or behind Nginx, runtime config via /config.json. sidebar: label: Local development @@ -114,12 +114,14 @@ The dashboard's variant swaps `dashboardUrl` for a `demoMode` flag (login-page d : "${FSH_API_URL:?FSH_API_URL is required (e.g. https://api.example.com)}" : "${FSH_DEFAULT_TENANT:=root}" -envsubst < /usr/share/nginx/html/config.json.template \ +envsubst < /etc/fsh/config.json.template \ > /usr/share/nginx/html/config.json exec nginx -g 'daemon off;' ``` +The template lives at `/etc/fsh/config.json.template`, outside the web root, so it is never served and `config.json` is re-rendered on every start - restarting the same container is safe. + ```jsonc // clients/admin/docker/config.json.template { From ab67df89d7e76788b19d98c796615cff19420df5 Mon Sep 17 00:00:00 2001 From: "Marcelo M. Maciel" <4993482+marcelo-maciel@users.noreply.github.com> Date: Sat, 26 Sep 2026 15:52:18 -0300 Subject: [PATCH 2/3] docs: link the changelog entry to #1400 --- src/content/docs/changelog/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/changelog/index.mdx b/src/content/docs/changelog/index.mdx index 38670753..cbc82f56 100644 --- a/src/content/docs/changelog/index.mdx +++ b/src/content/docs/changelog/index.mdx @@ -13,7 +13,7 @@ Notable changes to the kit, newest first. ## 2026-09-26 -- **Frontend containers: admin and dashboard survive a restart (fix).** Both images rendered `/config.json` from `/usr/share/nginx/html/config.json.template` at startup and then deleted the template so it wouldn't be served. A container's filesystem outlives a restart, so the next start of the same container - `docker restart`, a Docker daemon restart, or a host reboot under `restart: unless-stopped` - found no template, failed with `can't open /usr/share/nginx/html/config.json.template: no such file` under `set -e`, and crash-looped forever. The template now lives at `/etc/fsh/config.json.template`, outside the web root, so it is still never served, and `config.json` is re-rendered from it on every start. **Upgrade note:** rebuild the admin and dashboard images. A container already stuck in the loop is fixed by recreating it (`docker compose up -d --force-recreate admin dashboard`), even before you upgrade - a fresh container gets the template back until its next restart. See [#PRNUM](https://github.com/fullstackhero/dotnet-starter-kit/pull/PRNUM). +- **Frontend containers: admin and dashboard survive a restart (fix).** Both images rendered `/config.json` from `/usr/share/nginx/html/config.json.template` at startup and then deleted the template so it wouldn't be served. A container's filesystem outlives a restart, so the next start of the same container - `docker restart`, a Docker daemon restart, or a host reboot under `restart: unless-stopped` - found no template, failed with `can't open /usr/share/nginx/html/config.json.template: no such file` under `set -e`, and crash-looped forever. The template now lives at `/etc/fsh/config.json.template`, outside the web root, so it is still never served, and `config.json` is re-rendered from it on every start. **Upgrade note:** rebuild the admin and dashboard images. A container already stuck in the loop is fixed by recreating it (`docker compose up -d --force-recreate admin dashboard`), even before you upgrade - a fresh container gets the template back until its next restart. See [#1400](https://github.com/fullstackhero/dotnet-starter-kit/pull/1400). ## 2026-09-25 From bb059b72ea3c2fad10db1e7658a6f6f0ef9db69f Mon Sep 17 00:00:00 2001 From: "Marcelo M. Maciel" <4993482+marcelo-maciel@users.noreply.github.com> Date: Sat, 26 Sep 2026 16:14:24 -0300 Subject: [PATCH 3/3] docs: note the LF fix for the front-end image files --- src/content/docs/changelog/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/changelog/index.mdx b/src/content/docs/changelog/index.mdx index cbc82f56..cf5b6c84 100644 --- a/src/content/docs/changelog/index.mdx +++ b/src/content/docs/changelog/index.mdx @@ -13,7 +13,7 @@ Notable changes to the kit, newest first. ## 2026-09-26 -- **Frontend containers: admin and dashboard survive a restart (fix).** Both images rendered `/config.json` from `/usr/share/nginx/html/config.json.template` at startup and then deleted the template so it wouldn't be served. A container's filesystem outlives a restart, so the next start of the same container - `docker restart`, a Docker daemon restart, or a host reboot under `restart: unless-stopped` - found no template, failed with `can't open /usr/share/nginx/html/config.json.template: no such file` under `set -e`, and crash-looped forever. The template now lives at `/etc/fsh/config.json.template`, outside the web root, so it is still never served, and `config.json` is re-rendered from it on every start. **Upgrade note:** rebuild the admin and dashboard images. A container already stuck in the loop is fixed by recreating it (`docker compose up -d --force-recreate admin dashboard`), even before you upgrade - a fresh container gets the template back until its next restart. See [#1400](https://github.com/fullstackhero/dotnet-starter-kit/pull/1400). +- **Frontend containers: admin and dashboard survive a restart (fix).** Both images rendered `/config.json` from `/usr/share/nginx/html/config.json.template` at startup and then deleted the template so it wouldn't be served. A container's filesystem outlives a restart, so the next start of the same container - `docker restart`, a Docker daemon restart, or a host reboot under `restart: unless-stopped` - found no template, failed with `can't open /usr/share/nginx/html/config.json.template: no such file` under `set -e`, and crash-looped forever. The template now lives at `/etc/fsh/config.json.template`, outside the web root, so it is still never served, and `config.json` is re-rendered from it on every start. The files copied into both images are now checked out with LF line endings on every platform, so an image built on Windows no longer serves `config.json` with CRLF. **Upgrade note:** rebuild the admin and dashboard images. A container already stuck in the loop is fixed by recreating it (`docker compose up -d --force-recreate admin dashboard`), even before you upgrade - a fresh container gets the template back until its next restart. See [#1400](https://github.com/fullstackhero/dotnet-starter-kit/pull/1400). ## 2026-09-25