380 lines
6.8 KiB
Markdown
380 lines
6.8 KiB
Markdown
# Deployment Guide - LOAF Membership Platform
|
|
|
|
## Fresh Database Installation
|
|
|
|
Follow these steps in order for a **brand new deployment**:
|
|
|
|
### Step 1: Create PostgreSQL Database
|
|
|
|
```bash
|
|
# Connect to PostgreSQL
|
|
psql -U postgres
|
|
|
|
# Create database
|
|
CREATE DATABASE membership_db;
|
|
|
|
# Create user (if needed)
|
|
CREATE USER loaf_admin WITH PASSWORD 'your-secure-password';
|
|
GRANT ALL PRIVILEGES ON DATABASE membership_db TO loaf_admin;
|
|
|
|
# Exit PostgreSQL
|
|
\q
|
|
```
|
|
|
|
### Step 2: Run Initial Schema
|
|
|
|
```bash
|
|
cd backend
|
|
|
|
# Apply the complete schema (creates all 17 tables, 8 enums, indexes)
|
|
psql -U loaf_admin -d membership_db -f migrations/000_initial_schema.sql
|
|
```
|
|
|
|
**What this creates:**
|
|
- ✅ 17 tables: users, events, subscriptions, roles, permissions, etc.
|
|
- ✅ 8 custom enums: UserStatus, UserRole, RSVPStatus, etc.
|
|
- ✅ All indexes and foreign keys
|
|
- ✅ All constraints and defaults
|
|
|
|
### Step 3: Mark Database for Alembic Tracking
|
|
|
|
```bash
|
|
# Mark the database as being at the baseline
|
|
alembic stamp head
|
|
```
|
|
|
|
### Step 4: Verify Setup
|
|
|
|
```bash
|
|
# Check Alembic status
|
|
alembic current
|
|
# Expected output: 001_initial_baseline (head)
|
|
|
|
# Check database tables
|
|
psql -U loaf_admin -d membership_db -c "\dt"
|
|
# Should show 17 tables
|
|
```
|
|
|
|
### Step 5: Set Environment Variables
|
|
|
|
Create `backend/.env`:
|
|
|
|
```env
|
|
# Database
|
|
DATABASE_URL=postgresql://loaf_admin:your-password@localhost:5432/membership_db
|
|
|
|
# JWT
|
|
JWT_SECRET=your-secret-key-minimum-32-characters-long
|
|
JWT_ALGORITHM=HS256
|
|
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
|
|
|
# Email (SMTP)
|
|
SMTP_HOST=smtp.gmail.com
|
|
SMTP_PORT=587
|
|
SMTP_USERNAME=your-email@gmail.com
|
|
SMTP_PASSWORD=your-app-password
|
|
SMTP_FROM_EMAIL=noreply@loafmembers.org
|
|
SMTP_FROM_NAME=LOAF Membership
|
|
|
|
# Frontend URL
|
|
FRONTEND_URL=https://members.loafmembers.org
|
|
|
|
# Cloudflare R2
|
|
R2_ENDPOINT_URL=https://your-account-id.r2.cloudflarestorage.com
|
|
R2_ACCESS_KEY_ID=your-r2-access-key
|
|
R2_SECRET_ACCESS_KEY=your-r2-secret-key
|
|
R2_BUCKET_NAME=loaf-membership
|
|
R2_PUBLIC_URL=https://cdn.loafmembers.org
|
|
|
|
# Stripe
|
|
STRIPE_SECRET_KEY=sk_live_...
|
|
STRIPE_WEBHOOK_SECRET=whsec_...
|
|
STRIPE_PRICE_ID_ANNUAL=price_...
|
|
STRIPE_PRICE_ID_GROUP=price_...
|
|
```
|
|
|
|
### Step 6: Install Dependencies
|
|
|
|
```bash
|
|
# Backend
|
|
cd backend
|
|
pip install -r requirements.txt
|
|
|
|
# Frontend
|
|
cd ../frontend
|
|
yarn install
|
|
```
|
|
|
|
### Step 7: Start Services
|
|
|
|
```bash
|
|
# Backend (in backend/)
|
|
uvicorn server:app --host 0.0.0.0 --port 8000
|
|
|
|
# Frontend (in frontend/)
|
|
yarn start
|
|
```
|
|
|
|
### Step 8: Create First Superadmin User
|
|
|
|
```bash
|
|
# Connect to database
|
|
psql -U loaf_admin -d membership_db
|
|
|
|
# Create superadmin user
|
|
INSERT INTO users (
|
|
id, email, password_hash, first_name, last_name,
|
|
status, role, email_verified, created_at, updated_at
|
|
) VALUES (
|
|
gen_random_uuid(),
|
|
'admin@loafmembers.org',
|
|
'$2b$12$your-bcrypt-hashed-password-here', -- Use bcrypt to hash password
|
|
'Admin',
|
|
'User',
|
|
'active',
|
|
'superadmin',
|
|
true,
|
|
NOW(),
|
|
NOW()
|
|
);
|
|
```
|
|
|
|
**Generate password hash:**
|
|
```python
|
|
import bcrypt
|
|
password = b"your-secure-password"
|
|
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
|
|
print(hashed.decode())
|
|
```
|
|
|
|
---
|
|
|
|
## Existing Database Update
|
|
|
|
For **updating an existing deployment** with new code:
|
|
|
|
### Step 1: Backup Database
|
|
|
|
```bash
|
|
pg_dump -U loaf_admin membership_db > backup_$(date +%Y%m%d_%H%M%S).sql
|
|
```
|
|
|
|
### Step 2: Pull Latest Code
|
|
|
|
```bash
|
|
git pull origin main
|
|
```
|
|
|
|
### Step 3: Install New Dependencies
|
|
|
|
```bash
|
|
# Backend
|
|
cd backend
|
|
pip install -r requirements.txt
|
|
|
|
# Frontend
|
|
cd ../frontend
|
|
yarn install
|
|
```
|
|
|
|
### Step 4: Apply Database Migrations
|
|
|
|
```bash
|
|
cd backend
|
|
|
|
# Check current migration status
|
|
alembic current
|
|
|
|
# Apply pending migrations
|
|
alembic upgrade head
|
|
|
|
# Verify
|
|
alembic current
|
|
```
|
|
|
|
### Step 5: Restart Services
|
|
|
|
```bash
|
|
# Restart backend
|
|
systemctl restart membership-backend
|
|
|
|
# Rebuild and restart frontend
|
|
cd frontend
|
|
yarn build
|
|
systemctl restart membership-frontend
|
|
```
|
|
|
|
---
|
|
|
|
## First-Time Alembic Setup (Existing Database)
|
|
|
|
If you have an **existing database** that was created with `000_initial_schema.sql` but hasn't been marked for Alembic tracking:
|
|
|
|
```bash
|
|
cd backend
|
|
|
|
# Mark database as being at the baseline (one-time only)
|
|
alembic stamp head
|
|
|
|
# Verify
|
|
alembic current
|
|
# Expected output: 001_initial_baseline (head)
|
|
```
|
|
|
|
---
|
|
|
|
## Database Schema Verification
|
|
|
|
**Check all tables exist:**
|
|
```bash
|
|
psql -U loaf_admin -d membership_db -c "\dt"
|
|
```
|
|
|
|
**Expected tables (17 total):**
|
|
- users
|
|
- events
|
|
- event_rsvps
|
|
- subscriptions
|
|
- subscription_plans
|
|
- permissions
|
|
- roles
|
|
- role_permissions
|
|
- user_invitations
|
|
- import_jobs
|
|
- import_rollback_audit
|
|
- event_galleries
|
|
- newsletter_archives
|
|
- financial_reports
|
|
- bylaws_documents
|
|
- donations
|
|
- storage_usage
|
|
|
|
**Check enums:**
|
|
```bash
|
|
psql -U loaf_admin -d membership_db -c "\dT"
|
|
```
|
|
|
|
**Expected enums (8 total):**
|
|
- userstatus
|
|
- userrole
|
|
- rsvpstatus
|
|
- subscriptionstatus
|
|
- donationtype
|
|
- donationstatus
|
|
- invitationstatus
|
|
- importjobstatus
|
|
|
|
---
|
|
|
|
## Rollback Procedures
|
|
|
|
### Rollback Last Migration
|
|
|
|
```bash
|
|
cd backend
|
|
alembic downgrade -1
|
|
```
|
|
|
|
### Rollback to Specific Revision
|
|
|
|
```bash
|
|
alembic downgrade <revision_id>
|
|
```
|
|
|
|
### Complete Database Reset
|
|
|
|
```bash
|
|
# WARNING: This deletes ALL data!
|
|
|
|
# 1. Backup first
|
|
pg_dump -U loaf_admin membership_db > emergency_backup.sql
|
|
|
|
# 2. Drop database
|
|
dropdb membership_db
|
|
|
|
# 3. Recreate database
|
|
createdb membership_db
|
|
|
|
# 4. Run initial schema
|
|
psql -U loaf_admin -d membership_db -f backend/migrations/000_initial_schema.sql
|
|
|
|
# 5. Mark for Alembic
|
|
cd backend
|
|
alembic stamp head
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### "relation does not exist" error
|
|
|
|
The database wasn't initialized properly.
|
|
|
|
**Solution:**
|
|
```bash
|
|
psql -U loaf_admin -d membership_db -f backend/migrations/000_initial_schema.sql
|
|
alembic stamp head
|
|
```
|
|
|
|
### "Target database is not up to date"
|
|
|
|
Migrations haven't been applied.
|
|
|
|
**Solution:**
|
|
```bash
|
|
cd backend
|
|
alembic upgrade head
|
|
```
|
|
|
|
### "Can't locate revision"
|
|
|
|
Alembic tracking is out of sync.
|
|
|
|
**Solution:**
|
|
```bash
|
|
# Check what revision the database thinks it's at
|
|
alembic current
|
|
|
|
# If empty or wrong, manually set it
|
|
alembic stamp head
|
|
```
|
|
|
|
### Database connection errors
|
|
|
|
Check `.env` file has correct `DATABASE_URL`.
|
|
|
|
**Format:**
|
|
```
|
|
DATABASE_URL=postgresql://username:password@host:port/database
|
|
```
|
|
|
|
---
|
|
|
|
## Production Checklist
|
|
|
|
Before going live:
|
|
|
|
- [ ] Database created and schema applied
|
|
- [ ] Alembic marked as up-to-date (`alembic current` shows baseline)
|
|
- [ ] All environment variables set in `.env`
|
|
- [ ] Dependencies installed (Python + Node)
|
|
- [ ] Superadmin user created
|
|
- [ ] SSL certificates configured
|
|
- [ ] Backup system in place
|
|
- [ ] Monitoring configured
|
|
- [ ] Domain DNS pointing to server
|
|
- [ ] Email sending verified (SMTP working)
|
|
- [ ] Stripe webhook endpoint configured
|
|
- [ ] R2 bucket accessible and CORS configured
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
For issues:
|
|
1. Check logs: `tail -f backend/logs/app.log`
|
|
2. Check Alembic status: `alembic current`
|
|
3. Verify environment variables: `cat backend/.env`
|
|
4. Test database connection: `psql -U loaf_admin -d membership_db`
|