From 4a9c3a645487e4e718751d6933063c6ea95c2b4d Mon Sep 17 00:00:00 2001 From: dtonon Date: Tue, 22 Sep 2026 16:01:51 +0200 Subject: [PATCH] Add a config to manage assets when building specific instances --- .env.example | 2 +- README.md | 2 +- svelte.config.js | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index fe99724..6c96c15 100644 --- a/.env.example +++ b/.env.example @@ -17,4 +17,4 @@ PUBLIC_BLOSSOM_URL= # Blossom server URL for uploads (e.g., h # Theme color overrides — quote the value, a leading # is read as a comment otherwise PUBLIC_ACCENT_COLOR= # override the accent color (default #e32a6d), e.g. "#00ff00"; hover shade derived PUBLIC_SECONDARY_COLOR= # override the secondary color (default #ffaf25), e.g. "#0000ff"; hover shade derived -PUBLIC_FAVICON= # favicon URL (absolute, or /favicon.png for a file in static/); default is a filled circle in the accent color +PUBLIC_FAVICON= # favicon URL (absolute, or /favicon.png for a file in static/ or .local//static/); default is a filled circle in the accent color diff --git a/README.md b/README.md index 1bc50a0..bb279b2 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ Preview a build locally with `npm run preview` (static) or `node --env-file=.env `just deploy ` rsyncs the static bundle to `~/squalk/` on the host and purges the Cloudflare cache. -`just deploy-ssr ` builds with `--mode ` (so vite bakes `.env.` in), ships the Node build, `package.json`/`package-lock.json` and `.env.` (as `.env` in the app dir, since the server reads the `PUBLIC_*` values at runtime), runs `npm ci --omit=dev` and restarts the instance's systemd unit. Everything instance-specific lives in `.env..local` (gitignored, never shipped): `DEPLOY_HOST`, `DEPLOY_DIR` and `DEPLOY_SERVICE` (all required), plus the Cloudflare credentials (`CF_ZONE_ID`/`CF_API_TOKEN`) for the cache purge. Multiple instances coexist by giving each its own mode, directory, unit and port. On the host you need: +`just deploy-ssr ` builds with `--mode ` (so vite bakes `.env.` in), ships the Node build, `package.json`/`package-lock.json` and `.env.` (as `.env` in the app dir, since the server reads the `PUBLIC_*` values at runtime), runs `npm ci --omit=dev` and restarts the instance's systemd unit. Everything instance-specific lives in `.env..local` (gitignored, never shipped): `DEPLOY_HOST`, `DEPLOY_DIR` and `DEPLOY_SERVICE` (all required), plus the Cloudflare credentials (`CF_ZONE_ID`/`CF_API_TOKEN`) for the cache purge. Multiple instances coexist by giving each its own mode, directory, unit and port. Files an instance needs served at its root (a favicon, say) go in `.local//static/` (gitignored): when that folder exists, the build ships it instead of the shared `static/`. On the host you need: - Node 22 or newer (the relay client uses the built-in `WebSocket`). - The unit from [`deploy/production-example.service`](deploy/production-example.service), with `ORIGIN` set to the public URL — it feeds canonical links, `robots.txt` and the sitemap. diff --git a/svelte.config.js b/svelte.config.js index 75459b0..661e05d 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,3 +1,4 @@ +import { existsSync } from "node:fs"; import { loadEnv } from "vite"; import adapterNode from "@sveltejs/adapter-node"; import adapterStatic from "@sveltejs/adapter-static"; @@ -12,10 +13,23 @@ const env = loadEnv( ); const ssr = (process.env.PUBLIC_SSR ?? env.PUBLIC_SSR) === "yes"; +// Instance assets: a build run with `--mode ` serves the files in +// .local//static (gitignored) instead of the shared static/ folder. +const argv = process.argv; +const modeIdx = argv.findIndex((a) => a === "--mode" || a === "-m"); +const mode = + modeIdx !== -1 + ? argv[modeIdx + 1] + : argv.find((a) => a.startsWith("--mode="))?.slice(7); +const instanceAssets = mode ? `.local/${mode}/static` : undefined; +const assets = + instanceAssets && existsSync(instanceAssets) ? instanceAssets : "static"; + /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { adapter: ssr ? adapterNode() : adapterStatic({ fallback: "index.html" }), + files: { assets }, }, };