Files
verify/deploy/EC2_SETUP.md
Mohamed Mathar Irfan ed6610d5d8 Initial project upload
2026-07-28 17:57:02 +05:30

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`.