Files
Primora/scripts/setup.sh
T
Tomas DvorakandDevin 55edbf8b56 feat: phase 6 production hardening + DB-to-DB transfer
Security:
- Graceful shutdown: http.Server + signal.NotifyContext, 10s drain,
  retention sweeper cancelled before pool close
- Scoped API keys (migration 00006): ingest/read/write/admin enforced in
  auth middleware; scope picker + badges in Settings UI; scopeless legacy
  keys act as admin. Read-only keys now get 403 on ingest (verified live)
- nginx: baseline security headers on all responses, CSP scoped to SPA;
  fixed add_header inheritance shadowing
- better-auth rate limit enabled unconditionally (was gated on NODE_ENV,
  which the shipped .env sets to development)
- Mailpit moved to docker-compose.dev.yml; prod compose cannot expose it
- setup.sh generates PRIMORA_ENCRYPTION_KEY

Reliability/ops:
- Retention: per-project retention_{events,audit,webhook}_days
  (migration 00007, 0=off) + hourly RetentionSweeper; edit UI in Projects
- GET /api/v1/metrics Prometheus exposition
- compose: healthchecks + restart policies everywhere, dragonfly pinned
  to v2.0.0, depends_on service_healthy
- backup.sh/restore.sh (pg_dump -Fc + storage volume); restore verified
  against scratch postgres+volume
- .dockerignore: exclude target dirs (build context was 4.7GB)

Correctness/testing:
- DBX transfer endpoint: POST /db-connections/:id/transfer — SQL or Redis
  target, 1000-row bound, server-side creds (verified live pg→dragonfly)
- Pagination audit: ListComponents capped at 500 (auto-registers)
- CI: goose up/reset/up job + compose e2e-smoke job (smoke-e2e.sh
  verified locally: signup, bootstrap, scoped keys, ingest, metrics)
- k6 load sanity script: 6650 reqs, ~217/s, 0 real failures, p95 221ms
  (429s = configured rate limiter working)

Docs: DEPLOYMENT_GUIDE.md, PRODUCTION_READINESS.md; verify script
repaired (stale refs + set -e arithmetic abort). ROADMAP: phase 2 +
phase 6 marked complete.

Authored By: TDvorak <[email protected]>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 09:15:42 +02:00

79 lines
3.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
set -e
# Primora Setup Script
# Simplified deployment for local and single-dev environments
echo "🚀 Starting Primora Platform Setup..."
# Check dependencies
if ! command -v docker &> /dev/null; then
echo "❌ Error: docker is not installed."
exit 1
fi
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
echo "❌ Error: docker-compose is not installed."
exit 1
fi
# Create .env from .env.example if it doesn't exist
if [ ! -f .env ]; then
echo "📝 Creating .env file from .env.example..."
cp .env.example .env
# Generate secrets
echo "🔐 Generating secure secrets..."
JWT_SECRET=$(openssl rand -base64 32)
BETTER_AUTH_SECRET=$(openssl rand -base64 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
# Update .env with secrets
# Use different sed approach for better compatibility
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s/JWT_SECRET=change-me-super-long-jwt-secret/JWT_SECRET=$JWT_SECRET/g" .env
sed -i '' "s/BETTER_AUTH_SECRET=change-me-super-long-better-auth-secret/BETTER_AUTH_SECRET=$BETTER_AUTH_SECRET/g" .env
sed -i '' "s/^PRIMORA_ENCRYPTION_KEY=.*/PRIMORA_ENCRYPTION_KEY=$ENCRYPTION_KEY/" .env
else
sed -i "s/JWT_SECRET=change-me-super-long-jwt-secret/JWT_SECRET=$JWT_SECRET/g" .env
sed -i "s/BETTER_AUTH_SECRET=change-me-super-long-better-auth-secret/BETTER_AUTH_SECRET=$BETTER_AUTH_SECRET/g" .env
sed -i "s/^PRIMORA_ENCRYPTION_KEY=.*/PRIMORA_ENCRYPTION_KEY=$ENCRYPTION_KEY/" .env
fi
echo "✅ .env file created and secured."
else
echo "ℹ️ .env file already exists. Skipping creation."
fi
# Ask for domain/host
read -p "🌐 Enter your domain or IP (default: localhost): " DOMAIN
DOMAIN=${DOMAIN:-localhost}
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s/COOKIE_DOMAIN=localhost/COOKIE_DOMAIN=$DOMAIN/g" .env
sed -i '' "s/BETTER_AUTH_URL=http:\/\/localhost/BETTER_AUTH_URL=http:\/\/$DOMAIN/g" .env
sed -i '' "s/VITE_APP_URL=http:\/\/localhost/VITE_APP_URL=http:\/\/$DOMAIN/g" .env
else
sed -i "s/COOKIE_DOMAIN=localhost/COOKIE_DOMAIN=$DOMAIN/g" .env
sed -i "s/BETTER_AUTH_URL=http:\/\/localhost/BETTER_AUTH_URL=http:\/\/$DOMAIN/g" .env
sed -i "s/VITE_APP_URL=http:\/\/localhost/VITE_APP_URL=http:\/\/$DOMAIN/g" .env
fi
# Start services — the dev overlay adds mailpit for local email capture.
# Production deploys use the base file alone: docker compose up -d
echo "📦 Pulling images and starting services..."
if command -v docker-compose &> /dev/null; then
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
else
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
fi
echo ""
echo "✨ Primora is now setting up in the background!"
echo "📡 Access your platform at: http://$DOMAIN"
echo "📧 Check emails (Mailpit) at: http://$DOMAIN/mailpit"
echo ""
echo "🛠️ To view logs: docker-compose logs -f"
echo "🛑 To stop: docker-compose down"
echo ""
echo "Enjoy your simplified development platform! 🚀"