Build and Deploy
andurel build produces the production web binary and every compiled asset. It does not build the queue, migration, or SSR processes; build those with go build when the application uses them.
What andurel build does
1andurel build --version 1.2.3
The command runs these steps in order:
- Downloads
templand generates Go from.templfiles (email templates and the Inertia root document). - Runs narsilc when
domains/**/*.sqlcontains annotated queries. - Compiles the Tailwind classes used by email templates into inline styles.
- For an Inertia project, installs JavaScript dependencies and runs the package's build script. The package manager comes from
andurel.toml:pnpm install --frozen-lockfile,npm ci, orbun install --frozen-lockfile. The scaffold's Vite build emits the client assets and the SSR bundle underassets/dist. - Downloads Go modules.
- Compiles
./cmd/appwithCGO_ENABLED=0andGOOS=linux, writing a binary named after the module in the project root.
The version comes from --version, or from git describe --tags --always --dirty when the flag is omitted. It is injected as main.appVersion with -ldflags.
Build the other processes
Production may run up to four process types. andurel build only produces the first.
1CGO_ENABLED=0 GOOS=linux go build -o andurel-site-queue ./cmd/queue
2CGO_ENABLED=0 GOOS=linux go build -o migrate ./cmd/migrate
3CGO_ENABLED=0 GOOS=linux go build -o andurel-site-ssr ./cmd/ssr
cmd/queueruns River workers, periodic jobs, telemetry, and email senders.cmd/migrateapplies the embedded migrations once and exits.cmd/ssris the production owner of the Node SSR bundle. Build it only when pages opt into SSR. It starts the bundle atINERTIA_SSR_LISTEN(defaulthttp://127.0.0.1:13714), and the web process calls it atINERTIA_SSR_URL.
Use a Node runtime at or above INERTIA_SSR_MINIMUM_MAJOR (22 by default) for the SSR process.
Release sequence
- Run
andurel build. - Run the
migratebinary against the release database. - Start the queue process.
- Start the SSR process if any page uses SSR.
- Start the web process.
Deploy the binaries as separate processes. They share PostgreSQL and the telemetry backend, but each owns its lifecycle and shutdown. Apply migrations deliberately before traffic reaches code that expects the new schema, and back up important data before destructive changes.
Environment
Set ENVIRONMENT=production; it enables secure session cookies and refuses the development-only Mailpit email provider.
ENVIRONMENT=production
HOST_PRIMARY=example.com
PROTOCOL=https
DB_HOST=db.internal
DB_PORT=5432
DB_NAME=andurel_site
DB_USER=andurel
DB_PASSWORD=secret
DB_SSL_MODE=require
SESSION_KEY=<hex key>
SESSION_ENCRYPTION_KEY=<hex key>
SESSION_MAX_AGE=604800
TOKEN_SIGNING_KEY=<secret>
PEPPER=<secret>
PREVIOUS_PEPPERS=
EMAIL_PROVIDER=smtp
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=secret
SMTP_TLS=starttls
CACHE_DRIVER=redis
CACHE_REDIS_ADDR=redis.internal:6379
OTLP_TRACES_ENDPOINT=https://collector.example.com
EMAIL_PROVIDER=mailpit is refused in production. Session keys must be hexadecimal. PREVIOUS_PEPPERS keeps rotated passwords verifiable until they are rehashed at login. Use the Redis cache driver when running more than one web replica so auth rate limits are shared.
Behind a reverse proxy, set HTTP_TRUSTED_PROXIES to the proxy IPs or CIDRs and keep the public Host header intact. Add extra origins with CORS_ALLOWED_ORIGINS and CSRF_TRUSTED_ORIGINS.
Health and shutdown
GET /api/health calls storage.Health on the database and returns the result. Point the platform's readiness check at it, and keep liveness checks limited to process health so a brief database outage does not restart every instance.
The web process starts the HTTP serve loop through lifecycle.Run with WithBlockingStart, so SIGTERM stops accepting connections and drains in-flight requests. The queue process stops its processor before closing PostgreSQL and telemetry. Give the platform enough termination time for requests and jobs to finish cleanly.