Getting Started

Deployment

Edit page
Build Customer Portal, apply migrations safely, configure its public origin, and verify a production release.

Customer Portal builds as a single Nuxt service backed by PostgreSQL. The repository includes a multi-stage Dockerfile, but the generated Node server can also run on any platform that supports persistent environment variables and outbound PostgreSQL connections.

Production requirements

Prepare these before a release:

  • a PostgreSQL database with backups and a restricted application user;
  • HTTPS at the public origin;
  • production values for every required environment variable;
  • one stable, high-entropy BETTER_AUTH_SECRET shared by every instance in the deployment;
  • email credentials if registration, verification, recovery, or invoice delivery is enabled;
  • an explicit migration step using the same source revision as the application.

The repository includes an ApexPro reference identity. Complete the branding checklist before publishing a derived deployment.

PUBLIC_URL and BETTER_AUTH_URL must both use the externally visible HTTPS origin. OAuth callback URLs must match that origin in GitHub or Google.

Deploy with Docker

The demo Dockerfiles use workspace packages, so the Docker build context must be the repository root. For demo-apex, configure the deployment service with / (the repository root) as its base/build context and apps/demo-apex/Dockerfile as its Dockerfile path. Do not use apps/demo-apex as the build context; that excludes the workspace path used by the Dockerfile and causes COPY apps/demo-apex/entrypoint.sh to fail.

Build the Apex image from the repository root:

Terminal
docker build -f apps/demo-apex/Dockerfile -t customer-portal-apex .

Run it with production configuration supplied by the deployment platform:

Terminal
docker run --env-file .env.production -p 3000:3000 customer-portal-apex

The included entrypoint validates the portal configuration and applies package migrations through the kit before starting .output/server/index.mjs. A migration failure stops the container instead of serving code against an outdated schema.

Do not bake .env.production into the image or commit it. Use the secret and environment-variable facilities of the hosting platform.

Deploy the generated server

From your consuming Nuxt application directory, build and run the Node server. This example loads .env.production explicitly; use deployment-injected environment variables instead when your host provides them. Nuxt does not automatically load that file for the built server.

Terminal
pnpm install --frozen-lockfile
pnpm build
node --env-file=.env.production ./node_modules/@nuxt-customer-portal/kit/bin/nuxt-customer-portal.mjs db status
node --env-file=.env.production ./node_modules/@nuxt-customer-portal/kit/bin/nuxt-customer-portal.mjs db migrate
node --env-file=.env.production .output/server/index.mjs

Apply the migration once as a release job before directing traffic to the new application version. Keep the migration files and application build from the same commit.

Release sequence

  1. Create or verify a production database backup and confirm the restore procedure.
  2. Build and validate the exact revision to deploy.
  3. Review pending SQL, especially drops, rewrites, backfills, and cross-schema foreign keys.
  4. Apply the ordered migration history.
  5. Start the new application revision.
  6. Verify sign-in, active-organization selection, a protected page, and any changed feature workflow.
  7. Inspect server logs and email-provider delivery status after the release.

Prefer backward-compatible schema changes when old and new instances may overlap during a rolling deployment. Learn how the repository manages changes in database migrations.

If a migration or release fails, preserve its state before retrying and follow the upgrade recovery runbook. Establish the production signals described in observability before the first release.