3.5 KiB
astro-docs — Docker deployment
Single container. Astro + Starlight, served by the Astro Node adapter on port 7701. TLS, hostname routing, and auth stay with your existing nginx + Authelia.
1. Create the app source
These Docker files expect an Astro project alongside them. There isn't one yet — generate it:
npm create astro@latest astro-docs -- --template starlight
Copy Dockerfile, .dockerignore, and compose.yaml into the generated project, then add the
Node adapter:
npx astro add node
2. Required config
astro.config.mjs must produce a standalone server — the container runs dist/server/entry.mjs:
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
import starlight from '@astrojs/starlight';
export default defineConfig({
site: 'https://docs.example.org', // public URL served by nginx
output: 'server',
adapter: node({ mode: 'standalone' }),
integrations: [starlight({ title: 'astro-docs' })],
});
Starlight prerenders its routes, so pages are static output; the Node server just delivers them.
package.json needs "build": "astro build" (the Starlight template includes it).
Commit package-lock.json. Without it the image build falls back to npm install, which gives
up reproducible dependency versions.
3. Deploy via Dockhand
Dockhand expects the stack at {DATA_DIR}/stacks/{environment}/astro-docs/compose.yaml. Because
this stack builds from source, the whole project has to live in that directory — Dockhand's Git
auto-sync is the intended way to get it there.
- Push the project (app source + these Docker files) to Gitea.
- Create the
astro-docsstack in Dockhand and point its Git sync at that repo, so the stack directory is populated from the repo rather than by hand. - Set
TZin Dockhand's encrypted environment editor. Do not commit a.env— auto-sync will overwrite it.TZis the only variable; everything else is fixed incompose.yaml. - Deploy. The first run builds the image on the NAS, which takes several minutes.
- Verify over SSH on the NAS:
curl -I http://localhost:7701/
- Point an nginx vhost at
http://<nas-ip>:7701, and decide whether it sits behind Authelia or is publicly readable.
Faster alternative: build off-NAS
Building on NAS hardware is slow and memory-hungry. To build on your workstation and push to
Gitea's registry instead, drop the build: block from compose.yaml and set
image: <gitea-host>/<user>/astro-docs:latest. Dockhand then only pulls, and the stack
directory needs nothing but compose.yaml.
4. Publishing content changes
The image holds a build artifact, so edits under src/content/docs/ go live only after a
rebuild — push to Gitea, then trigger Dockhand's rebuild/redeploy on the stack.
Notes
- No
name:orcontainer_name:— they collide across Dockhand environments. - No bind mounts: this stack is stateless, so nothing survives or needs to survive a redeploy.
platform: linux/amd64is pinned for Synology x86 hardware. Remove that line on ARM models.- Runs as the non-root
nodeuser, read-only root filesystem,/tmpon tmpfs. - The health check uses Node's built-in
fetch; the image ships no curl or wget. - Base image is
node:24-bookworm-slimrather than Alpine, because Starlight's image optimization pulls insharp, which is less trouble on glibc.
Not verified
Neither Node nor Docker is available in the environment where these files were written, so nothing here has been built or run. The first Dockhand deploy is the first real test.