fix production db

This commit is contained in:
root
2026-05-17 00:35:35 -04:00
parent 1294109c55
commit be98e3e65d
9 changed files with 150 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
# Traefik / public domains
ACME_EMAIL=rentaldrivego@gmail.com
API_DOMAIN=api.rentaldrivego.ma
PUBLIC_SITE_DOMAIN=rentaldrivego.ma
PGMANAGE_DOMAIN=pgmanage.rentaldrivego.ma
# Database
DATABASE_URL_FROM_POSTGRES=true
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=rentaldrivego
POSTGRES_USER=postgres
POSTGRES_PASSWORD=PMPS5k0D7rUeJOk0NkhI5bRtoGjkUqjK
# Cache
REDIS_URL=redis://redis:6379
# API
API_PORT=4000
API_INTERNAL_URL=http://api:4000/api/v1
API_URL=https://api.rentaldrivego.ma
NEXT_PUBLIC_API_URL=https://api.rentaldrivego.ma/api/v1
# Frontend public URLs
NEXT_PUBLIC_MARKETING_URL=https://rentaldrivego.ma
NEXT_PUBLIC_MARKETPLACE_URL=https://rentaldrivego.ma/marketplace
NEXT_PUBLIC_DASHBOARD_URL=https://rentaldrivego.ma/dashboard
NEXT_PUBLIC_ADMIN_URL=https://rentaldrivego.ma/admin
NEXT_PUBLIC_PUBLIC_SITE_DOMAIN=rentaldrivego.ma
DASHBOARD_URL=https://rentaldrivego.ma/dashboard
ADMIN_URL=https://rentaldrivego.ma/admin
# CORS
CORS_ORIGINS=https://rentaldrivego.ma
# Auth
JWT_SECRET=PMPS5k0D7rUeJOk0NkhI5bRtoGjkUqjK
JWT_EXPIRY=8h
RENTER_JWT_EXPIRY=7d
NODE_ENV=production
# Email
RESEND_API_KEY=C8qPDuFwsv5l@KsGhL/V
EMAIL_FROM=rentaldrivego@gmail.com
EMAIL_FROM_NAME=RentalDriveGo
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_SCHEME=smtp
MAIL_USERNAME=rentaldrivego@gmail.com
MAIL_PASSWORD=xmhg ibqy muoc rntc
MAIL_FROM_ADDRESS=rentaldrivego@gmail.com
MAIL_FROM_NAME=RentalDriveGo
MAIL_REPLY_TO_ADDRESS=rentaldrivego@gmail.com
MAIL_REPLY_TO_NAME=RentalDriveGo
# Optional SMTP instead of Resend
# MAIL_HOST=smtp.rentaldrivego.ma
# MAIL_PORT=587
# MAIL_USERNAME=smtp-user
# MAIL_PASSWORD=smtp-password
# MAIL_SCHEME=smtp
# MAIL_FROM_ADDRESS=noreply@rentaldrivego.ma
# MAIL_FROM_NAME=RentalDriveGo
# Optional Firebase push notifications
# FIREBASE_PROJECT_ID=your-firebase-project-id
# FIREBASE_CLIENT_EMAIL=firebase-adminsdk@your-project.iam.gserviceaccount.com
# FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
# Optional Twilio SMS / WhatsApp
# TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# TWILIO_AUTH_TOKEN=your_auth_token
# TWILIO_PHONE_NUMBER=+1234567890
# TWILIO_WHATSAPP_NUMBER=+1234567890
+2
View File
@@ -152,6 +152,8 @@ Open `.env.docker.production` and fill in every value. The minimum required secr
| `ACME_EMAIL` | Your email for Let's Encrypt notifications |
| `RESEND_API_KEY` | Resend API key (or configure SMTP vars instead) |
Production now derives `DATABASE_URL` inside the app container from `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, and `POSTGRES_PASSWORD` when `DATABASE_URL_FROM_POSTGRES=true`. That avoids Prisma auth failures when the database password contains reserved URL characters such as `@`, `:`, or `/`.
The example file uses `rentaldrivego.ma` for the public site and `app.rentaldrivego.ma` for the marketplace. Adjust them only if you use different hostnames.
#### 5. Start Traefik
+6
View File
@@ -46,6 +46,12 @@ services:
condition: service_started
env_file:
- .env.docker.production
environment:
DATABASE_URL_FROM_POSTGRES: ${DATABASE_URL_FROM_POSTGRES:-true}
POSTGRES_HOST: ${POSTGRES_HOST:-postgres}
POSTGRES_PORT: ${POSTGRES_PORT:-5432}
POSTGRES_DB: ${POSTGRES_DB:-rentaldrivego}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
restart: unless-stopped
labels:
- traefik.enable=true
+3
View File
@@ -1,5 +1,8 @@
import { PrismaClient } from '../generated'
import bcrypt from 'bcryptjs'
import { ensureDatabaseUrl } from '../src/runtime-config'
ensureDatabaseUrl()
const prisma = new PrismaClient()
+2
View File
@@ -3,6 +3,7 @@
const { spawnSync } = require('node:child_process')
const { readdirSync } = require('node:fs')
const path = require('node:path')
const { ensureDatabaseUrl } = require('../src/runtime-config')
const { PrismaClient } = require('../generated')
const repoRoot = path.resolve(__dirname, '../../..')
@@ -23,6 +24,7 @@ function run(command, args) {
}
async function main() {
ensureDatabaseUrl()
const prisma = new PrismaClient()
try {
+4
View File
@@ -1,5 +1,9 @@
const { ensureDatabaseUrl } = require('./runtime-config')
const { PrismaClient } = require('../generated')
ensureDatabaseUrl()
module.exports = {
PrismaClient,
ensureDatabaseUrl,
}
+5
View File
@@ -1,4 +1,9 @@
import { ensureDatabaseUrl } from './runtime-config'
ensureDatabaseUrl()
export { PrismaClient } from '../generated'
export { ensureDatabaseUrl } from './runtime-config'
export type AdminRole = 'SUPER_ADMIN' | 'ADMIN' | 'SUPPORT' | 'FINANCE' | 'VIEWER'
export type EmployeeRole = 'OWNER' | 'MANAGER' | 'AGENT'
+29
View File
@@ -0,0 +1,29 @@
const ENABLED_VALUES = new Set(['1', 'true', 'yes'])
function ensureDatabaseUrl(env = process.env) {
const shouldBuildFromPostgres = ENABLED_VALUES.has(
env.DATABASE_URL_FROM_POSTGRES?.trim().toLowerCase() ?? '',
)
if (!shouldBuildFromPostgres) {
return env.DATABASE_URL
}
if (!env.POSTGRES_PASSWORD) {
throw new Error('DATABASE_URL_FROM_POSTGRES is enabled but POSTGRES_PASSWORD is not set')
}
const user = env.POSTGRES_USER ?? 'postgres'
const password = env.POSTGRES_PASSWORD
const host = env.POSTGRES_HOST ?? 'postgres'
const port = env.POSTGRES_PORT ?? '5432'
const database = env.POSTGRES_DB ?? 'rentaldrivego'
env.DATABASE_URL = `postgresql://${encodeURIComponent(user)}:${encodeURIComponent(password)}@${host}:${port}/${encodeURIComponent(database)}`
return env.DATABASE_URL
}
module.exports = {
ensureDatabaseUrl,
}
+25
View File
@@ -0,0 +1,25 @@
const ENABLED_VALUES = new Set(['1', 'true', 'yes'])
export function ensureDatabaseUrl(env: NodeJS.ProcessEnv = process.env) {
const shouldBuildFromPostgres = ENABLED_VALUES.has(
env.DATABASE_URL_FROM_POSTGRES?.trim().toLowerCase() ?? '',
)
if (!shouldBuildFromPostgres) {
return env.DATABASE_URL
}
if (!env.POSTGRES_PASSWORD) {
throw new Error('DATABASE_URL_FROM_POSTGRES is enabled but POSTGRES_PASSWORD is not set')
}
const user = env.POSTGRES_USER ?? 'postgres'
const password = env.POSTGRES_PASSWORD
const host = env.POSTGRES_HOST ?? 'postgres'
const port = env.POSTGRES_PORT ?? '5432'
const database = env.POSTGRES_DB ?? 'rentaldrivego'
env.DATABASE_URL = `postgresql://${encodeURIComponent(user)}:${encodeURIComponent(password)}@${host}:${port}/${encodeURIComponent(database)}`
return env.DATABASE_URL
}