diff --git a/docs-site/astro.config.mjs b/docs-site/astro.config.mjs index 7c732a7..4e31e4f 100644 --- a/docs-site/astro.config.mjs +++ b/docs-site/astro.config.mjs @@ -6,12 +6,17 @@ import starlightOpenAPI, { openAPISidebarGroups } from "starlight-openapi"; import starlightBlog from "starlight-blog"; import starlightLinksValidator from "starlight-links-validator"; import starlightImageZoom from "starlight-image-zoom"; +import remarkPrefixBase from "./plugins/remark-prefix-base.mjs"; const githubRepo = "https://github.com/vazra/simpledeploy"; +const siteBase = "/simpledeploy"; export default defineConfig({ site: "https://vazra.github.io", - base: "/simpledeploy", + base: siteBase, + markdown: { + remarkPlugins: [[remarkPrefixBase, { base: siteBase }]], + }, integrations: [ svelte(), starlight({ @@ -45,7 +50,14 @@ export default defineConfig({ failOnError: false, errorOnRelativeLinks: false, errorOnInvalidHashes: false, - exclude: ["/reference/api", "/reference/api/**"], + exclude: [ + "/reference/api", + "/reference/api/**", + "/simpledeploy/blog", + "/simpledeploy/blog/", + "http://localhost:**", + "https://localhost:**", + ], }), starlightOpenAPI([ { diff --git a/docs-site/plugins/remark-prefix-base.mjs b/docs-site/plugins/remark-prefix-base.mjs new file mode 100644 index 0000000..90489d7 --- /dev/null +++ b/docs-site/plugins/remark-prefix-base.mjs @@ -0,0 +1,57 @@ +// Rewrites absolute internal links (e.g. "/start/quickstart/") in markdown +// and MDX content to be prefixed with the configured site base, so that +// hosting under a subpath like /simpledeploy/ does not produce 404s. +// +// Skips: external URLs, protocol-relative URLs, fragment-only links, +// already-prefixed paths, and asset paths Astro handles itself (_astro, etc). + +const DEFAULT_SKIP_PREFIXES = ["/_astro/", "/@", "/api/"]; + +function shouldRewrite(url, base) { + if (typeof url !== "string" || url.length === 0) return false; + if (!url.startsWith("/")) return false; + if (url.startsWith("//")) return false; + if (url.startsWith(base + "/") || url === base) return false; + for (const p of DEFAULT_SKIP_PREFIXES) if (url.startsWith(p)) return false; + return true; +} + +function rewrite(url, base) { + return base + url; +} + +function visitNode(node, base) { + if (!node || typeof node !== "object") return; + + if ((node.type === "link" || node.type === "image") && shouldRewrite(node.url, base)) { + node.url = rewrite(node.url, base); + } + + if (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") { + if (Array.isArray(node.attributes)) { + for (const attr of node.attributes) { + if ( + attr && + attr.type === "mdxJsxAttribute" && + (attr.name === "href" || attr.name === "src" || attr.name === "link") && + typeof attr.value === "string" && + shouldRewrite(attr.value, base) + ) { + attr.value = rewrite(attr.value, base); + } + } + } + } + + if (Array.isArray(node.children)) { + for (const child of node.children) visitNode(child, base); + } +} + +export default function remarkPrefixBase(options = {}) { + const base = (options.base || "").replace(/\/$/, ""); + if (!base) return () => {}; + return (tree) => { + visitNode(tree, base); + }; +} diff --git a/docs-site/src/content/docs/index.mdx b/docs-site/src/content/docs/index.mdx index f2a6251..71987ae 100644 --- a/docs-site/src/content/docs/index.mdx +++ b/docs-site/src/content/docs/index.mdx @@ -8,7 +8,7 @@ hero: file: ../../assets/logo.svg actions: - text: 5-Minute Quickstart - link: /start/quickstart/ + link: /simpledeploy/start/quickstart/ icon: right-arrow variant: primary - text: Star on GitHub diff --git a/docs/concepts/state-and-storage.md b/docs/concepts/state-and-storage.md index e2848e4..62dd8d6 100644 --- a/docs/concepts/state-and-storage.md +++ b/docs/concepts/state-and-storage.md @@ -56,4 +56,4 @@ The DB is itself a backup target via the System page. SimpleDeploy uses SQLite ` Copying the raw `simpledeploy.db` file while the process is running is unsafe. WAL pages may not yet be checkpointed. Use the System backup endpoint (which calls `VACUUM INTO`) or stop the process first. -For backing up your apps' data (postgres volumes, redis dumps, app files), see [Backups](/simpledeploy/concepts/backups/) and [Backup architecture](/simpledeploy/architecture/backup/). +For backing up your apps' data (postgres volumes, redis dumps, app files), see [Backups](/guides/backups/overview/) and [Backup architecture](/architecture/backup/). diff --git a/docs/first-deploy/admin.md b/docs/first-deploy/admin.md index 44437d2..e8b86c5 100644 --- a/docs/first-deploy/admin.md +++ b/docs/first-deploy/admin.md @@ -79,6 +79,6 @@ The full key is shown only once. If you lose it, revoke it and create a new one. | `admin` | All apps + most settings (no user management) | | `user` | Only the apps explicitly granted to them | -Per-app access for `user` accounts is set under **Users → (user) → App access**. See [Roles and permissions](/guides/users/roles/). +Per-app access for `user` accounts is set under **Users → (user) → App access**. See [Roles and permissions](/guides/users-roles/). Next: [write your first compose file](/first-deploy/compose/). diff --git a/docs/first-deploy/ui.md b/docs/first-deploy/ui.md index 687d8e3..4e1c82f 100644 --- a/docs/first-deploy/ui.md +++ b/docs/first-deploy/ui.md @@ -24,7 +24,7 @@ The fastest way to deploy if you already have the dashboard open. Templates ask you to pick an **Access mode** before continuing: - - **Quick test** (default): SimpleDeploy auto-generates a `..sslip.io` domain and issues a self-signed cert via Caddy's internal CA. No DNS setup needed. Browsers will warn about the certificate until you install the root cert from the [Trust page](/trust). Best for trying a template in minutes on a homelab, LAN, or VPS without public DNS. + - **Quick test** (default): SimpleDeploy auto-generates a `..sslip.io` domain and issues a self-signed cert via Caddy's internal CA. No DNS setup needed. Browsers will warn about the certificate until you install the root cert from the **Trust** page on your SimpleDeploy server (`/trust` on the server URL). Best for trying a template in minutes on a homelab, LAN, or VPS without public DNS. - **Custom domain**: You supply a real public domain and point its DNS at the server. TLS is provisioned automatically via Let's Encrypt. Best for production. - **Port only**: Skips the Caddy proxy entirely. Docker picks a random host port; you reach the app at `http://:`. Disabled for multi-endpoint templates. Best for SSH-tunnel or LAN-only testing. diff --git a/docs/first-deploy/verify.md b/docs/first-deploy/verify.md index 7bd496d..8c5f342 100644 --- a/docs/first-deploy/verify.md +++ b/docs/first-deploy/verify.md @@ -67,6 +67,6 @@ For deeper troubleshooting: [Operations → Troubleshooting](/operations/trou That is the full happy path. Next, dig in: - [Add backups](/guides/backups/overview/) for stateful services. -- [Invite teammates](/guides/users/roles/) and scope per-app access. +- [Invite teammates](/guides/users-roles/) and scope per-app access. - [Wire up a private registry](/guides/registries/) for non-public images. - [Front SimpleDeploy with a load balancer](/guides/load-balancer/) if you outgrow one VPS. diff --git a/docs/reference/directory-layout.md b/docs/reference/directory-layout.md index b391353..ff985b3 100644 --- a/docs/reference/directory-layout.md +++ b/docs/reference/directory-layout.md @@ -77,5 +77,5 @@ Managed via `simpledeploy context add|use|list`. Permissions `0600` are recommen ## See also - [Configuration](/reference/configuration/) for `data_dir` and `apps_dir` config keys. -- [Backups](/guides/backups/) for the `backups/` layout in detail. +- [Backups](/guides/backups/overview/) for the `backups/` layout in detail. - [TLS and HTTPS](/guides/tls/) for Caddy storage paths. diff --git a/docs/start/quickstart.md b/docs/start/quickstart.md index 0508b8c..6a5687b 100644 --- a/docs/start/quickstart.md +++ b/docs/start/quickstart.md @@ -132,5 +132,5 @@ Before you start: make sure ports 80 and 443 are open, Docker is installed, and - +