Environment & Configuration
All runtime configuration lives in a single .env file at the project root. The scaffold ships with an .env.example; copy it to .env and edit.
Variables
Database
| Variable | Default | Notes |
|---|---|---|
DATABASE_HOST | localhost | |
DATABASE_PORT | 5432 | |
DATABASE_USERNAME | (set at scaffold) | |
DATABASE_PASSWORD | (set at scaffold) | |
DATABASE_NAME | (set at scaffold) |
These are read by both the API runtime (MarketlumCoreModule) and the TypeORM CLI (data-source.ts).
Authentication
| Variable | Default | Notes |
|---|---|---|
JWT_SECRET | change-me-in-production | Must be changed before deploying |
JWT_EXPIRES_IN | 1d | Standard jsonwebtoken duration |
Ports and URLs
| Variable | Default | Notes |
|---|---|---|
API_PORT | 3001 | |
WEB_PORT | 3000 | |
NEXT_PUBLIC_WEB_URL | http://localhost:3000 | Used by API CORS allowlist |
File storage
| Variable | Default | Notes |
|---|---|---|
STORAGE_DRIVER | local | Set to s3 to use the S3 provider |
S3_BUCKET | — | Required when STORAGE_DRIVER=s3 |
S3_REGION | — | |
AWS_ACCESS_KEY_ID | — | Or use IAM role |
AWS_SECRET_ACCESS_KEY | — |
When STORAGE_DRIVER is unset or local, uploads land in ./uploads at the project root.
Custom storage provider
If you need a storage backend other than local disk or S3 (e.g. GCS, Azure Blob), implement the StorageProvider interface and bind it in your API module.
import { Readable } from 'stream';
import type { StorageProvider, StorageDownloadResult } from '@marketlum/core';
export class GcsStorageProvider implements StorageProvider {
async upload(key: string, buffer: Buffer): Promise<void> { /* ... */ }
async download(key: string): Promise<StorageDownloadResult> { /* ... */ }
async delete(key: string): Promise<void> { /* ... */ }
}
import { MarketlumCoreModule, STORAGE_PROVIDER } from '@marketlum/core';
import { GcsStorageProvider } from './gcs-storage.provider';
@Module({
imports: [ConfigModule.forRoot({ isGlobal: true, envFilePath: '../.env' }), MarketlumCoreModule],
providers: [
{ provide: STORAGE_PROVIDER, useClass: GcsStorageProvider },
],
})
export class AppModule {}
NestJS' last-binding-wins rule means your provider supersedes the one registered inside MarketlumCoreModule.
Custom configuration
For values that aren't in .env (feature flags, third-party API keys), use NestJS' ConfigModule and inject ConfigService into your own modules. Don't edit @marketlum/core to read new env vars — read them in your own code instead.