Environment Variables
This reference documents all environment variables used across PSS Bids Manager services.
Never commit secrets to version control. Use .env files locally and secure secret management in production.
Shared Variables
These variables must be consistent across all services:
SuperTokens Configuration
| Variable | Description | Example |
|---|---|---|
SUPERTOKENS_CONNECTION_URI | Self-hosted SuperTokens Core URL | http://supertokens:3567 |
SUPERTOKENS_API_KEY | API key for SuperTokens Core (if configured) | (leave empty for local) |
SUPERTOKENS_DASHBOARD_API_KEY | Dashboard access key | openssl rand -base64 32 |
App Domains (Critical for CORS & Cookies)
| Variable | Description | Example |
|---|---|---|
API_DOMAIN | Backend API base URL | https://bids.precisionsiteservices.com |
WEBSITE_DOMAIN | Frontend app URL | https://bids.precisionsiteservices.com |
PORTAL_URL | Authentication portal URL | https://portal.precisionsiteservices.com |
Domain configuration is critical. SuperTokens uses these for CORS headers and cookie domains. Mismatched domains will cause authentication failures.
Other Shared Variables
| Variable | Description | Example |
|---|---|---|
GCP_PROJECT_ID | Google Cloud project ID | forge-475221 |
SuperTokens Authentication: ForgeX uses self-hosted SuperTokens Core with Google OAuth. Session management is handled via HTTP-only cookies across all subdomains — no JWT tokens are used.
Generate secure secrets with:
openssl rand -base64 32
Or with Node.js:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Bids Service
Backend (services/bids/backend/.env)
- Required
- Optional
DATABASE_URLstringrequiredPostgreSQL connection string.
Local: postgresql://postgres:devpassword@localhost:5432/bids_db?schema=public
Production: Cloud SQL connection string
SUPERTOKENS_CONNECTION_URIstringrequiredURL of the self-hosted SuperTokens Core instance.
Local: http://supertokens:3567 (Docker Compose)
Production: Your SuperTokens Core deployment URL
GOOGLE_CLIENT_IDstringrequiredGoogle OAuth Client ID from GCP Console.
GOOGLE_CLIENT_SECRETstringrequiredGoogle OAuth Client Secret from GCP Console.
Keep this secret! Never commit to version control.
ALLOWED_EMAIL_DOMAINSstringrequiredComma-separated list of allowed email domains.
Example: precisionsiteservices.com,precisionsiteworks.com,sitedrywall.com
PORTnumberdefault: 5000Server port
NODE_ENVstringdefault: developmentEnvironment: development or production
SERVICE_TOKENstringToken for inter-service API calls
GCP_PROJECT_IDstringGoogle Cloud project ID for Pub/Sub
GOOGLE_APPLICATION_CREDENTIALSstringPath to service account JSON file for Google APIs (Sheets, Drive, Gmail).
Local: ../../gcp-key.json
Docker: /gcp/application_default_credentials.json
Production: Use Workload Identity or Secret Manager
GMAIL_SENDER_EMAILstringdefault: it@precisionsiteservices.comEmail address to send invitation emails from. Must be a valid email in your Google Workspace domain. Requires service account with domain-wide delegation and gmail.send scope.
RESEND_API_KEYstringAPI key for Resend email service (transactional emails).
Get from: https://resend.com/api-keys
EMAIL_FROMstringdefault: Precision Platform <noreply@precisionsiteservices.com>From address for transactional emails sent via Resend
GCS_BUCKET_NAMEstringdefault: forge-475221-attachmentsGoogle Cloud Storage bucket name for bid attachments.
Local: Works without GCS (files stored locally)
Production: Must configure GCS bucket and service account
Frontend (services/bids/frontend/.env)
VITE_API_URLstringrequiredBackend API URL.
Local: http://localhost:5001/api
Production: https://bids.precisionsiteservices.com/api
VITE_PORTAL_URLstringrequiredPortal URL for authentication.
Local: http://localhost:3000
Production: https://forge.precisionsiteservices.com
VITE_GOOGLE_CLIENT_IDstringrequiredGoogle OAuth Client ID (same as backend)
Projects Service
Backend (services/projects/backend/.env)
- Required
- Optional
DATABASE_URLstringrequiredPostgreSQL connection string (port 5433 for Projects).
Local: postgresql://postgres:devpassword@localhost:5433/projects_db?schema=public
SUPERTOKENS_CONNECTION_URIstringrequiredMust match Bids service SuperTokens config
BIDS_API_URLstringrequiredBids service API URL for inter-service calls.
Local: http://localhost:5001/api
Production: https://bids.precisionsiteservices.com/api
SERVICE_TOKENstringrequiredToken for authenticating inter-service API calls
PORTnumberdefault: 5000Server port (mapped to 5002 in Docker)
NODE_ENVstringdefault: developmentEnvironment mode
GCP_PROJECT_IDstringGoogle Cloud project ID
ENABLE_PUBSUBbooleandefault: falseEnable Pub/Sub messaging
PUBSUB_EMULATOR_HOSTstringPub/Sub emulator host for local development
Field Service
Backend (services/field/backend/.env)
- Required
- GPS & Security
- Storage
- Server
DATABASE_URLstringrequiredPostgreSQL connection string (port 5434 for Field).
Local: postgresql://postgres:devpassword@localhost:5434/field_db?schema=public
SUPERTOKENS_CONNECTION_URIstringrequiredMust match Bids and Projects services
PROJECTS_API_URLstringrequiredProjects service API URL.
Local: http://localhost:5002/api
BIDS_API_URLstringrequiredBids service API URL.
Local: http://localhost:5001/api
GPS_VALIDATION_ENABLEDbooleandefault: trueEnable GPS geofence validation for clock in/out
GPS_MAX_DISTANCE_MILESnumberdefault: 5Maximum distance from project site for GPS validation
PIN_MAX_ATTEMPTSnumberdefault: 5Maximum PIN entry attempts before lockout
PIN_LOCKOUT_DURATION_MINUTESnumberdefault: 15Lockout duration after max PIN attempts
GCP_PROJECT_IDstringGoogle Cloud project ID
GCP_STORAGE_BUCKET_DAILY_REPORTSstringGCS bucket for daily report images
BIDS_INTEGRATION_CACHE_TTLnumberdefault: 3600Cache TTL for Bids service data (seconds)
PORTnumberdefault: 5003Server port
NODE_ENVstringdefault: developmentEnvironment mode
ALLOWED_ORIGINSstringCORS allowed origins (comma-separated)
MOCK_PROJECTS_INTEGRATIONbooleandefault: falseUse mock data instead of Projects service
Docker Compose Ports
When running with Docker Compose, services use these ports:
| Service | Internal Port | External Port |
|---|---|---|
| Portal | 3000 | 3000 |
| Bids Frontend | 3001 | 3001 |
| Bids Backend | 5000 | 5001 |
| Projects Frontend | 3002 | 3002 |
| Projects Backend | 5000 | 5002 |
| Field Frontend | 3003 | 3003 |
| Field Backend | 5003 | 5003 |
| Bids DB | 5432 | 5432 |
| Projects DB | 5432 | 5433 |
| Field DB | 5432 | 5434 |
Production Deployment
Cloud Run Environment Variables
Set environment variables in Cloud Run with:
gcloud run deploy bids-backend \
--set-env-vars="NODE_ENV=production" \
--set-env-vars="SUPERTOKENS_CONNECTION_URI=your-production-secret" \
--set-env-vars="DATABASE_URL=postgresql://..." \
--set-env-vars="GOOGLE_CLIENT_ID=..." \
--set-env-vars="GOOGLE_CLIENT_SECRET=..."
Cloud SQL Connection
For Cloud SQL, use the socket path format:
DATABASE_URL=postgresql://user:password@localhost/dbname?host=/cloudsql/PROJECT:REGION:INSTANCE
Do NOT use @/dbname format - this causes empty host errors. Always include @localhost/dbname.
Secret Manager
For sensitive values, consider using Google Secret Manager:
# Create secret
echo -n "your-secret-value" | gcloud secrets create SUPERTOKENS_CONNECTION_URI --data-file=-
# Reference in Cloud Run
gcloud run deploy bids-backend \
--set-secrets="SUPERTOKENS_CONNECTION_URI=SUPERTOKENS_CONNECTION_URI:latest"
Local Development Setup
cp services/bids/backend/.env.example services/bids/backend/.env
cp services/bids/frontend/.env.example services/bids/frontend/.env
- Go to GCP Console
- Create OAuth 2.0 Client ID
- Copy Client ID and Secret to
.envfiles
Set SUPERTOKENS_CONNECTION_URI in all backend .env files.
Local: http://supertokens:3567 (Docker Compose)
Production: Your SuperTokens Core URL
docker-compose up -d
Troubleshooting
Authentication fails across services
Ensure SUPERTOKENS_CONNECTION_URI and domain config (API_DOMAIN, WEBSITE_DOMAIN) are identical in all backend .env files. SuperTokens cookies must share the same domain (.precisionsiteservices.com in production).
Google OAuth returns error
- Verify
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETare correct - Check that redirect URIs are configured in GCP Console
- Ensure your email domain is in
ALLOWED_EMAIL_DOMAINS
Database connection refused
- Check Docker containers are running:
docker-compose ps - Verify port mapping matches your
DATABASE_URL - For Cloud SQL, check socket path format
Inter-service calls fail
- Verify
SERVICE_TOKENmatches between services - Check
BIDS_API_URL/PROJECTS_API_URLare reachable - In Docker, use service names (e.g.,
http://bids-backend:5000/api)