Template
91 lines
3.5 KiB
Markdown
91 lines
3.5 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
npm create astro@latest astro-docs -- --template starlight
|
|
```
|
|
|
|
Copy `Dockerfile`, `.dockerignore`, and `compose.yaml` into the generated project, then add the
|
|
Node adapter:
|
|
|
|
```bash
|
|
npx astro add node
|
|
```
|
|
|
|
## 2. Required config
|
|
|
|
`astro.config.mjs` must produce a standalone server — the container runs `dist/server/entry.mjs`:
|
|
|
|
```js
|
|
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.
|
|
|
|
1. Push the project (app source + these Docker files) to Gitea.
|
|
2. Create the `astro-docs` stack in Dockhand and point its Git sync at that repo, so the stack
|
|
directory is populated from the repo rather than by hand.
|
|
3. Set `TZ` in Dockhand's encrypted environment editor. Do not commit a `.env` — auto-sync will
|
|
overwrite it. `TZ` is the only variable; everything else is fixed in `compose.yaml`.
|
|
4. Deploy. The first run builds the image on the NAS, which takes several minutes.
|
|
5. Verify over SSH on the NAS:
|
|
|
|
```bash
|
|
curl -I http://localhost:7701/
|
|
```
|
|
|
|
6. 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:` or `container_name:` — they collide across Dockhand environments.
|
|
- No bind mounts: this stack is stateless, so nothing survives or needs to survive a redeploy.
|
|
- `platform: linux/amd64` is pinned for Synology x86 hardware. Remove that line on ARM models.
|
|
- Runs as the non-root `node` user, read-only root filesystem, `/tmp` on tmpfs.
|
|
- The health check uses Node's built-in `fetch`; the image ships no curl or wget.
|
|
- Base image is `node:24-bookworm-slim` rather than Alpine, because Starlight's image
|
|
optimization pulls in `sharp`, 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.
|