Vercel deploy
Git sources, both Vercel projects, ignore wiring and manual production deploys for the monorepo.
Git sources
The repository is mirrored across three sources:
- GitLab (
gitlab.com:isyuricunha/website): the deploy source. Both Vercel projects connect their Git integration to this repository, so pushes tomaintrigger production builds. - GitHub (
github.com/isyuricunha/website): mirror and CI surface. The account is rate-limited, so GitHub Actions runs are not relied on. - YuGit/Forgejo (
ssh.git.yuricunha.com:2222): self-hosted mirror.
Push to all three:
Projects
Two Vercel projects serve this monorepo:
| Project | Root Directory | Production domain | Serves |
|---|---|---|---|
website-web | apps/web | yuricunha.com | the website |
website-docs | apps/docs | docs.yuricunha.com | the docs app |
Both are Node.js 24.x with the Next.js framework preset. apps/docs/vercel.json carries its own install and build commands because the build needs the monorepo root:
Ignore wiring and crons
In a monorepo with Root Directory set, Vercel reads vercel.json from inside the Root Directory and runs the ignore command from there; a repository-root vercel.json is dead config for git-triggered builds.
apps/web/vercel.json(used bywebsite-web) declares the ignore command and the cron schedules for/api/cron/alertsand/api/cron/data-retention. Its ignore script (apps/web/scripts/vercel-ignore.js) is a wrapper that executes the repository-root script, which skips changes that only touchapps/docs/, README, license and metadata-only paths.apps/docs/vercel.json(used bywebsite-docs) mirrors the pattern: its ignore script skips changes that only touchapps/web/.
A docs-only change therefore builds website-docs and skips website-web; a web-only change does the opposite. Declaring crons in the app-level vercel.json keeps them attached on every deployment instead of relying on dashboard state.
Automatic deploys
A push to GitLab main triggers production builds in both projects, filtered by the ignore wiring. If a push did not trigger a deploy (integration freshly connected or webhooks missing), run a manual production deploy.
Run manual deploys from the repository root, not from inside the app directory. A CLI deploy from apps/web uploads only that subdirectory and fails with The specified Root Directory "apps/web" does not exist. Please update your Project Settings. because the project's Root Directory setting is applied on top of the uploaded tree.
website-web is the repository-root link by default:
website-docs needs a temporary link swap because the root link points at website-web:
Avoid leaving vercel link artifacts inside app directories (.vercel/, .env.local): they are local tooling files and can confuse later CLI deploys.
Verify the serving revision
Probes confirm which revision is live:
- Call an endpoint whose response shape changed in the release and check the new behavior.
- For docs releases, request a newly added recipe page on
docs.yuricunha.com. - Inspect response headers; CSP changes appear immediately.
Do not rely on deployment dashboard status alone: a Ready deployment is promoted to production traffic only when it becomes the production alias.
Migrations are not run on deploy
Vercel builds do not run database migrations. After merging schema changes, apply them manually:
Run the preflight checklist in Drizzle first; the migrator stops mid-journal if a migration references objects that already exist or constraints that do not.