5.9 KiB
Local non-container development
This guide documents the local, non-container developer path for the EPPP workspace: how to install, build and run the project on your machine without Docker. The containerised path (Docker Compose baseline, container smoke tests) is tracked separately as story [E00-S02] Docker Compose baseline and is not covered here.
Status: this document tracks the E00-S01 workspace bootstrap state. Commands and expected outputs below were verified from a clean clone.
What you get at bootstrap
The workspace is a pnpm monorepo with three package groups:
| Group | Path | Purpose |
|---|---|---|
apps/ |
apps/server (@personal-blog/server) |
Public server application. Bootstrap placeholder — the Fastify 5 application shell lands in a later story. |
packages/ |
packages/core (@personal-blog/core) |
Application core (site identity, content primitives). Bootstrap placeholder. |
extensions/ |
extensions/example (@personal-blog/example-extension) |
Example extension exercising the extensions/ group. Bootstrap placeholder. |
A dependency-boundary rule (dependency-boundaries.json, enforced by
tests/architecture-import.test.mjs) keeps the groups from collapsing into an
accidental dependency graph: no packages/* package may import a concrete
extensions/* package.
Prerequisites
- Git — to clone the repository.
- Node.js 24.x — the CI pipeline runs Node 24 and this is the supported
line for the workspace (a hard
enginesrestriction is tracked separately as E00-S01-T08). Any Node ≥ 22 is enough for the current bootstrap commands. - pnpm 11.23.0 — pinned via the
packageManagerfield in the rootpackage.json. The easiest way to get exactly this version is Corepack, which ships with Node.js (corepack enable).
No database, no runtime services and no Docker daemon are required at this stage.
Install
# 1. Clone the repository
git clone https://git.stevanovic.co.uk/Fabrika/PersonalBlog.git
cd PersonalBlog
# 2. Activate the pinned pnpm (11.23.0) via Corepack
corepack enable
# 3. Install dependencies against the committed lockfile (reproducible)
pnpm install --frozen-lockfile
- The install is frozen:
--frozen-lockfilerefuses to run ifpnpm-lock.yamlis out of date with the manifests, so every clone gets the exact same dependency tree. CI uses the same flag. - If you are adding or changing dependencies, run
pnpm install(without the flag) and commit the resultingpnpm-lock.yamlso the frozen install keeps working for everyone. node_modules/and the pnpm content-addressable store are git-ignored and never committed.
Build
# Compile every workspace package (apps, packages, extensions) into dist/
pnpm build
# Typecheck every workspace package (no emit)
pnpm typecheck
pnpm build runs tsc -p tsconfig.json in each package in topological order
and emits dist/ (JavaScript + type declarations + source maps) per package.
Expected result: apps/server/dist/, packages/core/dist/ and
extensions/example/dist/ are produced, all packages report Done, exit 0.
dist/ is git-ignored; rebuild whenever you change src/.
Run
# Run the compiled public server entrypoint
pnpm --filter @personal-blog/server start
This runs the start script of apps/server (node dist/index.js), i.e. the
compiled application entrypoint. Two things to know at bootstrap:
- The command must follow
pnpm build— thestartscript executes the compiled artifact indist/, it does not compile first. apps/serveris currently a bootstrap placeholder: its entrypoint is an empty module, so starting it loads the module and exits cleanly (exit 0) without opening an HTTP port yet. The real Fastify 5 application shell — which turns this into a serving process — lands in a later story; thestartcommand shape above stays the same once it does.
To run the compiled output of any other workspace package directly:
node <package-dir>/dist/index.js # e.g. node packages/core/dist/index.js
Test
pnpm test
pnpm test runs the node:test suites under tests/ (currently
tests/architecture-import.test.mjs, 10 tests) with zero extra dependencies.
This is also the suite that enforces the dependency-boundary rule.
Smoke check from a clean clone
git clone https://git.stevanovic.co.uk/Fabrika/PersonalBlog.git && cd PersonalBlog
corepack enable
pnpm install --frozen-lockfile # exit 0, lockfile untouched
pnpm build # 3/3 packages emit dist/, exit 0
pnpm typecheck # 3/3 packages pass --noEmit, exit 0
pnpm test # 10/10 pass, exit 0
pnpm --filter @personal-blog/server start # loads compiled server entrypoint, exit 0
Troubleshooting
| Symptom | Cause / fix |
|---|---|
pnpm: command not found |
Corepack shims not activated — run corepack enable, or prefix commands with corepack pnpm .... |
ERR_PNPM_OUTDATED_LOCKFILE |
pnpm-lock.yaml is out of date with the manifests. Run pnpm install (unfrozen) and commit the lockfile update. |
| Node version warnings / unexpected behavior | Use Node 24.x to match CI (e.g. via nvm, fnm or another version manager). A hard engines restriction is tracked as E00-S01-T08. |
start exits immediately with no output |
Expected at bootstrap — the server entrypoint is a placeholder module; the Fastify 5 shell is a later story (see Run). |
.env files |
.env/.env.* are git-ignored; a committed .env.example template lands with the environment story (E00-S04). |
Out of scope
- Root build/test/typecheck script wiring — covered by E00-S01-T05; only usage is documented here.
- Docker Compose baseline and container smoke tests — E00-S02.
- PostgreSQL adapter, migration runner and other runtime services — later E00 stories.