Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.git
.github
.vscode
.astro
dist
node_modules
.env*
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Build with the repo root as context: docker build .
#
# The site is fully static (astro `output: 'static'`): the build renders
# everything to dist/ and nginx serves it — no runtime env needed. On hotbox,
# create a GitHub service pointing at this repo (Dockerfile at the root) and
# set the service's public port to 8080.

FROM node:22-slim AS builder
WORKDIR /app

# Bun is the package manager (bun.lockb); the official binary from the
# oven/bun image runs fine on the same debian base.
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun

COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile

COPY . .

# Sentry sourcemap upload self-disables (no auth token set), same as CI.
ENV ASTRO_TELEMETRY_DISABLED=1
RUN bun run build

FROM nginx:alpine AS runner
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 8080
2 changes: 1 addition & 1 deletion astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { defineConfig } from 'astro/config'
import spotlightjs from '@spotlightjs/astro'
import starlightLinksValidator from 'starlight-links-validator'

const SITE_URL = 'https://docs.efp.app/'
const SITE_URL = 'https://docs.efp.rip/'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 SITE_URL hardcoded to hotbox domain bakes wrong canonicals into every build

SITE_URL is now https://docs.efp.rip/ in the shared astro.config.ts. Because output: 'static', every build — including the CI job in checks.yml that presumably still deploys to docs.efp.app — will emit canonical <link> tags, sitemap entries, og:image, and twitter:image metadata pointing at docs.efp.rip. Any page served from docs.efp.app will tell search engines its canonical URL is on a different domain, which is a direct SEO regression for the existing deployment.

The standard fix is to read the URL from an environment variable with the current domain as the fallback: const SITE_URL = process.env.SITE_URL ?? 'https://docs.efp.app/', then set SITE_URL=https://docs.efp.rip/ in the hotbox service environment. That way each deployment gets its own canonical base without touching shared config.

Fix in Conductor Fix in Cursor Fix in Codex Fix in Claude Code


// https://astro.build/config
export default defineConfig({
Expand Down
21 changes: 21 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
server {
listen 8080;
root /usr/share/nginx/html;
index index.html;
Comment on lines +1 to +4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Without server_tokens off, nginx advertises its exact version string in the Server response header and in default error pages (e.g. nginx/1.27.3), making it trivial to target known CVEs for that version. This is a quick hardening win with no functional cost.

Suggested change
server {
listen 8080;
root /usr/share/nginx/html;
index index.html;
server {
listen 8080;
server_tokens off;
root /usr/share/nginx/html;
index index.html;

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Conductor Fix in Cursor Fix in Codex Fix in Claude Code


gzip on;
gzip_types text/css application/javascript application/json image/svg+xml text/plain;
Comment on lines +6 to +7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing gzip_vary on. Without it, a caching proxy that has stored the gzip-encoded response will serve it to clients that did not send Accept-Encoding: gzip, causing garbled output for those clients. gzip_vary adds Vary: Accept-Encoding to gzip'd responses so proxy caches can distinguish between compressed and uncompressed variants.

Suggested change
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml text/plain;
gzip on;
gzip_vary on;
gzip_types text/css application/javascript application/json image/svg+xml text/plain;

Fix in Conductor Fix in Cursor Fix in Codex Fix in Claude Code


# Astro emits content-hashed assets under /_astro/ — safe to cache forever.
location /_astro/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}

# Starlight generates a 404.html page.
error_page 404 /404.html;

location / {
# Pages are built in 'directory' format: <path>/index.html
try_files $uri $uri/index.html $uri/ =404;
}
}
Loading