Nightly Image Domain Rebuild
Summary
Next.js requires image host domains to be whitelisted at build time in next.config.js remotePatterns. When new partners are onboarded with new photo CDN domains, the frontend must be rebuilt to serve their images. nightly-rebuild.sh runs at 03:00 UTC, regenerates the allowed-image-domains JSON from the live database, diffs it against the previous version, and only triggers a full frontend rebuild + PM2 restart if the domain list changed. A Slack notification is posted in #deploys on successful rebuild. If domains are unchanged, the script exits without rebuilding.
State Diagram
stateDiagram-v2 state "Génération des domaines" as GenerateDomains state "Comparaison avec version précédente" as DiffCheck state "Aucun changement" as NoChange state "Rebuild déclenché" as RebuildTriggered state "Build terminé" as BuildComplete state "Serveur web redémarré" as PM2Restarted state "Slack notifié" as SlackNotified [*] --> GenerateDomains: npx tsx scripts/generate-image-domains-cli.ts GenerateDomains --> DiffCheck: compare with allowed-image-domains.json.prev DiffCheck --> NoChange: files identical → exit 0 DiffCheck --> RebuildTriggered: domain list changed RebuildTriggered --> BuildComplete: npx turbo build --filter=@sealion/web BuildComplete --> PM2Restarted: pm2 restart sealion-web PM2Restarted --> SlackNotified: post to #deploys SlackNotified --> [*] NoChange --> [*]
Steps
1. Generate Image Domain Whitelist (Actor: system)
cd /opt/sealion/apps/api && npx tsx scripts/generate-image-domains-cli.ts
Queries the database for all active partner photo base URLs, extracts hostnames, and writes them to apps/web/allowed-image-domains.json.
Outcome: Fresh allowed-image-domains.json written
2. Diff Against Previous Version (Actor: system)
Compares apps/web/allowed-image-domains.json against apps/web/allowed-image-domains.json.prev using diff -q. If files are identical, the script exits 0 with "No domain changes — skipping rebuild".
If the .prev file does not exist (first run), the diff fails and a rebuild is triggered.
Outcome: Either early exit or rebuild proceeds
3. Frontend Rebuild (Actor: system)
NEXT_PUBLIC_API_URL=https://sealion.cacio.fr/api npx turbo build --filter=@sealion/web
NEXT_PUBLIC_API_URL must be set at build time — it is inlined into the Next.js client bundle. Running only at PM2 runtime would have no effect on client-side code.
The current allowed-image-domains.json is copied to .prev before rebuilding so future nightly runs have a correct baseline.
Outcome: Next.js app rebuilt with updated image domain whitelist
4. PM2 Restart (Actor: system)
pm2 restart sealion-web — reloads the frontend process to serve the new build.
Outcome: New build live
5. Slack Notification (Actor: system, tools: slack)
Sources SLACK_BOT_TOKEN and SLACK_DEPLOYS_CHANNEL_ID from /opt/sealion/apps/api/.env using grep -E '^SLACK_(BOT_TOKEN|DEPLOYS_CHANNEL_ID)=' — only those two vars are exported, avoiding issues with malformed lines in the .env file.
Posts: "Rebuild nocturne terminé — nouveaux domaines photos actifs." to #deploys.
Outcome: Team notified of automatic rebuild
Error States
generate-image-domains-cli.tsfails (DB unreachable, Prisma error) → script exits non-zero due toset -euo pipefail, no rebuild happensnpx turbo buildfails → script exits non-zero,sealion-webis not restarted, old build remains livepm2 restartfails → new build is on disk but not serving traffic.envmissing Slack vars → notification silently skipped (curl call is not checked)
Related Processes
- partner-onboarding — adding a partner with a new photo domain requires this rebuild
- deployment — full manual deploy also runs the frontend build with the same
NEXT_PUBLIC_API_URLflag