Skip to main content

Overview

PhotoFlow uses environment variables to configure database connections, network settings, and application behavior. These variables are stored in a .env file in the project root.
Never commit your .env file to version control. It contains sensitive information like database passwords.

Environment File

Create a .env file in your project root:
touch .env
This file is automatically loaded by the application and should be listed in .gitignore.

Required Variables

DATABASE_URL

The PostgreSQL database connection string.
.env
DATABASE_URL="postgresql://[user]:[password]@[host]:[port]/[database]"
Format breakdown:
  • postgresql:// - Database type (always PostgreSQL)
  • [user] - Database username
  • [password] - Database password
  • [host] - Database server hostname or IP
  • [port] - Database port (default: 5432)
  • [database] - Database name
Examples:
.env
DATABASE_URL="postgresql://photoflow:photoflow_password@localhost:5432/photoflow"
For local development where PostgreSQL runs on the same machine.
Use different database names for development and production (e.g., photoflow_dev and photoflow_prod) to avoid accidental data mixing.

Special Characters in Passwords

If your password contains special characters, URL-encode them:
# Password: my@pass#word
DATABASE_URL="postgresql://user:my%40pass%23word@localhost:5432/photoflow"
Common encodings:
  • @ becomes %40
  • # becomes %23
  • $ becomes %24
  • / becomes %2F
  • ? becomes %3F

Optional Variables

VITE_SOCKET_URL

Configures the Socket.io connection URL for real-time synchronization.
.env
VITE_SOCKET_URL="http://localhost:3000"
When to set this:
  • When other PCs need to connect to the server
  • In production deployments
  • When using a reverse proxy
Default behavior: If not set, Socket.io connects to window.location (the current page URL), which works for:
  • Single-PC installations
  • Local development
  • When clients access via the correct URL already
Multi-PC setup example:
.env
# Server PC IP address
VITE_SOCKET_URL="http://192.168.1.100:3000"
All client PCs will connect to this URL for real-time updates.
The VITE_ prefix exposes this variable to the client-side code. Without this prefix, the variable would only be available on the server.

NODE_ENV

Specifies the environment mode.
.env
NODE_ENV="production"
Valid values:
  • development - Development mode with debugging
  • production - Production mode with optimizations
  • test - Testing environment
Effects:
  • Logging verbosity
  • Error message detail
  • Performance optimizations
  • Build process behavior
In production, always set NODE_ENV=production for better performance and security.

PORT

The port number for the application server.
.env
PORT=3000
Default:
  • Development: 5173 (Vite dev server)
  • Production: 4173 (preview) or 3000 (custom)
Change port:
.env
PORT=8080
Access at http://localhost:8080

Docker Environment Variables

When using Docker, environment variables can be set in docker-compose.yml:
docker-compose.yml
services:
  postgres:
    environment:
      POSTGRES_USER: photoflow
      POSTGRES_PASSWORD: photoflow_password
      POSTGRES_DB: photoflow

  app:
    environment:
      - DATABASE_URL=postgresql://photoflow:photoflow_password@postgres:5432/photoflow
      - NODE_ENV=production
      - VITE_SOCKET_URL=http://localhost:3000
Docker Compose can also read from a .env file:
docker-compose.yml
services:
  app:
    env_file:
      - .env
Or reference variables:
docker-compose.yml
services:
  postgres:
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
Then in .env:
.env
POSTGRES_PASSWORD=secure_password_here

Coolify Environment Variables

For Coolify deployments, environment variables are set differently:
docker-compose.coolify.yml
services:
  app:
    environment:
      - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
      - NODE_ENV=production
      - VITE_SOCKET_URL=${COOLIFY_URL}
Coolify provides:
  • ${COOLIFY_URL} - Automatically set to your deployment URL
  • ${POSTGRES_USER}, ${POSTGRES_PASSWORD}, ${POSTGRES_DB} - Set in Coolify UI
See Coolify Deployment for details.

Environment File Example

Here’s a complete .env.example file from the repository:
.env.example
# Database URL for PostgreSQL
# For local development: postgresql://photoflow:photoflow_password@localhost:5432/photoflow
# For Docker: postgresql://photoflow:photoflow_password@postgres:5432/photoflow
DATABASE_URL="postgresql://photoflow:photoflow_password@localhost:5432/photoflow"
1

Copy Example File

cp .env.example .env
2

Edit Values

Update the .env file with your actual configuration:
nano .env  # or use your preferred editor
3

Set Secure Values

Replace default passwords with strong, unique passwords.

Security Best Practices

Strong Passwords

Use complex passwords with:
  • Minimum 16 characters
  • Mix of letters, numbers, symbols
  • No dictionary words
  • Unique per environment

Never Commit .env

Always add to .gitignore:
.env
.env.local
.env.*.local

Restrict Access

Set file permissions:
chmod 600 .env
Only owner can read/write.

Separate Environments

Use different values for:
  • Development
  • Staging
  • Production

Accessing Environment Variables

Server-Side (Node.js)

Access via process.env:
const databaseUrl = process.env.DATABASE_URL;

Client-Side (Browser)

Only variables prefixed with VITE_ are exposed:
const socketUrl = import.meta.env.VITE_SOCKET_URL;
Never expose sensitive information (passwords, API keys) to the client. Don’t use the VITE_ prefix for secrets.

Prisma

Prisma automatically reads DATABASE_URL from .env:
schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

Environment-Specific Configuration

Development

.env.development
DATABASE_URL="postgresql://photoflow:dev_password@localhost:5432/photoflow_dev"
NODE_ENV="development"
VITE_SOCKET_URL="http://localhost:5173"

Production

.env.production
DATABASE_URL="postgresql://photoflow:[email protected]:5432/photoflow_prod"
NODE_ENV="production"
VITE_SOCKET_URL="http://192.168.1.100:3000"
PORT=3000

Troubleshooting

  1. Ensure .env is in the project root
  2. Check file is named exactly .env (not .env.txt)
  3. Restart the application after changing .env
  4. Verify file permissions allow reading
  1. Verify DATABASE_URL format is correct
  2. Test database credentials manually:
psql postgresql://user:pass@host:port/dbname
  1. Check PostgreSQL is running
  2. Verify network connectivity to database host
  3. Encode special characters in password
  1. Check VITE_SOCKET_URL uses correct IP/hostname
  2. Ensure port is accessible (no firewall blocking)
  3. Verify protocol (http:// or https://)
  4. Check browser console for connection errors
  1. Ensure variable name starts with VITE_
  2. Rebuild the application:
npm run build
  1. Vite injects variables at build time, not runtime

Production Secrets Management

For production environments, consider using a secrets management system:
docker-compose.yml
services:
  app:
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

Next Steps

Database Setup

Configure PostgreSQL for PhotoFlow

Network Setup

Configure multi-PC network access

Docker Deployment

Deploy with Docker using environment variables

Production Checklist

Security and configuration best practices

Build docs developers (and LLMs) love