Skip to content
Draft
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
4 changes: 2 additions & 2 deletions .github/actions/install-cache-deps/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ runs:

- name: Install pnpm
shell: bash
run: npm install -g pnpm@9
run: npm install -g pnpm@11

- name: Get pnpm store directory
shell: bash
Expand Down Expand Up @@ -77,4 +77,4 @@ runs:
- name: ↧ Install Remaining Dependencies
shell: bash
working-directory: ${{ inputs.WORKSPACE_ROOT }}
run: pnpm install
run: pnpm install --frozen-lockfile
2 changes: 1 addition & 1 deletion .github/workflows/backstop-remote.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ permissions:

env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
NODE_VERSION: 20
NODE_VERSION: 24

jobs:
backstop:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bd-fe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ permissions:

env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
NODE_VERSION: 20
NODE_VERSION: 24

jobs:
build_deploy:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:

env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
NODE_VERSION: 20
NODE_VERSION: 24

jobs:
lint:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-backstop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ permissions:

env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
NODE_VERSION: 20
NODE_VERSION: 24

jobs:
backstop:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-lighthouse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ on:
GH_WORKFLOW_TOKEN:
required: true
env:
NODE_VERSION: 20
NODE_VERSION: 24

jobs:
lighthouse:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-psi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ permissions:

env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
NODE_VERSION: 20
NODE_VERSION: 24

jobs:
psi:
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
6 changes: 3 additions & 3 deletions _ci/backstop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
"super-simple-web-server": "github:dgrebb/super-simple-web-server#0.0.2"
},
"engines": {
"node": ">=16.0.0 <=20.x.x",
"npm": ">=6.0.0",
"pnpm": ">= 8.14.1"
"node": ">=22.0.0",
"pnpm": ">=11.0.0"
},
"packageManager": "pnpm@11.10.0",
"pnpm": {
"overrides": {
"braces@<3.0.3": ">=3.0.3",
Expand Down
6 changes: 3 additions & 3 deletions _ci/perf/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
"npm-check-updates": "^16.14.18"
},
"engines": {
"node": ">=16.0.0 <=20.x.x",
"npm": ">=6.0.0",
"pnpm": ">= 8.14.1"
"node": ">=22.0.0",
"pnpm": ">=11.0.0"
},
"packageManager": "pnpm@11.10.0",
"pnpm": {
"overrides": {
"braces@<3.0.3": ">=3.0.3",
Expand Down
4 changes: 2 additions & 2 deletions _docker/back.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -------- Base -------- #
FROM node:20-alpine AS base
FROM node:24-alpine AS base
# Installing libvips-dev for sharp Compatibility
RUN apk update && apk add --no-cache build-base \
gcc autoconf automake zlib-dev libpng-dev \
Expand All @@ -23,7 +23,7 @@ ENV NODE_ENV=${NODE_ENV}
RUN pnpm run build

# -------- Run -------- #
FROM node:20-alpine
FROM node:24-alpine
COPY --from=build /app /app
WORKDIR /app
ENV PNPM_HOME="/pnpm"
Expand Down
6 changes: 3 additions & 3 deletions back/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
"strapi-plugin-config-sync": "^1.2.5"
},
"engines": {
"node": ">=16.0.0 <=20.x.x",
"npm": ">=6.0.0",
"pnpm": ">= 8.14.1"
"node": ">=22.0.0",
"pnpm": ">=11.0.0"
},
"packageManager": "pnpm@11.10.0",
"strapi": {},
"devDependencies": {
"prop-types": "^15.8.1"
Expand Down
188 changes: 188 additions & 0 deletions docs/CMS_EVALUATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# CMS Evaluation: Strapi 5 vs Alternatives

## Executive Summary

This document evaluates CMS options for dgrebb.com with a focus on:
1. Cost reduction (eliminating RDS/load balancer)
2. SSG compatibility for GitHub Actions builds
3. Migration effort from Strapi 4.25.2

## Current Architecture

- **CMS**: Strapi 4.25.2
- **Database**: PostgreSQL 15.5 on AWS RDS
- **Infrastructure**: ECS/Fargate + ALB
- **Front-end**: SvelteKit with SSG (adapter-static)
- **Content Types**: 25 API endpoints

## Option 1: Strapi 5 with SQLite

### Overview
Upgrade to Strapi 5 and switch from PostgreSQL to SQLite for cost reduction.

### Pros
- Minimal migration effort (same API structure)
- No database server required
- SQLite 3 fully supported in Strapi 5
- Uses `better-sqlite3` package (modernized WAL mode)
- Eliminates RDS costs (~$15-30/month)

### Cons
- **Not recommended for production** by Strapi
- SQLite limitations:
- No concurrent writes
- Single-writer model
- Risk of "database locked" errors
- No transaction isolation
- Still requires CMS server running (ECS/container costs)

### Verdict
**Not recommended** for this use case. SQLite is for development/testing only.

---

## Option 2: Git-Based CMS (TinaCMS, Keystatic, Decap)

### Overview
Move content from database to Git repository as Markdown/JSON files.

### Candidates

| CMS | GitHub Stars | Strengths | SvelteKit Support |
|-----|-------------|-----------|-------------------|
| TinaCMS | ~9K | Visual in-context editing | Via API |
| Keystatic | ~4K | Best Astro integration, clean UI | Via API |
| Decap CMS | ~18K | Most mature, many backends | Via API |

### Pros
- **Zero infrastructure cost** (content in Git)
- Perfect for SSG builds
- No API latency during build
- Version control for content
- Works entirely in GitHub Actions

### Cons
- **Significant migration effort** - must convert 25 content types
- Complex content relations harder to model
- No real-time preview without development server
- Limited for non-technical editors

### Migration Effort: **HIGH**
- Requires restructuring all content as files
- Rebuild data fetching layer
- Create new admin editing workflow

---

## Option 3: Payload CMS (Next.js Native)

### Overview
TypeScript-first CMS that integrates directly with Next.js (now owned by Figma).

### Pros
- Code-first, type-safe schemas
- Native Next.js integration
- SQLite support via better-sqlite3
- Can deploy to Vercel with database

### Cons
- **Not compatible with SvelteKit** - designed for Next.js
- Would require frontend framework change
- Significant rewrite effort

### Verdict
**Not suitable** - requires abandoning SvelteKit.

---

## Option 4: Directus (Database-First)

### Overview
Wraps any SQL database with instant API and admin panel.

### Pros
- Can use existing PostgreSQL data
- Instant API generation
- Visual data studio
- SQLite support for low-traffic

### Cons
- Still requires running server
- Migration from Strapi schema required
- Different content modeling approach

### Migration Effort: **MEDIUM**

---

## Option 5: Export-at-Build Architecture

### Overview
Keep Strapi as content editing tool but generate static JSON at build time, eliminating runtime CMS dependency.

### Architecture
```
GitHub Actions Workflow:
1. Spin up temporary Strapi + SQLite container
2. Seed database from exported content
3. Fetch all content via API → static JSON files
4. Build SvelteKit with static JSON as data source
5. Deploy static build to S3 + CloudFront
6. Destroy Strapi container
```

### Pros
- **Minimal code changes** - keep Strapi content model
- **Zero runtime infrastructure** - only S3 + CloudFront
- Content can be version-controlled (exported JSON)
- SSG build reads local files, not API

### Cons
- More complex build pipeline
- Content editing requires local Strapi
- Changes need rebuild/deploy cycle

### Implementation
1. Add `strapi export` to CI pipeline
2. Create SvelteKit data adapter for static JSON
3. Store content exports in repo or artifact

### Migration Effort: **LOW-MEDIUM**

---

## Recommendation

### Short-Term (Immediate Cost Reduction)
**Option 5: Export-at-Build Architecture**

- Eliminates RDS (~$15-30/month)
- Eliminates ECS/ALB (~$50-100/month)
- Keeps familiar Strapi workflow
- Minimal code changes to SvelteKit

### Long-Term (Best DX)
Consider **Git-Based CMS (Keystatic or TinaCMS)** when ready for larger refactor:
- Zero infrastructure
- Content versioned in Git
- Better for solo maintainer workflow

---

## Cost Analysis

| Architecture | Monthly Cost (Est.) | Infrastructure |
|--------------|-------------------|----------------|
| Current (Strapi + RDS + ECS) | $80-150 | RDS + ECS + ALB + S3 + CloudFront |
| Strapi on EC2/Lightsail | $20-40 | EC2/Lightsail + S3 + CloudFront |
| Export-at-Build | $5-15 | S3 + CloudFront only |
| Git-Based CMS | $5-15 | S3 + CloudFront only |

---

## Next Steps

1. Create GitHub Actions workflow for export-at-build pattern
2. Test Strapi 5 migration in local environment
3. Evaluate content editing workflow for solo maintainer
4. Consider Keystatic for future content architecture
Loading
Loading