fix: payload building issues
This commit is contained in:
@@ -4,23 +4,7 @@ A monorepo with two apps:
|
||||
|
||||
```
|
||||
apps/web Astro 5 (static site, Tailwind v4)
|
||||
apps/cms Payload 3 (admin UI + REST/GraphQL)
|
||||
```
|
||||
|
||||
## Package manager
|
||||
|
||||
`pnpm` 9. From the repo root:
|
||||
|
||||
```bash
|
||||
pnpm install # install both
|
||||
pnpm dev # dev:web
|
||||
pnpm dev:web # Astro only
|
||||
pnpm dev:cms # Payload only
|
||||
pnpm build # build:web
|
||||
pnpm build:cms # build Payload
|
||||
pnpm typecheck # Astro check
|
||||
pnpm format # prettier
|
||||
pnpm format:check # prettier --check
|
||||
apps/cms Payload 3 (admin UI + REST/GraphQL, Next.js 15)
|
||||
```
|
||||
|
||||
## Source paths
|
||||
@@ -31,7 +15,8 @@ pnpm format:check # prettier --check
|
||||
- `apps/web/src/styles/` — `global.css` (Tailwind v4 `@theme` tokens) and `prose.css`
|
||||
- `apps/web/public/fonts/` — drop `Geist-Variable.woff2` + `GeistMono-Variable.woff2` here
|
||||
- `apps/cms/src/collections/` — Payload collections
|
||||
- `apps/cms/src/hooks/` — Payload hooks (e.g. `revalidateAstro`)
|
||||
- `apps/cms/src/hooks/` — Payload hooks
|
||||
- `apps/cms/src/lib/` — Payload helpers (e.g. `withRevalidate`)
|
||||
|
||||
## Code style
|
||||
|
||||
@@ -42,46 +27,87 @@ pnpm format:check # prettier --check
|
||||
- Prefer `border border-border-subtle rounded-md` over arbitrary values to stay on the 4px baseline.
|
||||
- For code blocks in MDX / Lexical output, the article body uses `prose-article` (see `prose.css`).
|
||||
|
||||
## Lint / typecheck
|
||||
## Lint / typecheck (web app)
|
||||
|
||||
```bash
|
||||
pnpm typecheck # astro check
|
||||
pnpm format:check
|
||||
cd apps/web
|
||||
npx astro check
|
||||
npx prettier --check "src/**/*.{ts,astro,css}"
|
||||
```
|
||||
|
||||
There is no separate ESLint run; the project's quality bar is enforced by `astro check` and Prettier.
|
||||
|
||||
## Local development (optional, not required for homeserver deploy)
|
||||
|
||||
If you have Node + pnpm on your dev machine:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm dev:web # Astro on :4321
|
||||
pnpm dev:cms # Payload on :3000
|
||||
```
|
||||
|
||||
The homeserver deploy does **not** require Node or pnpm on the host — Docker builds both images from source.
|
||||
|
||||
## Build outputs
|
||||
|
||||
- `apps/web/dist/` is bind-mounted into the `web` nginx container (`./apps/web/dist:/usr/share/nginx/html:ro`). The host-side webhook rewrites this folder on demand; the nginx container does not need to be rebuilt.
|
||||
- `apps/cms/dist/` is built by Payload (Next.js) and runs as the CMS Node process.
|
||||
- `apps/web/dist/` is generated by `astro build` inside the `softvowels-web` Docker image. Baked into the image at `/usr/share/nginx/html/`.
|
||||
- `apps/cms/.next/standalone/` is generated by `next build` (with `output: 'standalone'`) inside the `softvowels-cms` Docker image. Baked into the image and run via `node server.js`.
|
||||
- `apps/cms/media/` (uploaded files) lives in a named Docker volume (`softvowels-cms-uploads`), not the image.
|
||||
|
||||
## Deploy (homeserver)
|
||||
## Deploy (homeserver, Docker only)
|
||||
|
||||
1. Copy the repo to `/opt/softvowels` on the server.
|
||||
2. `cp .env.example .env` and fill in the secrets.
|
||||
3. `docker compose up -d --build`.
|
||||
4. In Nginx Proxy Manager add two proxied hosts:
|
||||
- `softvowels.example` → `web:80` (force SSL, HSTS)
|
||||
- `cms.softvowels.example` → `cms:3000` (force SSL, HSTS)
|
||||
5. On the host, install the rebuild webhook:
|
||||
```bash
|
||||
sudo cp scripts/softvowels-webhook.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now softvowels-webhook
|
||||
```
|
||||
Make sure `REBUILD_TOKEN` in `/etc/systemd/system/softvowels-webhook.service` matches `REVALIDATE_TOKEN` in `.env`.
|
||||
The host needs Docker and Docker Compose v2. Nothing else.
|
||||
|
||||
## Revalidate flow
|
||||
```bash
|
||||
# 1. Get the code on the server
|
||||
git clone <repo> /opt/softvowels
|
||||
cd /opt/softvowels
|
||||
|
||||
1. Editor publishes in `/admin`.
|
||||
2. Payload `afterChange` hook POSTs to `http://host.docker.internal:4321/__revalidate?secret=…&collection=…&op=…`.
|
||||
3. The host-side Node webhook spawns `scripts/rebuild.sh`, which `git pull`s and runs `pnpm --filter web build`.
|
||||
4. nginx container now serves the new `apps/web/dist/`.
|
||||
# 2. Configure environment
|
||||
cp .env.example .env
|
||||
$EDITOR .env # fill in POSTGRES_PASSWORD, PAYLOAD_SECRET, hostnames
|
||||
|
||||
# 3. Build and start
|
||||
docker compose up -d --build
|
||||
|
||||
# 4. Watch the first boot
|
||||
docker compose logs -f softvowels-cms
|
||||
# On first run, Payload prints a one-time URL for creating the admin
|
||||
# account. Open it, then visit https://cms.softvowels.example/admin.
|
||||
```
|
||||
|
||||
### Updating the site (no webhook yet)
|
||||
|
||||
Until the webhook is in place, each site update requires:
|
||||
|
||||
```bash
|
||||
cd /opt/softvowels
|
||||
git pull
|
||||
docker compose build softvowels-web
|
||||
docker compose up -d softvowels-web
|
||||
```
|
||||
|
||||
That's the entire "redeploy" for a content change. The CMS does not need rebuilding for content changes — only the web image.
|
||||
|
||||
## Nginx Proxy Manager setup
|
||||
|
||||
Add two proxied hosts in NPM:
|
||||
|
||||
| Domain | Forward to | Notes |
|
||||
|---|---|---|
|
||||
| `softvowels.example` | `softvowels-web:80` (http) | Force SSL, HSTS, HTTP/2, websockets off |
|
||||
| `cms.softvowels.example` | `softvowels-cms:3000` (http) | Force SSL, HSTS, websockets on (Payload admin uses them) |
|
||||
|
||||
NPM must be able to resolve `softvowels-web` and `softvowels-cms`. The `nginx_proxy_manager` network is `external: true` in `docker-compose.yml`; the easiest way to make NPM see the containers is to run NPM on the same host and add the network to its container with:
|
||||
|
||||
```bash
|
||||
docker network connect nginx_proxy_manager <npm-container-name>
|
||||
```
|
||||
|
||||
## Self-hosting fonts
|
||||
|
||||
Drop these two files into `apps/web/public/fonts/`:
|
||||
Drop these two files into `apps/web/public/fonts/` (before `docker compose build`):
|
||||
|
||||
- `Geist-Variable.woff2` (https://github.com/vercel/geist-font — rename `GeistVF.woff2`)
|
||||
- `GeistMono-Variable.woff2` (rename `GeistMonoVF.woff2`)
|
||||
@@ -95,28 +121,8 @@ Root `.env` (used by `docker compose`):
|
||||
```
|
||||
POSTGRES_PASSWORD=
|
||||
PAYLOAD_SECRET=
|
||||
REVALIDATE_TOKEN=
|
||||
WEB_HOSTNAME=
|
||||
CMS_HOSTNAME=
|
||||
WEB_HOSTNAME= # e.g. softvowels.example
|
||||
CMS_HOSTNAME= # e.g. cms.softvowels.example
|
||||
```
|
||||
|
||||
`apps/web/.env`:
|
||||
|
||||
```
|
||||
PUBLIC_SITE_URL=
|
||||
PUBLIC_PAYLOAD_API=
|
||||
PAYLOAD_API_INTERNAL=
|
||||
REVALIDATE_TOKEN=
|
||||
```
|
||||
|
||||
`apps/cms/.env`:
|
||||
|
||||
```
|
||||
PAYLOAD_SECRET=
|
||||
DATABASE_URI=
|
||||
PAYLOAD_PUBLIC_SERVER_URL=
|
||||
SERVER_URL=
|
||||
CORS_ORIGINS=
|
||||
ASTRO_REVALIDATE_URL=
|
||||
ASTRO_REVALIDATE_TOKEN=
|
||||
```
|
||||
`REVALIDATE_TOKEN` was removed when the webhook was deferred. Re-add it to `.env` and `docker-compose.yml` when the on-publish rebuild is wired back in.
|
||||
|
||||
Reference in New Issue
Block a user