- Home
- Docs Builder
- Docker Build
Docker Build
The builder ships as a Docker image. Content repos run it to produce static HTML without installing Node.js or Astro locally.
Dockerfile
Section titled “Dockerfile”docker/Dockerfile uses a multi-step build on node:24-alpine:
FROM node:24-alpine AS builderWORKDIR /app
# Install deps (cached layer)COPY package*.json ./RUN npm ci
# Copy framework codeCOPY . .
# Remove placeholder contentRUN rm -rf src/content/docs/*
COPY docker/entrypoint.sh /entrypoint.shRUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Layer Strategy
Section titled “Layer Strategy”| Layer | What | Why cached separately |
|---|---|---|
| 1 | COPY package*.json + npm ci | Dependencies change infrequently; caching this layer avoids re-downloading on every build |
| 2 | COPY . . | Framework source code |
| 3 | rm -rf src/content/docs/* | Cleans out any placeholder content so only injected content appears |
| 4 | COPY entrypoint.sh | Build orchestration script |
Entrypoint
Section titled “Entrypoint”docker/entrypoint.sh runs each time the container starts. It performs these steps in order:
Step 1: Update Dependencies
Section titled “Step 1: Update Dependencies”npm installnpm updateEnsures the theme package and all dependencies are at their latest compatible versions.
Step 2: Copy Theme Config
Section titled “Step 2: Copy Theme Config”cp /app/node_modules/@f5xc-salesdemos/docs-theme/astro.config.mjs /app/astro.config.mjscp /app/node_modules/@f5xc-salesdemos/docs-theme/src/content.config.ts /app/src/content.config.tsCopies astro.config.mjs and content.config.ts from the theme package. The theme is the single source of truth for Astro configuration — see Architecture for the theme system design.
Step 3: Inject Content
Section titled “Step 3: Inject Content”if [ -d "$CONTENT_DIR" ]; then cp -r "$CONTENT_DIR"/* /app/src/content/docs/else echo "ERROR: No content found at $CONTENT_DIR" exit 1fiCopies the mounted content into Astro’s content collection directory. Exits with an error if the content directory is missing.
Step 4: Extract Title
Section titled “Step 4: Extract Title”if [ -z "$DOCS_TITLE" ] && [ -f /app/src/content/docs/index.mdx ]; then DOCS_TITLE=$(grep -m1 '^title:' /app/src/content/docs/index.mdx | sed 's/title: *["]*//;s/["]*$//') export DOCS_TITLEfiIf DOCS_TITLE is not set via environment, extracts it from the title: frontmatter field of index.mdx.
Step 5: Extract Base Path
Section titled “Step 5: Extract Base Path”if [ -z "$DOCS_BASE" ] && [ -n "$GITHUB_REPOSITORY" ]; then DOCS_BASE="/${GITHUB_REPOSITORY#*/}" export DOCS_BASEfiDerives the site base path from the GitHub repository name (e.g., owner/my-docs becomes /my-docs).
Step 6: Build
Section titled “Step 6: Build”npm run buildRuns astro build, producing static output in /app/dist/.
Step 7: Copy Output
Section titled “Step 7: Copy Output”if [ -d "$OUTPUT_DIR" ]; then cp -r /app/dist/* "$OUTPUT_DIR"/fiCopies the built site to the output mount point.
Environment Variables
Section titled “Environment Variables”| Variable | Default | Description |
|---|---|---|
CONTENT_DIR | /content/docs | Path to the mounted content directory |
OUTPUT_DIR | /output | Path where the built site is copied |
DOCS_TITLE | (extracted from index.mdx) | Site title passed to the Astro config |
DOCS_DESCRIPTION | (extracted from index.mdx) | Site description from frontmatter |
DOCS_BASE | (derived from GITHUB_REPOSITORY) | Base path for the site (e.g., /my-docs) |
DOCS_SITE | (derived from GITHUB_REPOSITORY_OWNER) | Site URL passed to the Astro config (e.g., https://<owner>.github.io) |
GITHUB_REPOSITORY | (set by GitHub Actions) | owner/repo string used to derive DOCS_BASE |
GENERATE_PDF | false | Enable PDF generation after build |
PDF_FILENAME | docs | Output filename for the generated PDF |
LLMS_OPTIONAL_LINKS | [] | JSON array of child site URLs for the llms.txt Optional section |
Local Usage
Section titled “Local Usage”To build documentation locally using Docker:
docker run --rm \ -v "$(pwd)/docs:/content/docs" \ -v "$(pwd)/output:/output" \ ghcr.io/f5xc-salesdemos/docs-builder:latestThis mounts the local docs/ directory as content and writes the built site to output/.
For content authors who want a live dev server workflow, see Local Preview for Content Authors.
Developer: Local Dev Server
Section titled “Developer: Local Dev Server”When working on the builder itself (components, plugins, theme integration), you can run Astro’s dev server directly without Docker:
npm cicp node_modules/@f5xc-salesdemos/docs-theme/astro.config.mjs astro.config.mjscp node_modules/@f5xc-salesdemos/docs-theme/src/content.config.ts src/content.config.ts# Copy some test content into the content collectioncp -r /path/to/test-content/* src/content/docs/DOCS_TITLE="Dev Test" npx astro dev --hostOpen http://localhost:4321. Hot module replacement (HMR) works for component and plugin changes.
Image Registry
Section titled “Image Registry”The image is published to GitHub Container Registry:
ghcr.io/f5xc-salesdemos/docs-builderTwo tags are pushed on every build:
| Tag | Description |
|---|---|
latest | Most recent build from main |
<sha> | Full Git commit SHA for reproducible builds |
See CI/CD and Governance for the workflow that builds and publishes the image.