Skip to main content

Overview

AmbioSys requires environment variables for database connections, external API integrations, authentication, and service configuration. Each service (backend, bot) has its own .env file.
Never commit .env files to version control. Always use .env.example as a template.

Environment File Locations

ServiceDevelopmentProduction
Backend APIBackend/web-ambiotec/.env.dev.env.prod
GPT BotBackend/gpt4-ambiotec-bot/.env.dev.env.prod
FrontendFrontend/.env.devFrontend/.env.staging

Backend API Variables

Application Configuration

# Server Configuration
NODE_ENV=development
API_HOST=0.0.0.0
API_PORT=3000
APP_API_HOST=http://localhost:3000
APP_CLIENT_HOST=http://localhost:5173

# Session & Security
SESSION_SECRET=your-super-secret-session-key-change-in-production
JWT_SECRET=your-jwt-secret-key-min-32-chars
JWT_EXPIRES=7d
Key Variables:
VariableRequiredDescriptionExample
NODE_ENVYesEnvironment modedevelopment, production
API_HOSTYesServer bind address0.0.0.0, localhost
API_PORTYesServer port3000
APP_API_HOSTYesPublic API URLhttps://api.ambiosys.com
APP_CLIENT_HOSTYesFrontend URL for CORShttps://app.ambiosys.com
SESSION_SECRETYesExpress session secret (32+ chars)Random string
JWT_SECRETYesJWT signing key (32+ chars)Random string
JWT_EXPIRESYesJWT token expiration7d, 24h, 30m
Generate secure secrets using: openssl rand -base64 32

Database Configuration

# PostgreSQL
PG_HOST=localhost
PG_PORT=5432
PG_USER=ambiotec_user
PG_PASSWORD=your-secure-password
PG_DATABASE_AMBIOTEC=ambiotec_db
PG_SEARCH_PATH=db_ambiotec,public

# Connection Pool Settings
PG_POOL_MAX=20
PG_CONN_TIMEOUT=30000
PG_IDLE_TIMEOUT=10000
PG_INIT_CONN_ATTEMPTS=5
Database Variables:
VariableRequiredDescriptionDefault
PG_HOSTYesPostgreSQL hostlocalhost
PG_PORTYesPostgreSQL port5432
PG_USERYesDatabase user-
PG_PASSWORDYesDatabase password-
PG_DATABASE_AMBIOTECYesDatabase nameambiotec_db
PG_SEARCH_PATHYesSchema search pathdb_ambiotec,public
PG_POOL_MAXNoMax pool connections20
PG_CONN_TIMEOUTNoConnection timeout (ms)30000
PG_IDLE_TIMEOUTNoIdle timeout (ms)10000
PG_INIT_CONN_ATTEMPTSNoRetry attempts on startup5

Redis Configuration

# Redis (Session Store & Cache)
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_URL=redis://redis:6379
REDIS_CONN_ATTEMPTS=5
When using Docker Compose, use service name redis as hostname. For external Redis, use IP or domain.

AWS Configuration

# AWS S3 (File Storage)
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_S3_QUOTATIONS_BUCKET=ambiotec-quotations-prod
AWS Variables:
VariableRequiredDescription
AWS_REGIONYesAWS region for S3
AWS_ACCESS_KEY_IDYesIAM access key
AWS_SECRET_ACCESS_KEYYesIAM secret key
AWS_S3_QUOTATIONS_BUCKETYesS3 bucket for quotation files
Ensure IAM user has s3:PutObject, s3:GetObject, s3:DeleteObject permissions on the specified bucket.

Google Services Configuration

# Google OAuth2
GOOGLE_OAUTH_CLIENT_ID=123456789-abcdefg.apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-your-client-secret
GOOGLE_OAUTH_REDIRECT_URI=http://localhost:3000/auth/google/callback

# Google Drive
GOOGLE_QUOTATIONS_FOLDER_ID=1ABCdefGHIjklMNOpqrSTUVwxyz
GOOGLE_SHARE_ROLE=reader
GOOGLE_SHARE_ANYONE_WRITER=false

# Google Sheets (Horas Extra Report)
GOOGLE_SHEETS_HORAS_EXTRA_SPREADSHEET_ID=1abcDEF123XYZ
GOOGLE_SHEETS_HORAS_EXTRA_TAB_NAME=Horas Extra 2026

# Google Maps
GOOGLE_MAPS_API_KEY=AIzaSyBxxxxxxxxxxxxxxxxxxxxxxxx
Google Variables:
VariableRequiredDescription
GOOGLE_OAUTH_CLIENT_IDYesOAuth 2.0 client ID
GOOGLE_OAUTH_CLIENT_SECRETYesOAuth 2.0 client secret
GOOGLE_OAUTH_REDIRECT_URIYesOAuth callback URL
GOOGLE_QUOTATIONS_FOLDER_IDYesDrive folder for quotations
GOOGLE_MAPS_API_KEYYesMaps API key for geocoding
GOOGLE_SHEETS_HORAS_EXTRA_SPREADSHEET_IDNoSpreadsheet ID for overtime reports
1

Create OAuth Credentials

  1. Go to Google Cloud Console
  2. Enable Google Drive API, Google Sheets API, Google Maps API
  3. Create OAuth 2.0 credentials
  4. Add authorized redirect URIs
2

Create Service Account (for Drive/Sheets)

  1. Create service account with Drive and Sheets access
  2. Download JSON key file
  3. Share Drive folders with service account email

Email Configuration (SMTP)

# SMTP Settings
EMAIL_FROM=[email protected]
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=[email protected]
SMTP_PASS=your-app-password

# Management Email Account
SMTP_USER_GERENCIA=[email protected]
SMTP_PASS_GERENCIA=management-app-password

# Email Configuration
EMAIL_BRAND_LOGO_URL=https://ambiosys.com/logo.png
NOTIFY_NEW_REQUEST_TO=[email protected],[email protected]
For Gmail, use App Passwords (not regular password). Enable 2FA first, then generate app password.
Email Variables:
VariableRequiredDescription
EMAIL_FROMYesDefault sender address
SMTP_HOSTYesSMTP server hostname
SMTP_PORTYesSMTP port (587 for TLS, 465 for SSL)
SMTP_SECUREYesUse SSL/TLS (true/false)
SMTP_USERYesSMTP username
SMTP_PASSYesSMTP password
NOTIFY_NEW_REQUEST_TONoComma-separated emails for notifications

WhatsApp Configuration

# WhatsApp Business API
WHATSAPP_TOKEN=EAABxxxxxxxxxxxxxxxxxxxxxxxx
WHATSAPP_PHONE_NUMBER_ID=123456789012345
WHATSAPP_PRINCIPAL_NUMBER_ID=502XXXXXXXX
WHATSAPP_BRAND_LOGO_URL=https://ambiosys.com/whatsapp-logo.png
WhatsApp Variables:
VariableRequiredDescription
WHATSAPP_TOKENYesWhatsApp Business API access token
WHATSAPP_PHONE_NUMBER_IDYesPhone number ID from Meta
WHATSAPP_PRINCIPAL_NUMBER_IDYesPrincipal business phone number
WHATSAPP_BRAND_LOGO_URLNoLogo URL for WhatsApp messages
Obtain WhatsApp credentials from Meta Business Suite.

OpenAI Configuration

# OpenAI API
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Required for:
  • GPT-4 powered chatbot responses
  • AI-assisted quotation generation
  • Intelligent service request classification

Service Type Configuration

# Service Types (IDs from database)
SERVICE_TYPE_SANITARY_ID=1
SERVICE_TYPE_FOSAS_ID=2
SERVICE_TYPE_PTAR_ID=3
SERVICE_TYPE_OTROS_ID=4

# Template Files (Google Drive)
SERVICE_TYPE_SANITARY_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_SANITARY_DELUXE_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_SANITARY_VIP_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_SANITARY_INTERMEDIATE_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_SANITARY_ECONOMY_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_FOSAS_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_PTAR_FILE=1ABCdefGHIjklMNO

# Product Files
SERVICE_TYPE_OTROS_LAVAMANOS_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_OTROS_PASTILLAS_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_OTROS_ROSETAS_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_OTROS_ENZICLEAN_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_OTROS_ENZILIMP_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_OTROS_TRAMPA_GRASA_ACERO_FILE=1ABCdefGHIjklMNO
SERVICE_TYPE_OTROS_TRAMPA_GRASA_FIBRA_FILE=1ABCdefGHIjklMNO
These IDs must match the database seed data. File IDs are Google Drive template document IDs.

Product Configuration

# Product Codes
PRODUCT_CODE_SANITARIO_VIP=SAN-VIP-001
PRODUCT_CODE_SANITARIO_DELUXE=SAN-DLX-001
PRODUCT_CODE_SANITARIO_INTERMEDIATE=SAN-INT-001
PRODUCT_CODE_SANITARIO_ECONOMY=SAN-ECO-001

Additional Configuration

# File Templates
QUOTATION_TEMPLATE_DIR=/usr/src/app/templates/quotations

# Horas Extra Report Settings
HORAS_EXTRA_REPORT_CHUNK_SIZE=5
HORAS_EXTRA_REPORT_MEAL_VALUE=20
HORAS_EXTRA_REPORT_EMAILS=[email protected],[email protected]

GPT Bot Service Variables

Bot Configuration

# Bot Server
NODE_ENV=development
API_WSPP_HOST=0.0.0.0
API_WSPP_PORT=4500

# Database
DB_USER=ambiotec_user
DB_HOST=localhost
DB_NAME_CONTROLFAC=ambiotec_db
DB_PASS=your-secure-password

# Redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=

# OpenAI
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Bot Variables:
VariableRequiredDescription
API_WSPP_HOSTYesBot API bind address
API_WSPP_PORTYesBot API port
DB_HOSTYesPostgreSQL host
DB_NAME_CONTROLFACYesDatabase name
REDIS_HOSTYesRedis host for conversation cache
OPENAI_API_KEYYesOpenAI API key

Frontend Variables

# API Endpoint
VITE_API_URL=http://localhost:3000

# Environment
VITE_ENV=development

# Features
VITE_ENABLE_ANALYTICS=false
VITE_ENABLE_DEBUG=true

Environment Variable Templates

Development Template

# .env.dev
NODE_ENV=development
API_HOST=0.0.0.0
API_PORT=3000
APP_API_HOST=http://localhost:3000
APP_CLIENT_HOST=http://localhost:5173

SESSION_SECRET=dev-session-secret-change-me
JWT_SECRET=dev-jwt-secret-min-32-characters
JWT_EXPIRES=7d

# Database
PG_HOST=localhost
PG_PORT=5432
PG_USER=postgres
PG_PASSWORD=postgres
PG_DATABASE_AMBIOTEC=ambiotec_dev
PG_SEARCH_PATH=db_ambiotec,public

# Redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_URL=redis://redis:6379

# AWS (use dev bucket)
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_S3_QUOTATIONS_BUCKET=ambiotec-quotations-dev

# OpenAI
OPENAI_API_KEY=sk-proj-your-key

# Email (optional in dev)
EMAIL_FROM=dev@localhost
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_SECURE=false

Validation and Testing

Check Required Variables

# Validate backend environment
docker-compose exec backend node -e '
const required = [
  "PG_HOST", "PG_USER", "PG_PASSWORD", "PG_DATABASE_AMBIOTEC",
  "REDIS_HOST", "JWT_SECRET", "SESSION_SECRET"
];
const missing = required.filter(v => !process.env[v]);
if (missing.length) {
  console.error("Missing:", missing);
  process.exit(1);
}
console.log("✓ All required variables set");
'

Test Database Connection

docker-compose exec backend node -e '
const { Pool } = require("pg");
const pool = new Pool({
  host: process.env.PG_HOST,
  port: process.env.PG_PORT,
  user: process.env.PG_USER,
  password: process.env.PG_PASSWORD,
  database: process.env.PG_DATABASE_AMBIOTEC
});
pool.query("SELECT NOW()").then(() => {
  console.log("✓ Database connected");
  process.exit(0);
}).catch(err => {
  console.error("✗ Database error:", err.message);
  process.exit(1);
});
'

Test Redis Connection

docker-compose exec backend node -e '
const redis = require("redis");
const client = redis.createClient({
  host: process.env.REDIS_HOST,
  port: process.env.REDIS_PORT
});
client.on("error", err => {
  console.error("✗ Redis error:", err.message);
  process.exit(1);
});
client.on("connect", () => {
  console.log("✓ Redis connected");
  client.quit();
  process.exit(0);
});
'

Security Best Practices

Critical Security Measures:
  1. Never commit .env files to Git
  2. Use strong, randomly generated secrets (32+ characters)
  3. Rotate secrets regularly (every 90 days)
  4. Use different secrets for dev/staging/prod
  5. Store production secrets in secret management service (AWS Secrets Manager, HashiCorp Vault)
  6. Limit AWS IAM permissions to minimum required
  7. Use read-only database users where possible

Generate Secure Secrets

# Generate random secret
openssl rand -base64 32

# Generate multiple secrets
for i in {1..3}; do openssl rand -base64 32; done

# Generate and export
export JWT_SECRET=$(openssl rand -base64 32)
echo "JWT_SECRET=$JWT_SECRET"

Environment Variable Encryption

For sensitive production environments, consider encrypting .env files:
# Encrypt env file
gpg --symmetric --cipher-algo AES256 .env.prod

# Decrypt at deployment
gpg --decrypt .env.prod.gpg > .env.prod

Troubleshooting

Variables not loaded

Issue: Environment variables not available in container
# Verify env_file path in docker-compose.yml
services:
  backend:
    env_file:
      - ./Backend/web-ambiotec/.env  # Check this path

# Check if file exists
ls -la Backend/web-ambiotec/.env

# Restart services to reload
docker-compose restart backend

Variable precedence issues

Issue: Wrong value loaded (docker-compose.yml overrides .env)
# Check effective configuration
docker-compose config

# Priority (highest to lowest):
# 1. docker-compose.yml environment:
# 2. docker-compose.yml env_file:
# 3. Dockerfile ENV
# 4. Shell environment

Next Steps

Docker Setup

Deploy services using Docker Compose

Database Setup

Initialize PostgreSQL with schemas and seed data

Build docs developers (and LLMs) love