OpenEco Documentation

Self-hosted climate transparency for enterprises

View the Project on GitHub Open-Eco/oe-core

OpenEco Installation Guide

This guide covers all installation scenarios: local development, enterprise self-hosting, and public site deployment.


Table of Contents

  1. Getting Started: Enterprise DeploymentStart here for production deployments
  2. Target Environments
  3. Quick Start (Local Development)
  4. Enterprise Self-Hosting
  5. Public Site Deployment
  6. Upgrades and Rollbacks
  7. Enterprise Installation Checklist
  8. Troubleshooting

Getting Started: Enterprise Deployment

This section provides a step-by-step guide for companies deploying OpenEco on their own infrastructure.

Overview

OpenEco is self-hosted software. Each company runs its own isolated deployment with its own PostgreSQL database. You can deploy on:

Time estimate: 2-4 hours for a pilot deployment, 1-2 days for production.


Step-by-Step Deployment Flow

Step 1: Choose Your Deployment Model

Option A: Single Host (Recommended for Pilots)

Option B: Kubernetes/OKD/OpenShift (Production)


Step 2: Provision Infrastructure

For Single Host Deployment:

  1. Get a Linux server
    • Minimum: 2 CPU cores, 4GB RAM, 50GB storage
    • Recommended: 4+ CPU cores, 8GB+ RAM, 100GB+ storage
    • OS: RHEL 8+, Ubuntu 20.04+, Debian 11+, or similar
  2. Install Podman or Docker

    RHEL/CentOS/Fedora:

    sudo dnf install podman podman-compose
    

    Ubuntu/Debian:

    sudo apt-get update
    sudo apt-get install podman podman-compose
    # or
    sudo apt-get install docker.io docker-compose
    
  3. Verify installation
    podman --version  # Should show 4.x or higher
    podman-compose --version
    

For Kubernetes Deployment:


Step 3: Set Up PostgreSQL Database

Option 1: Managed PostgreSQL (Recommended for Production)

Use your company’s managed PostgreSQL service:

Steps:

  1. Create a new database: openeco
  2. Create a database user with appropriate permissions:
    CREATE USER openeco_user WITH PASSWORD 'your-secure-password';
    GRANT ALL PRIVILEGES ON DATABASE openeco TO openeco_user;
    
  3. Note your connection string:
    postgresql://openeco_user:password@postgres.mycorp.internal:5432/openeco?schema=public
    

Option 2: Containerized PostgreSQL (For Pilots)

If you don’t have managed PostgreSQL, run it in a container:

podman run --name openeco-postgres \
  -e POSTGRES_PASSWORD=your-secure-password \
  -e POSTGRES_DB=openeco \
  -e POSTGRES_USER=openeco_user \
  -p 5432:5432 \
  -v openeco-postgres-data:/var/lib/postgresql/data \
  -d postgres:15

Important: For production, use managed PostgreSQL with automated backups.


Step 4: Configure Environment Variables

Create a file to store your configuration. You’ll need these variables:

Required Variables:

# Database Connection (REQUIRED)
DATABASE_URL="postgresql://openeco_user:password@host:5432/openeco?schema=public"

# Authentication Secret (REQUIRED)
# Generate with: openssl rand -base64 32
NEXTAUTH_SECRET="your-long-random-secret-minimum-32-characters"

# Application URL (REQUIRED)
# The public URL where OpenEco will be accessible
NEXTAUTH_URL="https://climate.yourcompany.com"
NEXT_PUBLIC_APP_URL="https://climate.yourcompany.com"

# Application Name (OPTIONAL)
NEXT_PUBLIC_APP_NAME="OpenEco"

Generate NEXTAUTH_SECRET:

openssl rand -base64 32

Security Note: Never commit these values to version control. Use environment variables or secrets management.


Step 5: Deploy the Application

For Single Host (Podman/Docker Compose):

  1. Get the deployment files:
    git clone https://github.com/Open-Eco/oe-core.git
    cd oe-core/deploy
    
  2. Create or edit compose.prod.yml:
    version: '3.8'
       
    services:
      web:
        image: ghcr.io/open-eco/oe-core:web-latest
        container_name: openeco-web
        ports:
          - "3000:3000"
        environment:
          DATABASE_URL: ${DATABASE_URL}
          NEXTAUTH_URL: ${NEXTAUTH_URL}
          NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
          NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL}
          NEXT_PUBLIC_APP_NAME: ${NEXT_PUBLIC_APP_NAME:-OpenEco}
        restart: unless-stopped
        healthcheck:
          test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
          interval: 30s
          timeout: 10s
          retries: 3
    
  3. Create .env file in the same directory:
    # .env
    DATABASE_URL=postgresql://openeco_user:password@postgres:5432/openeco?schema=public
    NEXTAUTH_URL=https://climate.yourcompany.com
    NEXTAUTH_SECRET=your-generated-secret-here
    NEXT_PUBLIC_APP_URL=https://climate.yourcompany.com
    NEXT_PUBLIC_APP_NAME=OpenEco
    
  4. Start the application:
    podman-compose -f compose.prod.yml up -d
    # or
    docker-compose -f compose.prod.yml up -d
    
  5. Check logs:
    podman logs -f openeco-web
    

For Kubernetes/OKD/OpenShift:

  1. Create secrets:
    kubectl create namespace openeco
       
    kubectl create secret generic openeco-secrets \
      --namespace=openeco \
      --from-literal=DATABASE_URL="postgresql://user:pass@host:5432/openeco" \
      --from-literal=NEXTAUTH_SECRET="your-secret-here"
       
    kubectl create configmap openeco-config \
      --namespace=openeco \
      --from-literal=NEXTAUTH_URL="https://climate.yourcompany.com" \
      --from-literal=NEXT_PUBLIC_APP_URL="https://climate.yourcompany.com" \
      --from-literal=NEXT_PUBLIC_APP_NAME="OpenEco"
    
  2. Deploy using manifests:
    cd oe-core/deploy/okd
    kubectl apply -f deployment-web.yaml
    kubectl apply -f service-web.yaml
    
  3. Create Ingress/Route:
    # For Kubernetes
    kubectl apply -f ingress.yaml
       
    # For OpenShift
    oc apply -f route.yaml
    

Step 6: Run Database Migrations

The database schema needs to be initialized. Run this one-time migration:

For Single Host:

podman run --rm \
  --env DATABASE_URL="postgresql://openeco_user:password@postgres:5432/openeco?schema=public" \
  ghcr.io/open-eco/oe-core:web-latest \
  npx prisma db push

For Kubernetes:

kubectl run openeco-migrate --rm -i --tty \
  --namespace=openeco \
  --image=ghcr.io/open-eco/oe-core:web-latest \
  --env="DATABASE_URL=postgresql://..." \
  -- npx prisma db push

Expected output:

✔ Generated Prisma Client
Your database is now in sync with your Prisma schema.

Step 7: Configure Reverse Proxy & SSL

Set up NGINX (Recommended):

  1. Install NGINX:
    # RHEL/CentOS/Fedora
    sudo dnf install nginx
       
    # Ubuntu/Debian
    sudo apt-get install nginx
    
  2. Create configuration file:
    sudo nano /etc/nginx/sites-available/openeco
    
  3. Add configuration:
    server {
        listen 80;
        server_name climate.yourcompany.com;
           
        location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_cache_bypass $http_upgrade;
        }
    }
    
  4. Enable site:
    sudo ln -s /etc/nginx/sites-available/openeco /etc/nginx/sites-enabled/
    sudo nginx -t  # Test configuration
    sudo systemctl reload nginx
    
  5. Add SSL with Let’s Encrypt:
    sudo dnf install certbot python3-certbot-nginx
    # or
    sudo apt-get install certbot python3-certbot-nginx
       
    sudo certbot --nginx -d climate.yourcompany.com
    

Alternative: Use Traefik or Caddy (both have automatic SSL)


Step 8: Configure DNS

Point your domain to your server:

DNS Records:

Type: A
Name: climate (or @ for root domain)
Value: [Your server's IP address]
TTL: 3600

Or if using a load balancer:

Type: CNAME
Name: climate
Value: [Your load balancer hostname]
TTL: 3600

Verify DNS propagation:

dig climate.yourcompany.com
# or
nslookup climate.yourcompany.com

Step 9: Verify Deployment

  1. Visit your URL:
    https://climate.yourcompany.com
    
  2. Test functionality:
    • Homepage loads
    • Can create an account
    • Can sign in
    • Dashboard loads
    • Can create an organization
    • Can enter activity data
  3. Check application logs:
    # Single host
    podman logs -f openeco-web
       
    # Kubernetes
    kubectl logs -f deployment/openeco-web -n openeco
    
  4. Check database connectivity:
    # Verify data is being stored
    psql -h postgres-host -U openeco_user -d openeco -c "SELECT COUNT(*) FROM \"User\";"
    

Step 10: Set Up Monitoring & Backups

Monitoring:

Backups:


Deployment Checklist

Use this checklist to ensure you’ve completed all steps:


Troubleshooting

Application won’t start:

Database connection errors:

SSL/HTTPS issues:

502 Bad Gateway:


Next Steps

After deployment:

  1. Create your first organization in OpenEco
  2. Invite team members to your organization
  3. Configure emission factors (see Factor Library documentation)
  4. Start entering activity data
  5. Set up reporting periods

For more details, see:


Target Environments (Officially Supported)

OpenEco is designed to be deployed in the following environments. All of them use the same OCI image for the web application; only the runtime and infrastructure differ.

Environment Recommended Pattern Notes
Linux Server Podman/Docker + Compose (single host) Primary, simplest path for pilots and production. See Option A: Single Host.
Windows Server Run Linux containers via WSL2 or a small Linux VM Windows Server hosts a Linux VM/WSL2 instance that runs the same Podman/Docker + Compose stack as Linux. IIS/NGINX on Windows can reverse proxy to the Linux VM if desired.
Kubernetes / OKD / OpenShift Native K8s/OKD deployment Use the manifests in deploy/okd/ with the same web image. See Option B: Kubernetes / OKD / OpenShift.

Key idea:


Quick Start (Local Development)

Prerequisites

Setup

# Clone the repository
git clone https://github.com/Open-Eco/oe-core.git
cd oe-core

# Install dependencies
cd web
npm install

# Configure environment
cp .env.example .env.local
# Edit .env.local with your database credentials

# Run database migrations
npm run db:push

# Start development server
npm run dev

Visit http://localhost:3000

Environment Variables

Create web/.env.local:

# Database (required)
DATABASE_URL="postgresql://user:password@localhost:5432/openeco?schema=public"

# Auth (required)
NEXTAUTH_SECRET="your-secret-key-min-32-chars"
NEXTAUTH_URL="http://localhost:3000"

# App (optional)
NEXT_PUBLIC_APP_URL="http://localhost:3000"
NEXT_PUBLIC_APP_NAME="OpenEco"

Local PostgreSQL Options

Option 1: Containerized (Recommended)

# Podman
podman run --name openeco-postgres \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=openeco \
  -p 5432:5432 -d postgres:15

# Docker
docker run --name openeco-postgres \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=openeco \
  -p 5432:5432 -d postgres:15

Option 2: System PostgreSQL

# Create database
createdb openeco

Enterprise Self-Hosting

Each enterprise runs its own isolated deployment with its own PostgreSQL database.

Deployment Models

Model Best For Complexity
Single Host Pilots, small teams Low
Kubernetes/OKD Production, HA Medium
Cloud Marketplace AWS/Azure/GCP users Low

Option A: Single Host (Podman/Docker + Compose)

Requirements

Step 1: Provision PostgreSQL

Managed PostgreSQL (Recommended for Production):

Containerized PostgreSQL (Pilots):

podman run --name openeco-postgres \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=openeco \
  -p 5432:5432 -d postgres:15

Step 2: Configure Compose File

Use deploy/compose.dev.yml as a starting point:

services:
  web:
    image: ghcr.io/open-eco/oe-core:web-latest
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://openeco_user:password@postgres:5432/openeco?schema=public
      NEXTAUTH_URL: https://climate.yourcompany.com
      NEXTAUTH_SECRET: change-me-to-a-long-random-secret
      NEXT_PUBLIC_APP_URL: https://climate.yourcompany.com
      NEXT_PUBLIC_APP_NAME: OpenEco

Step 3: Run the Stack

cd deploy

# Podman Compose
podman-compose -f compose.dev.yml up -d

# Docker Compose
docker-compose -f compose.dev.yml up -d

Step 4: Run Migrations

# One-off migration job
podman run --rm \
  --env DATABASE_URL=postgresql://... \
  ghcr.io/open-eco/oe-core:web-latest \
  npx prisma db push

Visit https://climate.yourcompany.com

Option B: Kubernetes / OKD / OpenShift

Requirements

Step 1: Build and Push Image

# Build with Buildah
buildah bud -t registry.example.com/openeco/web:latest ./web

# Push
podman push registry.example.com/openeco/web:latest

Step 2: Create ConfigMap and Secret

Edit deploy/okd/config-and-secrets.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: openeco-config
data:
  NEXTAUTH_URL: "https://climate.yourcompany.com"
  NEXT_PUBLIC_APP_URL: "https://climate.yourcompany.com"
---
apiVersion: v1
kind: Secret
metadata:
  name: openeco-secrets
type: Opaque
stringData:
  DATABASE_URL: "postgresql://user:pass@postgres:5432/openeco"
  NEXTAUTH_SECRET: "your-secret-key"

Apply:

kubectl apply -f deploy/okd/config-and-secrets.yaml
# or
oc apply -f deploy/okd/config-and-secrets.yaml

Step 3: Deploy Application

kubectl apply -f deploy/okd/deployment-web.yaml
kubectl apply -f deploy/okd/service-web.yaml

Step 4: Create Ingress/Route

Kubernetes Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: openeco-web
spec:
  rules:
    - host: climate.yourcompany.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: openeco-web
                port:
                  number: 80

OpenShift Route:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: openeco-web
spec:
  host: climate.yourcompany.com
  to:
    kind: Service
    name: openeco-web
  tls:
    termination: edge

Per-Enterprise Isolation

For each enterprise:

  1. Create separate namespace: openeco-acme, openeco-contoso
  2. Deploy same manifests with different:
    • DATABASE_URL (separate Postgres instance/schema)
    • NEXTAUTH_URL (their domain)
  3. Result: One codebase, many isolated installations

Public Site Deployment

Demo Site → Pterodactyl

Platform: Pterodactyl Panel
Domain: demo.open-eco.org


Vercel Deployment (Managed Hosting)

Best for: Demo sites, previews, small teams (non-enterprise production)

Vercel provides automatic deployments from GitHub with zero configuration for Next.js applications.

Time: ~10 minutes
Cost: Free tier available, pay-as-you-go for production

For complete Vercel deployment guide, see:

Quick Deploy

Deploy with Vercel


OpenEco demo is hosted on Pterodactyl, a game server management platform that can manage Docker containers for applications. The demo runs as a full OpenEco instance with demo data stored in browser sessionStorage.

Quick Setup

Option 1: Using Docker Compose (Standalone)

  1. Run Setup Script:
    ./scripts/pterodactyl-setup.sh
    
  2. Configure Environment:
    # Edit environment variables
    vi deploy/pterodactyl/.env
    
  3. Start Demo:
    cd deploy/pterodactyl
    docker-compose -f docker-compose.demo.yml up -d
    
  4. Run Migrations:
    docker-compose -f docker-compose.demo.yml exec web npx prisma db push
    

Option 2: Using Pterodactyl Panel

  1. Install Pterodactyl (if not installed):
  2. Create Demo Server:
    • Log into Pterodactyl Panel
    • Create new server: Name: OpenEco Demo
    • Nest: Node.js (or import custom egg from deploy/pterodactyl/pterodactyl-egg.json)
    • Docker Image: ghcr.io/open-eco/oe-core:web-latest
    • Startup Command: npm run start
  3. Configure Environment Variables:
    DATABASE_URL=postgresql://openeco_demo:password@postgres:5432/openeco_demo?schema=public
    NEXTAUTH_SECRET=your-secret-key-min-32-chars
    NEXTAUTH_URL=https://demo.open-eco.org
    NEXT_PUBLIC_APP_URL=https://demo.open-eco.org
    NODE_ENV=production
    PORT=3000
    
  4. Set Up Database:
    • Create PostgreSQL container/server in Pterodactyl
    • Or use external PostgreSQL database
    • Update DATABASE_URL with correct connection string
  5. Run Migrations:
    • In server console: npx prisma generate && npx prisma db push
  6. Configure Domain & SSL:
    • Set up reverse proxy (Nginx/Caddy) or use Pterodactyl’s proxy
    • Configure SSL certificate (Let’s Encrypt recommended)

Detailed Instructions

For complete setup instructions, troubleshooting, and maintenance:

Demo Characteristics

Documentation Site → GitHub Pages

Platform: GitHub Pages
Domain: docs.open-eco.org

Setup

  1. Enable GitHub Pages
    • Repository Settings → Pages
    • Source: Deploy from a branch
    • Branch: main, Folder: /docs
  2. Add Custom Domain (Optional)
    echo "docs.open-eco.org" > docs/CREDENTIALS
    
  3. Configure DNS
    Type: CNAME
    Name: docs
    Value: open-eco.github.io
    
  4. Auto-Deployment
    • Rebuilds on push to main (when docs/ changes)

DNS Configuration Summary

# Demo site (Vercel)
Type: CNAME
Name: demo (or @)
Value: cname.vercel-dns.com

# Documentation (GitHub Pages)
Type: CNAME
Name: docs
Value: open-eco.github.io

Upgrades and Rollbacks

Upgrades

  1. Build and push new image version (:v1.1.0)
  2. Update image: tag in manifests or compose file
  3. Apply: kubectl apply -f or podman-compose up -d

Kubernetes/OKD performs rolling updates automatically.

Rollbacks


Enterprise Installation Checklist


Troubleshooting

Application Not Loading

Database Connection Failed

SSL/HTTPS Issues

DNS Not Resolving



Need help? Open an issue on GitHub.