mirror of
https://github.com/andwati/andwati.com.git
synced 2026-11-04 08:42:16 +00:00
Nav bar & layout consistency - Base.astro's `wide` layout now defaults on for every page (was opt-in), fixing the nav bar wrapping differently depending on page width - Icon buttons for search and theme toggle (magnifying glass, sun/moon), replacing the plain "Search" text link and the "◐" glyph - Search is now a Cmd/Ctrl+K modal over Pagefind (lazy-loaded on first open) instead of a separate /search/ page, matching the old site - Fixed the article page's TOC sitting with unwanted left padding relative to the header (grid was center-justified instead of start-justified) Smooth navigation - Added Astro's ClientRouter for animated page transitions - Every page-local script that only ran once at module load (three.js hero, minimap, comments, book-spine carousel, scroll-to-top, reading progress, theme toggle, Pagefind init) now re-initializes via astro:page-load, with AbortController-based cleanup so window/document listeners don't accumulate across client-side navigations Restored from the legacy Zola site - Reading progress bar (article pages) and scroll-to-top button - Share buttons (X, Bluesky, LinkedIn, Reddit, HN, email) on writings - Prev/next post navigation with the old label/title layout - Utterances comments, wired to andwati/andwati.com with dark/light theme sync - YouTube embeds: any plain <iframe src="...youtube-nocookie.com..."> is now auto-wrapped in a responsive 16:9 container, gets loading="lazy", and emits VideoObject JSON-LD — no shortcode needed - LaTeX: $inline$ and $$block$$ math renders to static HTML via KaTeX at build time (no client-side JS shipped for it) - Tags page redesigned as a centered, alphabetical tag cloud Removed the related-posts section per request. Accessibility & contrast - --accent (#d1502f) measured 4.0:1 on the light background, just under WCAG AA's 4.5:1 for normal text — darkened to #a84025 (5.7:1), plus matching light-mode-only fixes for the two hljs syntax colors and the tip/warning callout colors that had the same problem in light mode - Fixed heading-order violations (h1 straight to h3 with nothing at h2) across the homepage, writings/portfolio/bookshelf/blogs lists, and tag pages — introduced a shared .entry-title class for the h2 list titles - Fixed inconsistent title-link underline colors: a plain <a> carries its own default underline (in its own text color) instead of matching its parent heading's accent-colored one — h1/h2/h3 anchors now explicitly inherit the heading's decoration - Bookshelf spine colors are generated per-title from a hash; the lightness-based text-color heuristic could still produce sub-4.5:1 contrast for some hues (e.g. green) — now computes real WCAG contrast and adjusts Performance - The three.js homepage hero was the single largest main-thread cost site-wide (dragging that page's Lighthouse performance score to the low 80s while every other page scored 95+): three.js is now dynamically imported only once the browser is idle (WebGL-support check split into its own tiny module so unsupported browsers never fetch it at all), the render loop is capped to ~30fps, and hover raycasting only runs on an actual pointer move instead of every frame SEO & structured data - Self-referential canonical links site-wide (with override support for posts first published elsewhere) - Sitewide WebSite/Person JSON-LD, plus per-article BlogPosting, BreadcrumbList, and (when applicable) VideoObject JSON-LD - robots.txt explicitly welcomes AI/LLM crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, CCBot, etc.) and points at llms.txt - Added an Atom feed (RSS and JSON Feed already existed) - Sitemap now sets <lastmod> per entry from its own date/updated frontmatter instead of leaving every URL at build time Analytics & comments infra - Self-hosted Umami wiring via PUBLIC_UMAMI_SCRIPT_URL/WEBSITE_ID (apps/site/.env.example), no-ops until both are set - sws.toml's CSP updated to allow utteranc.es and analytics.andwati.com — without this both were silently blocked in production Lighthouse CI - @lhci/cli wired up against the built site (mobile + desktop configs), `pnpm run lighthouse`, and a GitHub Actions workflow to run it on every push/PR — reporting only for now, no failing thresholds
111 lines
3.8 KiB
Markdown
111 lines
3.8 KiB
Markdown
# Dokploy deployment
|
|
|
|
The production deployment is one Dokploy Compose application with two
|
|
services:
|
|
|
|
- `site` builds the Astro app and serves its static output with
|
|
`static-web-server`.
|
|
- `cms` runs Strapi with persistent SQLite/admin data and a persistent Git
|
|
checkout.
|
|
|
|
Markdown remains the source of truth. A Strapi edit writes into the checkout,
|
|
commits and pushes the changed Markdown (plus a generated bookshelf cover when
|
|
applicable), then calls Dokploy's deploy webhook. The redeploy builds Astro
|
|
from that new commit.
|
|
|
|
## GitHub token
|
|
|
|
Create a fine-grained personal access token restricted to the
|
|
`andwati/andwati.com` repository with:
|
|
|
|
- Repository contents: read and write
|
|
- Metadata: read (automatically included)
|
|
|
|
The configured publishing branch must accept direct pushes from the token.
|
|
Store the token only in Dokploy as `GITHUB_TOKEN`.
|
|
|
|
## Dokploy application
|
|
|
|
1. Create a Compose application from this repository and select
|
|
`docker-compose.prod.yml`.
|
|
2. Configure its source branch to match `CONTENT_GIT_BRANCH` (normally
|
|
`main`).
|
|
3. Route the public site domain to the `site` service on port `80`.
|
|
4. Route the CMS domain (for example `cms.andwati.com`) to the `cms` service
|
|
on port `1337`.
|
|
5. Copy the application's deploy webhook URL into
|
|
`DOKPLOY_DEPLOY_WEBHOOK_URL`.
|
|
6. Add the environment variables below and deploy.
|
|
|
|
Required secrets:
|
|
|
|
```dotenv
|
|
CMS_PUBLIC_URL=https://cms.andwati.com
|
|
APP_KEYS=<four comma-separated random values>
|
|
API_TOKEN_SALT=<random value>
|
|
ADMIN_JWT_SECRET=<random value>
|
|
TRANSFER_TOKEN_SALT=<random value>
|
|
JWT_SECRET=<random value>
|
|
ENCRYPTION_KEY=<random value>
|
|
GITHUB_TOKEN=<fine-grained GitHub token>
|
|
DOKPLOY_DEPLOY_WEBHOOK_URL=<Dokploy Compose deploy webhook>
|
|
```
|
|
|
|
Optional publishing settings:
|
|
|
|
```dotenv
|
|
CONTENT_GIT_REPOSITORY=andwati/andwati.com
|
|
CONTENT_GIT_BRANCH=main
|
|
CONTENT_GIT_COMMIT_NAME="andwati.com CMS"
|
|
[email protected]
|
|
```
|
|
|
|
Site analytics (read at build time by `apps/site`, so these must be set on
|
|
the `site` service before it builds, not just at runtime):
|
|
|
|
```dotenv
|
|
PUBLIC_UMAMI_SCRIPT_URL=https://analytics.andwati.com/script.js
|
|
PUBLIC_UMAMI_WEBSITE_ID=9eef8fba-c932-4488-ae23-6b84553e8c29
|
|
```
|
|
|
|
`Analytics.astro` silently no-ops if either is unset — safe to deploy without
|
|
them, but analytics won't record anything until both are present at build
|
|
time. `sws.toml`'s CSP already allows `analytics.andwati.com` and
|
|
`utteranc.es` (comments); if the Umami host ever changes, update both that
|
|
CSP and these two vars together, or the tracker will be silently blocked in
|
|
production instead of erroring visibly.
|
|
|
|
Generate each random secret independently; do not reuse the local development
|
|
values from `docker-compose.yml`.
|
|
|
|
## Persistent data
|
|
|
|
The production Compose file declares three named volumes:
|
|
|
|
- `cms_database` keeps Strapi's admin users, API tokens, and SQLite cache.
|
|
- `cms_uploads` keeps files uploaded through Strapi.
|
|
- `content_checkout` keeps the Git working tree used for publishing.
|
|
|
|
Back up `cms_database` and `cms_uploads`. The content checkout is recoverable
|
|
from Git, but retaining it protects an edit if the process stops between the
|
|
filesystem write and Git push.
|
|
|
|
On startup, the CMS fast-forwards a clean checkout to the configured branch.
|
|
If it finds uncommitted files, it preserves them and starts without pulling so
|
|
an interrupted edit is not overwritten. Resolve and push those files from the
|
|
volume before forcing a reset.
|
|
|
|
## Local validation
|
|
|
|
Provide temporary values for required interpolation variables, then validate
|
|
the production manifest:
|
|
|
|
```sh
|
|
docker compose --env-file .env.production \
|
|
-f docker-compose.prod.yml config
|
|
docker compose --env-file .env.production \
|
|
-f docker-compose.prod.yml build
|
|
```
|
|
|
|
The existing `docker-compose.yml` remains the local Strapi development setup.
|