✓
Live Status
ERP
erp.srigaurangasamaj.com
HTTPS Live
Public Website
srigaurangasamaj.com
HTTPS Live
Auto-Deploy
git push → live
Self-hosted runner
SSL Certificate
all-domains-rsa-2026
Expires 2026-10-30
OCI Load Balancer
dharma-erp-lb
140.245.231.240 · 10 Mbps
Server
ubuntu@10.0.2.89
ap-hyderabad-1 · Private subnet
⚡
Quick Reference
| Task | How |
|---|---|
| Deploy a code change | git push origin main — auto-deploys in ~4 min |
| Manual deploy | GitHub → Actions → "Deploy to OCI" → Run workflow → type deploy |
| SSH to server | Create Bastion session in OCI Console, then use command in §Bastion |
| Check containers | sudo docker compose ps (on server) |
| View deploy logs | GitHub → repo → Actions tab → latest run |
| Check runner health | sudo systemctl status actions.runner.* (on server) |
| Renew SSL cert | See Certificate Renewal section — renew before 2026-10-16 |
| Staff Login on website | Top-right nav (desktop) or hamburger menu (mobile) |
🔐
Bastion SSH Access
Bastion sessions expire. Create a fresh session each time — do not reuse old session OCIDs.
Step 1 — Create a Bastion Session
- OCI Console → Identity & Security → Bastion →
bastion108dharma108erp - Create Session → Session type: Managed SSH
- Target host:
10.0.2.89· OS username:ubuntu - Upload public key:
~/.ssh/dharma-erp-prod.pub - Copy the SSH command shown after the session activates
Step 2 — Connect
Replace <SESSION-OCID> with the OCID from the new session:
ssh -i ~/.ssh/dharma-erp-prod \
-o ProxyCommand="ssh -i ~/.ssh/dharma-erp-prod -W %h:%p -p 22 \
<SESSION-OCID>@host.bastion.ap-hyderabad-1.oci.oraclecloud.com" \
-p 22 ubuntu@10.0.2.89
SSH key: Use
~/.ssh/dharma-erp-prod — not id_ed25519.
🚀
Auto-Deploy via GitHub Actions
Active since 2026-08-01. Every
git push to main rebuilds and restarts the ERP and website automatically.
Architecture
git push → GitHub → Actions workflow trigger
↓
Self-hosted runner (ON the OCI server — /opt/actions-runner)
↓
git pull → docker compose build → restart → health check
Pipeline
| Step | Command |
|---|---|
| 1. Pull latest code | git pull origin main |
| 2. Rebuild images | docker compose build fastapi nextjs website |
| 3. Restart containers | docker compose up -d --no-deps fastapi nextjs nginx website |
| 4. Reload nginx | docker compose exec nginx nginx -s reload |
| 5. Health check | curl -sf http://localhost/health |
Runner Maintenance
sudo systemctl status actions.runner.* # check runner is running
sudo systemctl restart actions.runner.* # restart if needed
sudo journalctl -u actions.runner.* -f # view live logs
Re-Installing the Runner (new server)
- GitHub → Settings → Actions → Runners → New self-hosted runner (Linux/x64)
- Run the config command with the registration token on the server in
/opt/actions-runner sudo ./svc.sh install ubuntu && sudo ./svc.sh start
🔒
ERP HTTPS Setup (Original)
The original ERP cert erp-letsencrypt was stored in OCI Certificate Service and covered only erp.srigaurangasamaj.com. It is no longer active on the listener — superseded by the combined cert below.
🌐
Public Website HTTPS (Multi-Domain)
Live since 2026-08-01. One RSA-2048 cert covers all three domains — no SNI complexity.
OCI LB does not support ECC certs. Always use
--keylength 2048 (RSA). ECC causes ssl alert number 40.
OCI LB has two cert types — Certificate Service managed and Load Balancer managed. These cannot be mixed on one listener. Use one combined LB-managed cert for all domains.
Current Certificate
| Field | Value |
|---|---|
| Name | all-domains-rsa-2026 |
| Type | Load Balancer managed |
| Domains | srigaurangasamaj.com, www.srigaurangasamaj.com, erp.srigaurangasamaj.com |
| Algorithm | RSA-2048 · Let's Encrypt · acme.sh DNS-01 |
| Expires | 2026-10-30 — renew before 2026-10-16 |
DNS (Hostinger)
| Name | Type | Value |
|---|---|---|
@ | A | 140.245.231.240 |
www | A | 140.245.231.240 |
erp | A | 140.245.231.240 |
🔄
Certificate Renewal
Calendar reminder: 2026-10-16 (two weeks before expiry). Late renewal breaks HTTPS on all three domains.
- SSH to server via Bastion. Run:
~/.acme.sh/acme.sh --issue --dns \ --yes-I-know-dns-manual-mode-enough-go-ahead-please \ --server letsencrypt --keylength 2048 \ -d srigaurangasamaj.com \ -d www.srigaurangasamaj.com \ -d erp.srigaurangasamaj.com - Add the three
_acme-challengeTXT records to Hostinger DNS (values printed by acme.sh). Wait 5 min. - Run
--renew(same flags). Then extract files:CERT_DIR=~/.acme.sh/srigaurangasamaj.com_ecc cat $CERT_DIR/srigaurangasamaj.com.cer # leaf cert cat $CERT_DIR/fullchain.cer # chain (intermediates) cat $CERT_DIR/srigaurangasamaj.com.key # RSA private key - OCI Console → LB → Certificates → Add certificate → name
all-domains-rsa-YYYYMMDD→ type: Load balancer → paste leaf, chain, key. - OCI Console → LB → Listeners →
https_443→ Edit → select new cert → Save. - Delete the three
_acme-challengeTXT records from Hostinger.
🐳
Docker Compose Stack
Compose file: /opt/dharma-erp/dharma_erp/03_PLATFORM/infrastructure/config/docker-compose.yml
| Container | Role | Notes |
|---|---|---|
dharma-postgres | PostgreSQL database | Never rebuilt by auto-deploy |
dharma-fastapi | FastAPI backend | Rebuilt on every deploy |
dharma-nextjs | ERP frontend (Next.js) | Rebuilt on every deploy |
dharma-website | Public website (Next.js) | Rebuilt on every deploy |
dharma-nginx | Reverse proxy | TLS terminates at LB; nginx receives HTTP :80 |
cd /opt/dharma-erp/dharma_erp/03_PLATFORM/infrastructure/config
sudo docker compose ps # check all containers
sudo docker compose logs -f fastapi # tail backend logs
sudo docker compose exec nginx nginx -s reload # hot-reload nginx config
🗄
Database Migrations & Seeds
Auto-deploy handles code only — SQL migrations and seeds must be run manually via Bastion.
# Run all migrations:
sudo bash /opt/dharma-erp/dharma_erp/03_PLATFORM/infrastructure/scripts/run-migrations.sh
# Run a specific seed (all seeds are idempotent — safe to re-run):
sudo docker exec -i dharma-postgres psql -U postgres dharma_erp \
< /opt/dharma-erp/dharma_erp/03_PLATFORM/backend/seeds/013_trial_entity.sql
✅
Validation Checklist
| Check | How | Expected |
|---|---|---|
| ERP HTTPS | curl -I https://erp.srigaurangasamaj.com/health | 200 OK |
| ERP HTTP redirect | curl -I http://erp.srigaurangasamaj.com/ | 301 → https:// |
| Public website | curl -I https://srigaurangasamaj.com/ | 200 OK |
| www alias | curl -I https://www.srigaurangasamaj.com/ | 200 OK |
| TLS cert | Browser padlock on all 3 domains | Valid; expires 2026-10-30 |
| ERP login | https://erp.srigaurangasamaj.com/login | admin / vgsf2026 logs in |
| Staff Login link | Nav top-right on srigaurangasamaj.com | "Staff Login" → opens ERP |
| Containers | sudo docker compose ps | All 5 Up |
| Auto-deploy | Push a commit to main | GitHub Actions green in ~4 min |
🔑
Credentials & Reference
Store secrets in a password manager. Do not commit to the repository.
| Resource | Value |
|---|---|
| ERP domain | erp.srigaurangasamaj.com |
| Public website | srigaurangasamaj.com · www.srigaurangasamaj.com |
| LB Public IP | 140.245.231.240 |
| Server Private IP | 10.0.2.89 |
| OCI Region | ap-hyderabad-1 |
| SSH key | ~/.ssh/dharma-erp-prod |
| Bastion name | bastion108dharma108erp |
| Bastion host | host.bastion.ap-hyderabad-1.oci.oraclecloud.com |
| SSL cert (OCI) | all-domains-rsa-2026 · expires 2026-10-30 |
| DB name | dharma_erp |
| DB user | postgres |
| GitHub repo | srigaurangasamaj108-svg/VGSF-Systems |
| Runner location | /opt/actions-runner/ on OCI server |
⚠
Common Mistakes
| # | Mistake | Symptom | Fix |
|---|---|---|---|
| 1 | ECC cert on OCI LB | ssl alert number 40 / no peer certificate | Reissue with --keylength 2048 |
| 2 | Mixing cert types on listener | Second domain has no TLS | One combined LB-managed cert |
| 3 | Reusing expired Bastion session OCID | SSH connection refused | Create a new session in OCI Console |
| 4 | Wrong SSH key (id_ed25519 not dharma-erp-prod) | Permission denied (publickey) | Use -i ~/.ssh/dharma-erp-prod |
| 5 | Running seeds via auto-deploy | Seed runs on every deploy | Always run seeds manually via Bastion |
| 6 | useSearchParams() without Suspense (Next.js) | Build exit code 1 | Wrap component in <Suspense> |
🛡
Security Baseline
| Layer | Control |
|---|---|
| Network | OCI LB (public) → private VCN → server (no public IP on instance) |
| SSH access | OCI Managed Bastion only — no direct inbound SSH |
| TLS | Terminates at OCI LB · RSA-2048 · Let's Encrypt · expires 2026-10-30 |
| HTTP redirect | OCI LB rule set http_to_https_redirect (301) |
| API docs | /api/docs returns 403 FORBIDDEN in production |
| Secrets | OCI Vault → loaded by load-secrets.sh at startup |
| Backups | Daily pg_dump → OCI Object Storage dharma-erp-backups at 02:00 UTC |
🔁
Disaster Recovery
Rollback a Bad Deploy
cd /opt/dharma-erp
git log --oneline -10
git checkout <good-commit-hash>
cd dharma_erp/03_PLATFORM/infrastructure/config
sudo docker compose build fastapi nextjs website
sudo docker compose up -d --no-deps fastapi nextjs nginx website
Restore Database from Backup
oci os object list --bucket-name dharma-erp-backups --prefix backups/
oci os object get --bucket-name dharma-erp-backups \
--name backups/daily/dharma_erp_<DATE>.sql.gz --file /tmp/restore.sql.gz
gunzip /tmp/restore.sql.gz
sudo docker exec -i dharma-postgres psql -U postgres dharma_erp < /tmp/restore.sql
📋
Operational Change Log
| Date | Resource | Change |
|---|---|---|
| 2026-08-01 | Website Nav/Footer/Mobile | Added Staff Login link → erp.srigaurangasamaj.com |
| 2026-08-01 | GitHub Actions runner | Self-hosted runner installed as systemd service; deploy.yml created |
| 2026-08-01 | OCI LB Listener https_443 | Updated cert from erp-letsencrypt → all-domains-rsa-2026 |
| 2026-08-01 | OCI LB Certificates | Added all-domains-rsa-2026 (RSA-2048; 3 domains; expires 2026-10-30) |
| 2026-08-01 | Hostinger DNS | A records @ and www → 140.245.231.240; deleted AAAA and ftp records |
| 2026-07-30 | OCI LB Rule Set | Created http_to_https_redirect (301) |
| 2026-07-30 | OCI LB Listener | Created https_443 port 443 with erp-letsencrypt |
| 2026-07-30 | OCI Certificate Service | Imported erp-letsencrypt (expires 2026-10-28) |
| 2026-07-30 | OCI LB dharma-erp-lb | Created Load Balancer; backend 10.0.2.89:80 |