Part of the Sanchayam series.

Overview

Sanchayam has two deployable components:

  • Backend: Node.js process running as a systemd service behind nginx
  • Frontend: Static React build deployed to S3, served via CloudFront

Prerequisites

  • A Linux server with Node.js 18+ and PostgreSQL
  • An AWS account with an S3 bucket and CloudFront distribution for the frontend
  • A domain with DNS pointing to your server (for TLS)
  • A Twelve Data API key (free tier at twelvedata.com - 8 calls/minute)

Backend

Clone and install:

git clone https://github.com/sagarnayak/sanchayamBackend-public.git
cd sanchayamBackend-public
npm install

Configure:

cp .env.example .env

Edit .env. Generate fresh values for secrets:

openssl rand -hex 64   # JWT_SECRET
openssl rand -hex 32   # ENCRYPTION_KEY

Set DATABASE_URL to your PostgreSQL connection string and FRONTEND_URL to your frontend’s public URL (used for CORS).

Set TWELVE_DATA_API_KEY to your Twelve Data key. Without this, price feeds will not work. The DeepSeek key (DEEPSEEK_API_KEY) is optional - only needed for automated NSE corporate action extraction.

Run migrations:

npm run migrate

Build:

npm run build

Systemd service at /etc/systemd/system/sanchayam.service:

[Unit]
Description=Sanchayam Backend
After=network.target

[Service]
User=youruser
WorkingDirectory=/path/to/sanchayamBackend-public
EnvironmentFile=/path/to/sanchayamBackend-public/.env
ExecStart=/usr/bin/node dist/index.js
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable sanchayam
sudo systemctl start sanchayam

Nginx Reverse Proxy

server {
    listen 443 ssl;
    server_name api.yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3100;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Frontend

Clone and install:

git clone https://github.com/sagarnayak/sanchayamFrontend-public.git
cd sanchayamFrontend-public
npm install

Configure:

cp .env.example .env

Set VITE_API_URL to your backend’s public URL.

Build:

npm run build

Upload the dist/ contents to your S3 bucket. Set the CloudFront default root object to index.html and add a custom error response: 404 -> /index.html with status 200 (required for React Router).

GitHub Actions deployment: The included deploy.yml is set to manual trigger (workflow_dispatch). Add these secrets to your repository:

SecretValue
VITE_API_URLYour backend URL
S3_BUCKETS3 bucket name
AWS_ACCESS_KEY_IDIAM key with S3 and CloudFront permissions
AWS_SECRET_ACCESS_KEYIAM secret
CLOUDFRONT_DISTRIBUTION_IDCloudFront distribution ID

First Run

Visit your frontend URL. With no users in the database, you will be redirected to /setup. Create the master admin account.

Log in as admin. The first step is registering a price provider:

  1. Go to Admin > Collectors and add Twelve Data with your API key
  2. Go to Admin > FX to verify the currency-to-collector mapping is set

Then register your first assets in Admin > Assets. For Indian equities, use symbol = 'TICKER:NSE' (e.g. RELIANCE:NSE). For US equities, use symbol = 'TICKER' (e.g. AAPL). For mutual funds, use the AMFI scheme code as the symbol.

Once assets are registered, invite your first user from Admin > Invitations and share the invite link.

Checklist

  • Backend .env configured with real secrets
  • TWELVE_DATA_API_KEY set
  • Migrations run (npm run migrate)
  • Backend builds cleanly (npm run build)
  • systemd service enabled and running
  • Nginx config and TLS certificate in place
  • Frontend .env pointing to backend URL
  • Frontend built and deployed to S3
  • CloudFront configured with index.html fallback for 404s
  • Twelve Data collector registered in admin panel
  • At least one asset registered
  • First user invited and signed up

Start from the beginning