Post-Deploy Verification
How to verify a deploy succeeded using the health endpoint, container status, logs, and monitoring alerts.
After every deploy, verify the application is healthy. The deploy job itself does not run an explicit health check -- it relies on Docker's built-in health check on the web container. You should confirm the deploy manually, especially for changes that touch auth, database queries, or external service integrations.
Quick Verification (Remote)
Health Endpoint
curl -s https://trovella.ai/api/health | jq
Expected response when all services are healthy:
{
"status": "healthy",
"checks": {
"database": { "ok": true },
"redis": { "ok": true },
"typesense": { "ok": true }
},
"timestamp": "2026-..."
}
The health endpoint checks three backing services:
| Check | What It Tests |
|---|---|
database | Cloud SQL connection via the Cloud SQL Auth Proxy container |
redis | Upstash Redis connection |
typesense | Typesense container connection |
A "degraded" response (HTTP 200) means at least one service is down but the app is partially functional. An "unhealthy" response (HTTP 503) means all services are down.
Watch the Pipeline
# See the latest run on main
gh run list --branch main --limit 1
# Live tail the current run
gh run watch
VM-Level Verification
SSH into the VM to inspect container status and logs directly.
Container Status
gcloud compute ssh trovella-prod-vm \
--zone=us-central1-a --project=trovella-prod \
--tunnel-through-iap
# Check all containers (all should show "Up" with "(healthy)" for web)
docker compose -f /opt/trovella/docker-compose.prod.yml ps
Expected output shows five containers: caddy, web, cloud-sql-proxy, typesense, and inngest. The web container should show (healthy) in its status. Other containers show Up without a health qualifier (they don't have Docker health checks configured).
Recent Logs
# All services (last 50 lines)
docker compose -f /opt/trovella/docker-compose.prod.yml logs --tail=50
# Specific services
docker compose -f /opt/trovella/docker-compose.prod.yml logs web --tail=50
docker compose -f /opt/trovella/docker-compose.prod.yml logs caddy --tail=50
docker compose -f /opt/trovella/docker-compose.prod.yml logs inngest --tail=20
docker compose -f /opt/trovella/docker-compose.prod.yml logs typesense --tail=20
Look for:
- web:
Ready on http://0.0.0.0:3000confirms Next.js started - caddy: No TLS errors, successful reverse proxy connections
- inngest:
Functions registeredconfirms background job handlers connected - cloud-sql-proxy: No connection errors to Cloud SQL
Docker Health Check Details
The web container health check is defined in docker-compose.prod.yml:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/api/health').then(r => { if (!r.ok) process.exit(1) }).catch(() => process.exit(1))",
]
interval: 10s
timeout: 5s
retries: 3
start_period: 15s
- Start period: 15 seconds grace time for Next.js to boot
- Interval: checks every 10 seconds
- Retries: 3 consecutive failures before marking unhealthy
- Timeout: each check must respond within 5 seconds
Monitoring Alerts
Cloud Monitoring provides automated alerting for four conditions:
| Alert | Threshold | Response |
|---|---|---|
| CPU | > 85% for 5 minutes | Email notification |
| Memory | > 90% for 5 minutes | Email notification |
| Disk | > 80% | Email notification (immediate) |
| HTTPS Uptime | Health check fails | Email, auto-close after 30 min recovery |
The uptime check hits https://trovella.ai/api/health every 5 minutes from Google's global probes. If it fails, you receive an email alert.
View and manage alerts in the Cloud Monitoring console. Alert policies are defined in Terraform at infra/modules/compute-vm/monitoring.tf.
Error Tracking
Sentry
Check Sentry for new errors after deploy. Sentry captures:
- Unhandled exceptions
- Error boundary catches
- Request errors (via
onRequestErrorinstrumentation)
Filter by release to see errors specific to the latest deploy.
Cloud Logging
Structured application logs flow to Cloud Logging via Pino. Useful filters after a deploy:
# All errors since the deploy
severity >= ERROR
timestamp >= "2026-04-08T12:00:00Z"
# Slow operations
jsonPayload.durationMs > 5000
Admin Dashboards (via SSH Tunnel)
Two internal dashboards are accessible via SSH tunnel for deeper post-deploy inspection:
Inngest Dashboard
gcloud compute ssh trovella-prod-vm \
--zone=us-central1-a --project=trovella-prod \
--tunnel-through-iap -- -L 8288:localhost:8288
Open http://localhost:8288 to inspect background job execution, failed functions, and queue depth.
Drizzle Studio
gcloud compute ssh trovella-prod-vm \
--zone=us-central1-a --project=trovella-prod \
--tunnel-through-iap -- -L 4983:localhost:4983
Open https://local.drizzle.studio to browse the production database schema and data.