Deployment and static SPAs
Nội dung này hiện chưa có sẵn bằng ngôn ngữ của bạn.
Monorepo scripts (root package.json)
Section titled “Monorepo scripts (root package.json)”| Script | What it runs |
|---|---|
npm run admin:build | turbo run build --filter=@indochina/admin-web |
npm run vendor:build | turbo run build --filter=@indochina/vendor-web |
npm run admin:build:staging | Vite --mode staging + VITE_API_URL (see apps/admin-web/staging.env.example) |
npm run vendor:build:staging | Vite --mode staging + VITE_API_URL (see apps/vendor-web/staging.env.example) |
npm run deploy:staging | deploy-to-vps-staging.sh — staging SSH env, backend .env.host.staging, staging SPA builds |
npm run backend:build | turbo run build --filter=@indochina/backend |
npm run build:deploy | admin:build → vendor:build → backend:build (single command for release) |
npm run deploy | bash deploy/deploy-to-vps.sh (optional VPS rsync; see below) |
npm run docs:check | apps/docs/scripts/check-docs.mjs — runs astro check + the docs ↔ e2e screenshot contract linter |
npm run docs:check:screenshots | apps/docs/scripts/check-docs-screenshots.mjs only (skip astro) |
npm run docs:make:white-logo | Regenerate apps/vendor-web/public/logo-white.png from logo.png (transparent-bg, white marks) |
npm run docs:deploy | apps/docs/scripts/deploy-docs.sh — pre-flight checks, astro build, rsync to the docs host (uses deploy/.env.deploy) |
npm run docs:deploy:staging | Same as above with deploy/.env.deploy.staging |
Vite outDir in each app’s vite.config.ts points to apps/backend/static/admin and apps/backend/static/vendor, so SPA builds write straight into the Nest static tree before backend:build.
Docker (reference implementation)
Section titled “Docker (reference implementation)”The root Dockerfile:
- Builder:
npm ci, copy workspaces, setNODE_ENV=productionandVITE_API_URL=, runnpm run build:deploy. - Runner: production
npm install --omit=devforapps/backendonly, copydistandstatic, runnode dist/main.js.
So CI “copy dist into static” is already encoded in the image build — no manual rsync inside the container.
Upload persistence (gallery / imports)
Section titled “Upload persistence (gallery / imports)”- Runtime: Nest writes gallery files under
PUBLIC_STORAGE_ROOT(default{cwd}/public/storage) and serves them at/public/storage/*(mountPublicStorageinbootstrap-static-spas.ts). Clover import jobs useVENDOR_IMPORT_STORAGE_ROOT(default{cwd}/storage/vendor-imports). - Docker:
deploy/docker-compose.ymlmounts named volumes on those default paths so uploads survive image rebuilds. - PM2/VPS: set
PUBLIC_STORAGE_ROOTandVENDOR_IMPORT_STORAGE_ROOTinapps/backend/.env.hostto directories outside the rsync deploy tree; seedeploy/README.md→ Persistent uploads.
GitHub Actions
Section titled “GitHub Actions”.github/workflows/docker-build.yml— validates the image onmain/masterand PRs (build only, no registry push).
VPS without Docker
Section titled “VPS without Docker”deploy/deploy-to-vps.sh— builds locally (unlessSKIP_BUILD=1), rsyncsstatic/*and/ordistto the server, optionalRUN_MIGRATIONS=1, PM2 or systemd restart. Configure viadeploy/.env.deploy.
Documentation site (apps/docs)
Section titled “Documentation site (apps/docs)”The docs are an Astro/Starlight static site — they are not served by the Nest API and are not part of npm run build:deploy. They live in apps/docs/dist/ after a build and are deployed independently via npm run docs:deploy.
Local development
Section titled “Local development”| Command | What it does |
|---|---|
npm run docs:dev | Astro dev server (default localhost:4321) |
npm run docs:build | Production build → apps/docs/dist/ |
npm run docs:check | Run astro check (TS / content collection validation) plus the docs ↔ e2e screenshot contract linter in one shot |
Deploy to a static-serving VPS
Section titled “Deploy to a static-serving VPS”The deploy script lives at apps/docs/scripts/deploy-docs.sh and reuses the same SSH / rsync conventions as deploy/deploy-to-vps.sh. Configure once:
-
Copy the env example and fill in docs-only fields:
Terminal window cp deploy/env.deploy.example deploy/.env.deploy# edit deploy/.env.deploy — see the "Docs site" block at the bottom:# DOCS_DEPLOY_REMOTE_PATH=/var/www/docs.indochinaenterprises.com# DOCS_DEPLOY_HOST=docs.indochinaenterprises.com (optional override)# DOCS_DEPLOY_USER=deploy (optional override)# DOCS_PUBLIC_URL=https://docs.indochinaenterprises.com -
Ensure the docs server is reachable over SSH (
ssh-copy-id deploy@docs.indochinaenterprises.com). -
Run from the repo root:
Terminal window npm run docs:deploy # productionnpm run docs:deploy:staging # staging (uses deploy/.env.deploy.staging)
What the script does:
- Pre-flight:
astro check+ the docs ↔ e2e screenshot contract linter. Aborts the deploy on any failure. - Build:
astro build(honorsDOCS_PUBLIC_URLfor canonical URLs +sitemap-index.xml). SetDOCS_DEPLOY_SKIP_BUILD=1to reuse an existingapps/docs/dist/. - Rsync:
apps/docs/dist/dot→DOCS_DEPLOY_REMOTE_PATH/on the docs host with--deleteso the deploy is idempotent.
The target directory is whatever you put behind Nginx / Caddy / a CDN — it does not need to be public/docs. Typical setups:
- Bare Nginx server root:
DOCS_DEPLOY_REMOTE_PATH=/var/www/docs.indochinaenterprises.com. - Sub-path on the API host:
DOCS_DEPLOY_REMOTE_PATH=${DEPLOY_REMOTE_PATH}/public/docs(the default), then point your reverse proxy at/docs/*.
Asset contracts to remember
Section titled “Asset contracts to remember”apps/vendor-web/public/logo.pngandlogo-white.pngare version-controlled PNGs committed to the repo. The white variant is regenerated bynpm run docs:make:white-logo(uses the colored file as input). Both files are served from/logo.pngand/logo-white.pngvia Vite’spublic/mount — no code changes are needed after a swap.- Favicons reference
/logo.pnginapps/vendor-web/index.html,apps/vendor-web/index-cashier.html, andapps/vendor-web/index-customer-display.html. Update the PNG, then rebuild the vendor web (npm run vendor:build) so the new asset ships in the SPA bundle.
Static hosting (runtime)
Section titled “Static hosting (runtime)”- When
index.htmlexists underapps/backend/static/adminandstatic/vendor, the backend serves them (seebootstrap-static-spas.ts). - Reserved paths for the vendor SPA exclude
/api,/admin, and Swagger UI/JSON paths so APIs keep working.
Organization-specific
Section titled “Organization-specific”Document Nginx or CDN rules (TLS, caching, WebSocket if added) in your internal runbook.