ca-grow-ops-manager/DEPLOYMENT.md
fullsizemalt da7729d6e4
Some checks failed
Deploy to Production / deploy (push) Failing after 0s
Test / backend-test (push) Failing after 0s
Test / frontend-test (push) Failing after 0s
Initial commit: Spec Kit foundation complete
- Constitution and project spec (spec.yml)
- 7 comprehensive feature specs (tasks, batches, labor, compliance, inventory, integrations, comms)
- Phase 1 implementation plan (6-week roadmap)
- Week 1 task breakdown (15 concrete tasks)
- Architecture and compliance documentation
- Backend and frontend setup guides
- Deployment guide for nexus-vector
- CI/CD workflows (Forgejo Actions)
- Quick start guide for developers

Project is ready for implementation with:
- Automated testing on every push
- Automatic deployment to nexus-vector on push to main
- Database migrations handled automatically
- Health checks and monitoring

Stack: TypeScript, Fastify, React, Vite, PostgreSQL, Prisma, Docker
2025-12-08 23:54:12 -08:00

648 lines
12 KiB
Markdown

# Deployment Guide — nexus-vector
**Project**: CA Grow Ops Manager
**Target**: nexus-vector (100.95.3.92)
**Created**: 2025-12-08
**Job ID**: CAGROW-XXXXXX-GM (to be assigned)
---
## Overview
This guide explains how to deploy CA Grow Ops Manager to **nexus-vector** following the established infrastructure patterns.
---
## Prerequisites
### On Local Machine
- Git with SSH keys configured
- Access to nexus-vector via Tailscale or SSH
- Forgejo account with SSH key added
### On nexus-vector
- Docker and Docker Compose installed ✅
- PostgreSQL 15 available (via Docker)
- Redis available (via Docker)
- Port 8XXX available (to be assigned)
---
## Deployment Architecture
```
ca-grow-ops-manager/
├── backend/ # Fastify + Prisma API
├── frontend/ # Vite + React UI
└── docker-compose.yml # Service orchestration
Deployed to:
/srv/containers/ca-grow-ops-manager/
├── docker-compose.yml
├── docker-compose.env
├── backend/
│ ├── Dockerfile
│ ├── src/
│ └── prisma/
├── frontend/
│ ├── Dockerfile
│ └── src/
└── README.md
```
---
## Step 1: Create Forgejo Repository
### 1.1 Create Repository via API
```bash
# From nexus-vector or local machine with Tailscale
curl -X POST "https://git.runfoo.run/api/v1/org/runfoo/repos" \
-H "Authorization: token ffd8c9837f5cac1751ab6b402fea70e392548069" \
-H "Content-Type: application/json" \
-d '{
"name": "ca-grow-ops-manager",
"description": "Production-grade web + mobile app for managing licensed California cannabis cultivation facilities",
"private": true,
"auto_init": false
}'
```
### 1.2 Push Local Code to Forgejo
```bash
# From local machine (current directory: ca-grow-ops-manager)
cd /Users/ten/ANTIGRAVITY/777wolfpack/ca-grow-ops-manager
# Initialize Git if not already done
git init
git add .
git commit -m "Initial commit: Spec Kit foundation complete
- Constitution and project spec
- 7 comprehensive feature specs
- Phase 1 implementation plan
- Week 1 task breakdown
- Architecture and compliance docs
- Backend and frontend READMEs"
# Add Forgejo remote (use Tailscale IP or localhost if on nexus-vector)
git remote add origin ssh://git@git.runfoo.run:2222/runfoo/ca-grow-ops-manager.git
# Push to Forgejo
git push -u origin main
```
**Note**: If SSH to git.runfoo.run:2222 is blocked, use HTTPS:
```bash
git remote add origin https://git.runfoo.run/runfoo/ca-grow-ops-manager.git
git push -u origin main
```
---
## Step 2: Assign Port Number
### 2.1 Check Available Ports
```bash
# SSH to nexus-vector
ssh admin@nexus-vector
# Check currently used ports
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep "8[0-9][0-9][0-9]"
```
**Current Port Assignments**:
- 8000: Syncthing Exporter & Ingestion API
- 8001: Location Pipeline API
- 8003: Paperless-NGX
- 8005: Pinwheel
- 8020: Awesome MCP Servers
**Assign**: **8010** for CA Grow Ops Manager
---
## Step 3: Create Service Directory
### 3.1 Create Directory Structure
```bash
# On nexus-vector
ssh admin@nexus-vector
# Create service directory
sudo mkdir -p /srv/containers/ca-grow-ops-manager
sudo chown admin:admin /srv/containers/ca-grow-ops-manager
cd /srv/containers/ca-grow-ops-manager
```
### 3.2 Clone Repository
```bash
# Clone from Forgejo (use localhost on nexus-vector)
git clone ssh://git@localhost:2222/runfoo/ca-grow-ops-manager.git .
# Or via HTTPS
git clone https://git.runfoo.run/runfoo/ca-grow-ops-manager.git .
```
---
## Step 4: Create Docker Compose Configuration
### 4.1 Create docker-compose.yml
```bash
cd /srv/containers/ca-grow-ops-manager
```
Create `docker-compose.yml`:
```yaml
version: '3.8'
services:
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: ca_grow_ops
POSTGRES_USER: ca_grow_ops
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ca_grow_ops"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
backend:
build:
context: ./backend
dockerfile: Dockerfile
environment:
DATABASE_URL: postgresql://ca_grow_ops:${DB_PASSWORD}@db:5432/ca_grow_ops
REDIS_URL: redis://redis:6379
JWT_SECRET: ${JWT_SECRET}
JWT_ACCESS_EXPIRY: 15m
JWT_REFRESH_EXPIRY: 7d
NODE_ENV: production
PORT: 3000
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
environment:
VITE_API_URL: /api
ports:
- "8010:80"
depends_on:
- backend
restart: unless-stopped
volumes:
db_data:
```
### 4.2 Create Environment File
Create `docker-compose.env`:
```bash
# Database
DB_PASSWORD=CHANGE_THIS_SECURE_PASSWORD
# JWT
JWT_SECRET=CHANGE_THIS_SECURE_SECRET_KEY
# Email (optional for v1)
EMAIL_SERVICE=sendgrid
EMAIL_API_KEY=your_api_key_here
EMAIL_FROM=noreply@example.com
```
**Security**: Generate secure passwords:
```bash
# Generate DB password
openssl rand -base64 32
# Generate JWT secret
openssl rand -base64 64
```
---
## Step 5: Create Dockerfiles
### 5.1 Backend Dockerfile
Create `backend/Dockerfile`:
```dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
COPY prisma ./prisma/
# Install dependencies
RUN npm ci --only=production
# Copy source
COPY . .
# Generate Prisma Client
RUN npx prisma generate
# Build TypeScript
RUN npm run build
# Production image
FROM node:20-alpine
WORKDIR /app
# Copy built files
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/package*.json ./
# Run as non-root
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
```
### 5.2 Frontend Dockerfile
Create `frontend/Dockerfile`:
```dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci
# Copy source
COPY . .
# Build for production
RUN npm run build
# Production image with Nginx
FROM nginx:alpine
# Copy built files
COPY --from=builder /app/dist /usr/share/nginx/html
# Copy Nginx config
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
### 5.3 Frontend Nginx Config
Create `frontend/nginx.conf`:
```nginx
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# API proxy
location /api {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Frontend SPA routing
location / {
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}
```
---
## Step 6: Deploy Service
### 6.1 Build and Start
```bash
cd /srv/containers/ca-grow-ops-manager
# Load environment variables
set -a
source docker-compose.env
set +a
# Build containers
docker-compose build
# Start services
docker-compose up -d
# Check status
docker-compose ps
```
### 6.2 Run Database Migrations
```bash
# Run Prisma migrations
docker-compose exec backend npx prisma migrate deploy
# Seed initial data (if seed script exists)
docker-compose exec backend npx prisma db seed
```
### 6.3 Verify Deployment
```bash
# Check all containers are running
docker-compose ps
# Check backend health
curl http://localhost:8010/api/healthz
# Check frontend
curl -I http://localhost:8010/
# View logs
docker-compose logs -f --tail=100
```
---
## Step 7: Configure Domain (Optional)
### 7.1 DNS Configuration
Point domain to nexus-vector:
```
ca-grow-ops.runfoo.run → 216.158.230.94:8010
```
### 7.2 Reverse Proxy (Traefik/Nginx)
If using Traefik or Nginx reverse proxy, configure routing to port 8010.
---
## Step 8: Create Service Documentation
### 8.1 Create README
Create `/srv/containers/ca-grow-ops-manager/DEPLOYMENT.md`:
```markdown
# CA Grow Ops Manager — Deployment
**Job ID**: CAGROW-XXXXXX-GM
**Port**: 8010
**Purpose**: Cannabis cultivation facility management platform
## Quick Start
\`\`\`bash
cd /srv/containers/ca-grow-ops-manager
docker-compose up -d
curl http://localhost:8010/api/healthz
\`\`\`
## Configuration
Environment variables in `docker-compose.env`:
- `DB_PASSWORD`: PostgreSQL password
- `JWT_SECRET`: JWT signing secret
- `EMAIL_API_KEY`: SendGrid API key (optional)
## API Endpoints
- `GET /api/healthz` - Health check
- `POST /api/auth/login` - User login
- `GET /api/batches` - List batches
- `GET /api/tasks` - List tasks
## Health Monitoring
\`\`\`bash
# Check service health
curl http://localhost:8010/api/healthz
# Check container status
docker-compose ps
# View logs
docker-compose logs -f
\`\`\`
## Database Migrations
\`\`\`bash
# Apply migrations
docker-compose exec backend npx prisma migrate deploy
# View migration status
docker-compose exec backend npx prisma migrate status
\`\`\`
## Troubleshooting
### Backend won't start
- Check database connection: `docker-compose logs db`
- Verify environment variables: `docker-compose config`
### Frontend 404 errors
- Check Nginx config: `docker-compose exec frontend cat /etc/nginx/conf.d/default.conf`
- Verify build: `docker-compose exec frontend ls /usr/share/nginx/html`
\`\`\`
---
## Monitoring and Maintenance
### Daily Checks
```bash
# Check service health
curl http://localhost:8010/api/healthz
# Check container status
docker-compose ps
# Check disk usage
docker system df
```
### Log Monitoring
```bash
# View all logs
docker-compose logs -f
# View specific service
docker-compose logs -f backend
docker-compose logs -f frontend
docker-compose logs -f db
```
### Backup Database
```bash
# Backup PostgreSQL
docker-compose exec db pg_dump -U ca_grow_ops ca_grow_ops > backup_$(date +%Y%m%d).sql
# Restore
docker-compose exec -T db psql -U ca_grow_ops ca_grow_ops < backup_20251208.sql
```
---
## Updating the Service
### Pull Latest Code
```bash
cd /srv/containers/ca-grow-ops-manager
# Pull from Forgejo
git pull origin main
# Rebuild and restart
docker-compose down
docker-compose build
docker-compose up -d
# Run migrations
docker-compose exec backend npx prisma migrate deploy
```
---
## Troubleshooting
### Port Already in Use
```bash
# Check what's using port 8010
sudo netstat -tlnp | grep 8010
# Or use lsof
sudo lsof -i :8010
```
### Database Connection Issues
```bash
# Check database is running
docker-compose ps db
# Check database logs
docker-compose logs db
# Test connection
docker-compose exec backend npx prisma db pull
```
### Container Won't Start
```bash
# Check logs
docker-compose logs backend
# Check resource usage
docker stats
# Rebuild from scratch
docker-compose down -v
docker-compose build --no-cache
docker-compose up -d
```
---
## Security Checklist
- [ ] Changed default DB_PASSWORD
- [ ] Changed default JWT_SECRET
- [ ] Configured firewall rules (UFW)
- [ ] Set up HTTPS/SSL (if public-facing)
- [ ] Configured backup schedule
- [ ] Set up monitoring alerts
- [ ] Reviewed container security (non-root user)
---
## Next Steps
1. **Complete Week 1 tasks** (infrastructure setup)
2. **Implement authentication** (Week 2)
3. **Build core features** (Week 3-5)
4. **Test and polish** (Week 6)
5. **Deploy to production**
---
**Created**: 2025-12-08
**Last Updated**: 2025-12-08
**Maintained By**: Development team