fix production db
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { PrismaClient } from '../generated'
|
||||
import bcrypt from 'bcryptjs'
|
||||
import { ensureDatabaseUrl } from '../src/runtime-config'
|
||||
|
||||
ensureDatabaseUrl()
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
const { ensureDatabaseUrl } = require('./runtime-config')
|
||||
const { PrismaClient } = require('../generated')
|
||||
|
||||
ensureDatabaseUrl()
|
||||
|
||||
module.exports = {
|
||||
PrismaClient,
|
||||
ensureDatabaseUrl,
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user