253 lines
6.4 KiB
Markdown
253 lines
6.4 KiB
Markdown
# VerifyPack — Single EC2 (Ubuntu) Deployment
|
|
|
|
Everything on **one Ubuntu EC2 instance**: MongoDB + FastAPI backend + Next.js frontend,
|
|
with Nginx as the public reverse proxy.
|
|
|
|
Because MongoDB runs on the same box, it binds to `127.0.0.1` and is **never exposed to
|
|
the internet** — no DB port in the security group.
|
|
|
|
```
|
|
Internet ──443──> Nginx ──┬── / → Next.js (localhost:3000)
|
|
└── /api/* , etc → FastAPI (localhost:8000)
|
|
FastAPI ──> MongoDB (localhost:27017)
|
|
```
|
|
|
|
---
|
|
|
|
## 0. Provision the instance
|
|
|
|
- **AMI:** Ubuntu Server 22.04 LTS
|
|
- **Type:** t3.small minimum (t3.medium recommended — Mongo + Node build need RAM)
|
|
- **Storage:** 30 GB gp3
|
|
- **Security Group inbound:**
|
|
- `22` (SSH) — your IP only
|
|
- `80` (HTTP) — anywhere
|
|
- `443` (HTTPS) — anywhere
|
|
- **Do NOT open 27017, 8000, or 3000.** They stay local.
|
|
- Allocate an **Elastic IP** and point your domain's A records at it:
|
|
- `app.yourdomain.com` → EIP
|
|
- `api.yourdomain.com` → EIP (or serve API under `app.../api` — see Nginx below)
|
|
|
|
SSH in:
|
|
```bash
|
|
ssh -i your-key.pem ubuntu@<elastic-ip>
|
|
```
|
|
|
|
---
|
|
|
|
## 1. Base packages
|
|
|
|
```bash
|
|
sudo apt update && sudo apt upgrade -y
|
|
sudo apt install -y git nginx python3-venv python3-pip build-essential curl ufw
|
|
```
|
|
|
|
### Firewall (defense in depth)
|
|
```bash
|
|
sudo ufw allow OpenSSH
|
|
sudo ufw allow 'Nginx Full'
|
|
sudo ufw enable
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Install MongoDB 7.0
|
|
|
|
```bash
|
|
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
|
|
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
|
|
|
|
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
|
|
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
|
|
|
|
sudo apt update
|
|
sudo apt install -y mongodb-org
|
|
sudo systemctl enable --now mongod
|
|
sudo systemctl status mongod # should be active (running)
|
|
```
|
|
|
|
Mongo listens on `127.0.0.1:27017` by default — leave it that way.
|
|
|
|
### (Recommended) enable auth on MongoDB
|
|
```bash
|
|
mongosh
|
|
```
|
|
```javascript
|
|
use admin
|
|
db.createUser({
|
|
user: "vpadmin",
|
|
pwd: "<STRONG_PASSWORD>",
|
|
roles: [ { role: "root", db: "admin" } ]
|
|
})
|
|
exit
|
|
```
|
|
Turn on auth:
|
|
```bash
|
|
sudo sed -i 's/#security:/security:\n authorization: enabled/' /etc/mongod.conf
|
|
sudo systemctl restart mongod
|
|
```
|
|
Your connection string becomes:
|
|
`mongodb://vpadmin:<STRONG_PASSWORD>@127.0.0.1:27017/?authSource=admin`
|
|
|
|
---
|
|
|
|
## 3. Install Node 20 (for the frontend)
|
|
|
|
```bash
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
sudo apt install -y nodejs
|
|
node --version # v20.x
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Get the code onto the box
|
|
|
|
```bash
|
|
sudo mkdir -p /opt/verifypack && sudo chown ubuntu:ubuntu /opt/verifypack
|
|
cd /opt/verifypack
|
|
# either git clone your repo, or scp the "verify pack" folder up:
|
|
# scp -i key.pem -r "verify pack" ubuntu@<eip>:/opt/verifypack/
|
|
```
|
|
Assume the result is `/opt/verifypack/backend` and `/opt/verifypack/frontend`.
|
|
|
|
---
|
|
|
|
## 5. Backend (FastAPI)
|
|
|
|
```bash
|
|
cd /opt/verifypack/backend
|
|
python3 -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -r requirements.txt gunicorn
|
|
cp .env.example .env
|
|
nano .env
|
|
```
|
|
|
|
Set in `backend/.env`:
|
|
```env
|
|
ENVIRONMENT=production
|
|
SECRET_KEY=<32+ random chars — run: openssl rand -hex 32>
|
|
FRONTEND_URL=https://app.yourdomain.com
|
|
|
|
MONGODB_URL=mongodb://vpadmin:<STRONG_PASSWORD>@127.0.0.1:27017/?authSource=admin
|
|
MONGODB_DB=verifypack
|
|
MOCK_DB=0
|
|
|
|
MOCK_EMAIL=0
|
|
MOCK_STORAGE=0
|
|
|
|
AWS_REGION=ap-south-1
|
|
AWS_ACCESS_KEY_ID=...
|
|
AWS_SECRET_ACCESS_KEY=...
|
|
SES_FROM_EMAIL=no-reply@yourdomain.com
|
|
S3_BUCKET=verifypack-uploads
|
|
|
|
GOOGLE_CLIENT_ID=...
|
|
GOOGLE_CLIENT_SECRET=...
|
|
GOOGLE_REDIRECT_URI=https://api.yourdomain.com/auth/google/callback
|
|
|
|
RAZORPAY_KEY_ID=...
|
|
RAZORPAY_KEY_SECRET=...
|
|
RAZORPAY_WEBHOOK_SECRET=...
|
|
GST_RATE=0.18
|
|
```
|
|
> To run fully offline first (DB only, no AWS/Razorpay), set `MOCK_EMAIL=1 MOCK_STORAGE=1`
|
|
> and leave the cloud keys blank — the app still boots.
|
|
|
|
Seed once:
|
|
```bash
|
|
python -m app.db.seed
|
|
```
|
|
|
|
Install the systemd service (file provided in `deploy/verifypack-backend.service`):
|
|
```bash
|
|
sudo cp /opt/verifypack/deploy/verifypack-backend.service /etc/systemd/system/
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now verifypack-backend
|
|
sudo systemctl status verifypack-backend
|
|
curl localhost:8000/health # {"status":"ok",...,"mock_db":false}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Frontend (Next.js)
|
|
|
|
```bash
|
|
cd /opt/verifypack/frontend
|
|
npm ci
|
|
cp .env.local.example .env.local
|
|
nano .env.local
|
|
```
|
|
Set:
|
|
```env
|
|
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
|
|
NEXT_PUBLIC_APP_URL=https://app.yourdomain.com
|
|
```
|
|
Build & install service:
|
|
```bash
|
|
npm run build
|
|
sudo cp /opt/verifypack/deploy/verifypack-frontend.service /etc/systemd/system/
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now verifypack-frontend
|
|
sudo systemctl status verifypack-frontend
|
|
curl localhost:3000 # HTML returned
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Nginx reverse proxy
|
|
|
|
```bash
|
|
sudo cp /opt/verifypack/deploy/nginx-verifypack.conf /etc/nginx/sites-available/verifypack
|
|
sudo ln -s /etc/nginx/sites-available/verifypack /etc/nginx/sites-enabled/
|
|
sudo rm -f /etc/nginx/sites-enabled/default
|
|
sudo nginx -t && sudo systemctl reload nginx
|
|
```
|
|
|
|
### HTTPS with Let's Encrypt
|
|
```bash
|
|
sudo apt install -y certbot python3-certbot-nginx
|
|
sudo certbot --nginx -d app.yourdomain.com -d api.yourdomain.com
|
|
# auto-renew is installed as a systemd timer
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Updating after a code change
|
|
|
|
```bash
|
|
cd /opt/verifypack && git pull # or re-scp
|
|
# backend
|
|
cd backend && source .venv/bin/activate && pip install -r requirements.txt
|
|
sudo systemctl restart verifypack-backend
|
|
# frontend
|
|
cd ../frontend && npm ci && npm run build
|
|
sudo systemctl restart verifypack-frontend
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Logs & ops
|
|
|
|
```bash
|
|
sudo journalctl -u verifypack-backend -f # backend logs
|
|
sudo journalctl -u verifypack-frontend -f # frontend logs
|
|
sudo systemctl status mongod
|
|
```
|
|
|
|
Mongo backup (cron nightly):
|
|
```bash
|
|
mongodump --uri="mongodb://vpadmin:<pwd>@127.0.0.1:27017/verifypack?authSource=admin" \
|
|
--out /opt/backups/$(date +\%F)
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Single-instance security recap
|
|
- 27017 / 8000 / 3000 are **localhost only** — never in the security group.
|
|
- MongoDB auth enabled; strong `SECRET_KEY`; seeded admin password changed.
|
|
- TLS via certbot; HTTP redirects to HTTPS.
|
|
- `ufw` allows only SSH + Nginx.
|
|
- Consider snapshots/EBS backups + the nightly `mongodump`.
|