Skip to content

MicroERP Deployment Guide

This document outlines the complete deployment architecture for MicroERP (Production, Second Production Node, and Staging).

1. Architecture Overview

Environment Branch Hosting (Frontend) Hosting (Backend) Frontend URL Backend URL
Production 1 main Railway Railway https://merp25.up.railway.app https://merp25-api.up.railway.app
Production 2 main Vercel (Prod) Railway (Same) https://ebosai.com
https://merp25.vercel.app
https://merp25-api.up.railway.app
Staging stage Vercel (Preview) Render https://merp25stage.vercel.app https://merp25-backend.onrender.com

2. Production Environment (Main)

Backend (Railway)

  • Repo: GitHub main branch
  • Service: Django Backend
  • Domain: merp25-api.up.railway.app
  • Database: Railway PostgreSQL (Internal)

Frontend 1 (Railway)

  • Repo: GitHub main branch
  • Service: Vite Frontend
  • Domain: merp25.up.railway.app
  • Note: Serves as the primary/fallback host.

Frontend 2 (Vercel)

  • Repo: GitHub main branch
  • Purpose: Primary global CDN fast access.
  • Domains:
    • ebosai.com (Primary Custom Domain)
    • merp25.vercel.app (Fallback)

3. Staging Environment (Pre-Production)

Backend (Render)

  • Repo: GitHub stage branch
  • Platform: Render.com
  • Domain: https://merp25-backend.onrender.com
  • Database: Render PostgreSQL (or external staging DB)

Frontend (Vercel Preview)

  • Repo: GitHub stage branch (linked to merp25 project)
  • Environment: "Preview" (Pre-Production)
  • Domain: https://merp25stage.vercel.app
  • Deployment Setup:
    • Uses Preview Environment Variables to point to Render Backend.
    • Domain is assigned via Settings -> Environments -> Preview.

4. Environment Variables Reference

When setting up new environments or debugging, ensure these variables are set correctly for the Frontend.

Variable Name Production Value (Railway/Vercel) Staging Value (Vercel Preview) Description
VITE_API_URL https://merp25-api.up.railway.app https://merp25-backend.onrender.com Point to the correct Backend API
VITE_SUPABASE_URL https://prod.supabase.co https://stage.supabase.co Your Supabase Project URL
VITE_SUPABASE_ANON_KEY (Production Key) (Staging Key) Public Anon Key for Supabase


6. Supabase Setup Guide

MicroERP uses Supabase PostgreSQL as the primary database AND Supabase Auth for JWT-based authentication. Both must be configured correctly per environment.

6.1 Project Strategy — How Many Supabase Projects?

[!IMPORTANT] The critical rule: Production data must be isolated from non-production data. Use a minimum of 2 Supabase projects.

Supabase Project Covers Database Schema Auth Users
merp25-nonprod Dev + Stage Shared (see 6.3) or separate (see 6.4) Shared — same test credentials work on both
merp25-prod Production only public Real customer accounts only

Why not 3 projects? Dev and stage share the same test data. The risk of mixing dev/stage data is negligible — the critical isolation boundary is non-prod vs prod.


6.2 Supabase Auth — URL Configuration

Each Supabase project must have all its frontend URLs registered or Supabase will reject auth callbacks with Invalid Refresh Token errors.

merp25-nonprod project (Auth → URL Configuration)

Site URL:
  https://merp25stage.vercel.app

Additional Redirect URLs:
  https://merp25stage.vercel.app/**
  https://merp25dev.vercel.app/**
  http://localhost:5173/**

merp25-prod project (Auth → URL Configuration)

Site URL:
  https://ebosai.com

Additional Redirect URLs:
  https://ebosai.com/**
  https://merp25.vercel.app/**
  https://merp25.up.railway.app/**

Dev and stage both point to the same Supabase project and the same public schema. This is acceptable because: - Both environments use test data only - Migrations applied on dev are immediately visible on stage - Only one DATABASE_URL to manage for non-prod

Django DATABASE_URL setup:

Environment DATABASE_URL SUPABASE_URL / SUPABASE_ANON_KEY
Dev backend (Render) postgresql://postgres.[ref]:[pass]@aws-...:5432/postgres Non-prod project values
Stage backend (Render) ← same as Dev ← same as Dev
Prod backend (Railway) postgresql://postgres.[ref]:[pass]@aws-...:5432/postgres Prod project values

Workflow: 1. Developer runs python manage.py migrate on dev 2. Stage picks up the same schema automatically (shared DB) 3. Before go-live, run python manage.py migrate on prod separately


6.4 Option B — Separate Schemas in One Supabase Project

Dev and stage share the same Supabase project but use separate PostgreSQL schemas (dev and stage). This keeps data isolated while staying on one project.

Step 1 — Create schemas in Supabase SQL Editor

-- Run once in Supabase SQL Editor (non-prod project)
CREATE SCHEMA IF NOT EXISTS dev;
CREATE SCHEMA IF NOT EXISTS stage;

-- Grant permissions to the postgres user
GRANT ALL ON SCHEMA dev TO postgres;
GRANT ALL ON SCHEMA stage TO postgres;

Step 2 — Set Django OPTIONS per environment

In settings.py, read the schema from an env var:

import os

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DB_NAME', 'postgres'),
        'USER': os.getenv('DB_USER', 'postgres'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': os.getenv('DB_HOST'),
        'PORT': os.getenv('DB_PORT', '5432'),
        'OPTIONS': {
            'options': f"-c search_path={os.getenv('DB_SCHEMA', 'public')}",
        },
    }
}

Step 3 — Set DB_SCHEMA env var per environment

Platform Environment DB_SCHEMA
Render Dev backend dev
Render Stage backend stage
Railway Prod backend public (prod project, default schema)

Step 4 — Run migrations per schema

# On dev backend
DB_SCHEMA=dev python manage.py migrate

# On stage backend
DB_SCHEMA=stage python manage.py migrate

[!NOTE] Django migrations will create all tables inside the specified schema. Each schema is fully independent — dev.core_company and stage.core_company are separate tables.


6.5 Environment Variables Reference (Updated)

Full updated reference including Supabase database variables:

Backend env vars (Render for dev/stage, Railway for prod):

Variable Dev (Render) Stage (Render) Prod (Railway)
DATABASE_URL Non-prod Supabase DB URL Same as dev (Option A) or same project (Option B) Prod Supabase DB URL
DB_SCHEMA dev (Option B only) stage (Option B only) public or omit
SUPABASE_URL Non-prod project URL Non-prod project URL Prod project URL
SUPABASE_SERVICE_ROLE_KEY Non-prod service key Non-prod service key Prod service key
VITE_SITE_URL https://merp25dev.vercel.app https://merp25stage.vercel.app https://ebosai.com
CORS_ALLOWED_ORIGINS https://merp25dev.vercel.app https://merp25stage.vercel.app https://ebosai.com

Frontend env vars (Vercel per environment):

Variable Dev Stage Prod
VITE_API_URL Render backend URL Render backend URL Railway backend URL
VITE_SUPABASE_URL Non-prod project URL Non-prod project URL Prod project URL
VITE_SUPABASE_ANON_KEY Non-prod anon key Non-prod anon key Prod anon key

6.6 Go-Live Checklist (When Ready for Production)

  • [ ] Create new Supabase project merp25-prod
  • [ ] Copy schema (run python manage.py migrate) against prod Supabase DB
  • [ ] Set Auth → URL Configuration in prod Supabase project (see 6.2)
  • [ ] Update Railway backend env vars to prod Supabase credentials
  • [ ] Update Vercel prod environment vars (VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY)
  • [ ] Update settings.py BASE_ALLOWED_ORIGINS or set CORS_ALLOWED_ORIGINS on Railway
  • [ ] Set VITE_SITE_URL on Railway to the production frontend URL
  • [ ] Verify login works end-to-end on prod before announcing go-live