fix: API key save network error — add ENCRYPTION_KEY env and auto-migrate
The "Netzwerkfehler beim Speichern des Schlüssels" was caused by two issues: 1. ENCRYPTION_KEY env var was not passed to the Docker container, so AES-256-GCM encrypt() threw at runtime on every POST/PATCH. 2. The 0003_tenant_api_keys migration was not in the drizzle journal and no migration runner existed in the Docker image. Changes: - docker-compose.yml: pass ENCRYPTION_KEY to app container - .env.example: document ENCRYPTION_KEY with generation command - .gitignore: allow .env.example to be tracked - Dockerfile: include drizzle/ migrations and entrypoint script - entrypoint.sh: run migrations before starting the app - migrate.mjs: runtime migration script using drizzle-orm migrator - drizzle journal: register 0003_tenant_api_keys migration Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
23
.env.example
Normal file
23
.env.example
Normal file
@@ -0,0 +1,23 @@
|
||||
# Database
|
||||
DATABASE_URL=postgresql://legalai:legalai@localhost:5432/legalai
|
||||
|
||||
# Authentication
|
||||
NEXTAUTH_URL=http://localhost:3000
|
||||
NEXTAUTH_SECRET=your-secret-here
|
||||
|
||||
# AI Providers (set the one you use: anthropic, openai, ollama)
|
||||
AI_PROVIDER=anthropic
|
||||
ANTHROPIC_API_KEY=
|
||||
OPENAI_API_KEY=
|
||||
|
||||
# Ollama (local LLM)
|
||||
OLLAMA_URL=http://localhost:11434
|
||||
OLLAMA_MODEL=llama3
|
||||
|
||||
# Search
|
||||
MEILISEARCH_URL=http://localhost:7700
|
||||
MEILISEARCH_API_KEY=masterKey
|
||||
|
||||
# Encryption (required for per-tenant API key storage)
|
||||
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
||||
ENCRYPTION_KEY=
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,6 +32,7 @@ yarn-error.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
!.env.example
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
@@ -19,8 +19,12 @@ RUN adduser --system --uid 1001 nextjs
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/drizzle ./drizzle
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/migrate.mjs ./migrate.mjs
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/entrypoint.sh ./entrypoint.sh
|
||||
RUN chmod +x ./entrypoint.sh
|
||||
USER nextjs
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
CMD ["node", "server.js"]
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
|
||||
@@ -12,6 +12,7 @@ services:
|
||||
- AI_PROVIDER=${AI_PROVIDER:-anthropic}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"when": 1775729813628,
|
||||
"tag": "0002_wide_grandmaster",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1775775900000,
|
||||
"tag": "0003_tenant_api_keys",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
4
entrypoint.sh
Normal file
4
entrypoint.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
node migrate.mjs
|
||||
exec node server.js
|
||||
20
migrate.mjs
Normal file
20
migrate.mjs
Normal file
@@ -0,0 +1,20 @@
|
||||
// Runtime migration script — runs drizzle SQL migrations against the database.
|
||||
// Used by the Docker entrypoint before starting the app.
|
||||
|
||||
import { drizzle } from 'drizzle-orm/node-postgres';
|
||||
import { migrate } from 'drizzle-orm/node-postgres/migrator';
|
||||
import pg from 'pg';
|
||||
|
||||
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
||||
|
||||
try {
|
||||
const db = drizzle(pool);
|
||||
console.log('Running database migrations...');
|
||||
await migrate(db, { migrationsFolder: './drizzle' });
|
||||
console.log('Migrations complete.');
|
||||
} catch (err) {
|
||||
console.error('Migration failed:', err);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await pool.end();
|
||||
}
|
||||
Reference in New Issue
Block a user