# Deployment Guide

This guide summarizes the steps required to promote a freshly scaffolded Guren application to production. It assumes you generated your project with `create-guren-app` and that you have a PostgreSQL instance available.

## Production Checklist
- Configure environment variables (`DATABASE_URL`, `APP_URL`, `PORT`, etc.).
- Install dependencies with Bun in production mode.
- Build frontend assets.
- Run database migrations (and seed data if necessary).
- Start the Bun server behind a process manager or container runtime.

## 1. Prepare Environment Variables
Create a production-specific `.env` (or inject variables through your hosting platform). At minimum configure:

```dotenv
APP_URL=https://example.com
PORT=3333
DATABASE_URL=postgres://user:password@db-host:5432/database
NODE_ENV=production
```

Avoid committing this file—use your platform’s secret manager instead.

> [!WARNING]
> Treat every value in `.env` as sensitive. Prefer secret managers or environment variables provided by your platform so credentials never appear in git history, build logs, or container images.

## 2. Install Dependencies
On the deployment host:

```bash
bun install --production
```

This installs only the dependencies required at runtime. If your environment builds assets during deployment, you can omit `--production` to keep dev tooling available.

## 3. Build Frontend Assets

```bash
NODE_ENV=production bun run build
```

The scaffolded build script runs both `bunx vite build` and `bunx vite build --ssr`, producing the client manifest at `public/assets/.vite/manifest.json` and the SSR manifest at `public/assets/.vite/ssr-manifest.json`. At runtime `src/main.ts` calls `autoConfigureInertiaAssets`, which reads those files and wires the `GUREN_INERTIA_*` environment variables automatically.

## 4. Run Database Migrations (and Seeders)

```bash
NODE_ENV=production bun run db:migrate
# Optional
bun run db:seed
```

Run these commands on every deployment to keep the schema in sync. Seeders are optional and typically used for demo or staging data.

> [!IMPORTANT]
> Run migrations before the new code begins serving traffic. Rolling back partially applied migrations is messy—if a deploy fails after running them, redeploy the previous commit **without** re-running migrations.

## 5. Start the Server
You can start the Bun server directly:

```bash
NODE_ENV=production bun run bin/serve.ts
```

For reliability, wrap this command with a process manager (e.g. `systemd`, `pm2`, `supervisord`, or your hosting provider’s run command). Example `systemd` unit:

- The startup banner only renders in non-production environments by default. If you want to show it (or disable it explicitly) set `GUREN_DEV_BANNER=1` or `GUREN_DEV_BANNER=0`.
- The framework skips launching the Vite dev server when `NODE_ENV=production`. If you’re running a custom dev workflow in production-like environments, toggle it with `GUREN_DEV_VITE=1` (on) or `GUREN_DEV_VITE=0` (off).

```ini
[Unit]
Description=Guren Application
After=network.target

[Service]
EnvironmentFile=/etc/guren/my-app.env
WorkingDirectory=/var/www/my-app
ExecStart=/usr/local/bin/bun run bin/serve.ts
Restart=always

[Install]
WantedBy=multi-user.target
```

Reload systemd, enable the service, and start it with `sudo systemctl enable --now my-app`.

## Container Deployment Example

```dockerfile
FROM oven/bun:1 AS base
WORKDIR /app

COPY bun.lock package.json ./
RUN bun install --production

COPY . .
RUN NODE_ENV=production bun run build

EXPOSE 3333
ENV NODE_ENV=production
CMD ["bun", "run", "bin/serve.ts"]
```

Build and run:

```bash
docker build -t my-app .
docker run --env-file .env.prod -p 3333:3333 my-app
```

The container image bakes in both the client and SSR bundles so the server can stream pre-rendered HTML immediately.

Mount your configuration or secrets as needed for your hosting environment.

## AWS Lambda (Serverless)

Guren runs on AWS Lambda via the `@guren/core/lambda` adapter — ideal for variable traffic or minimal infrastructure management.

```typescript
// lambda.ts
import app from './src/app'
import { createLambdaHandler } from '@guren/core/lambda'

await app.boot()
export const handler = createLambdaHandler(app)
```

The framework provides dedicated handlers for HTTP, SQS queues, EventBridge scheduling, and CLI commands. See the **[Serverless Deployment Guide](./serverless.md)** for the full setup including SQS, EventBridge, CDK examples, and infrastructure recommendations.

## Vercel (Serverless)

SSR apps can deploy to Vercel using the official plugin. The plugin assembles a [Build Output API](https://vercel.com/docs/build-output-api/v3) directory that runs on Vercel's Bun runtime.

```bash
bunx guren plugin @guren/plugin-vercel
bun add @guren/plugin-vercel
```

The CLI scaffolds `src/vercel.ts`, `scripts/vercel-build.ts`, and `vercel.json` for you. Build and deploy:

```bash
bun run vercel:build
vercel deploy --prebuilt
```

> [!NOTE]
> The plugin targets SSR apps only. It reads Vite manifests to inject the correct `GUREN_INERTIA_*` environment variables into the serverless function. API-only apps should use Docker or Lambda instead.

## Post-Deployment Tasks
- Follow the [Production Operations Runbook](./operations.md) for SLO, incident response, and backup/restore drill policy.
- Set up HTTPS (e.g. via a reverse proxy such as Nginx, Caddy, or your cloud platform).
- Configure logging and monitoring—Bun prints to stdout/stderr, so ship logs to your chosen aggregator.
- Schedule automated backups for the PostgreSQL database.
- Implement health checks (e.g. expose `/health` from a `registerHealthRoutes(router)` registrar via `router.get('/health', (ctx) => ctx.json({ ok: true }))`) and wire them into your load balancer.

Following this checklist ensures each release is reproducible, migrates the database safely, and keeps your application responsive in production.
