Member Hub
Deployment

Member Hub Deployment Guide

This guide covers deployment procedures for the MyNATCA Member Hub, including local development, staging, and production environments.

Environment Configuration

Port Configuration

Important: The Hub development and preview server runs on port 1302 (changed from 1301 to avoid conflicts with other MyNATCA ecosystem services).

// package.json
{
  "scripts": {
    "dev": "vite --port 1302",
    "build": "vite build",
    "preview": "vite preview --port 1302"
  }
}
// vite.config.ts
export default defineConfig({
  server: {
    port: 1302, // Changed from 1301
    proxy: {
      '/api': {
        target: 'http://localhost:1300', // Platform API
        changeOrigin: true,
        secure: false,
        credentials: 'include'
      }
    }
  }
});

Environment Variables

Development (.env.local)

# Auth0 Configuration
VITE_AUTH0_DOMAIN=natca-dev.us.auth0.com
VITE_AUTH0_CLIENT_ID=your_dev_client_id
VITE_AUTH0_AUDIENCE=https://platform.natca.org
VITE_AUTH0_REDIRECT_URI=http://localhost:1302/callback
 
# Supabase Configuration
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your_dev_anon_key
 
# API Configuration
VITE_API_URL=http://localhost:1300
 
# Feature Flags
VITE_ENABLE_RACKSPACE_EMAIL=true

Staging (.env.staging)

# Auth0 Configuration
VITE_AUTH0_DOMAIN=natca-staging.us.auth0.com
VITE_AUTH0_CLIENT_ID=your_staging_client_id
VITE_AUTH0_AUDIENCE=https://platform-staging.natca.org
VITE_AUTH0_REDIRECT_URI=https://hub-staging.natca.org/callback
 
# Supabase Configuration
VITE_SUPABASE_URL=https://your-staging.supabase.co
VITE_SUPABASE_ANON_KEY=your_staging_anon_key
 
# API Configuration
VITE_API_URL=https://platform-staging.natca.org
 
# Feature Flags
VITE_ENABLE_RACKSPACE_EMAIL=true

Production (.env.production)

# Auth0 Configuration
VITE_AUTH0_DOMAIN=natca-prod.us.auth0.com
VITE_AUTH0_CLIENT_ID=your_prod_client_id
VITE_AUTH0_AUDIENCE=https://platform.natca.org
VITE_AUTH0_REDIRECT_URI=https://hub.natca.org/callback
 
# Supabase Configuration
VITE_SUPABASE_URL=https://your-prod.supabase.co
VITE_SUPABASE_ANON_KEY=your_prod_anon_key
 
# API Configuration
VITE_API_URL=https://platform.natca.org
 
# Feature Flags
VITE_ENABLE_RACKSPACE_EMAIL=true

Development Deployment

Prerequisites

  • Node.js 18+ installed
  • Platform API running on localhost:1300
  • Auth0 application configured
  • Supabase project created

Setup Steps

  1. Clone and Install
cd /Users/jason/dev/mynatca/hub
npm install
  1. Configure Environment
# Copy environment template
cp .env.example .env.local
 
# Edit with your credentials
nano .env.local
  1. Start Development Server
npm run dev
# Hub runs on http://localhost:1302
# Platform API must be running on http://localhost:1300
  1. Verify Integration
  • Navigate to http://localhost:1302 (opens in a new tab)
  • Test authentication flow
  • Verify Rackspace email card displays for eligible members
  • Test email availability checking
  • Test email creation and password reset

Development Workflow

# Start Platform API (Terminal 1)
cd /Users/jason/dev/mynatca/platform
npm run dev
 
# Start Member Hub (Terminal 2)
cd /Users/jason/dev/mynatca/hub
npm run dev
 
# Platform: http://localhost:1300
# Hub: http://localhost:1302

Production Build

Build Process

# Install dependencies
npm ci
 
# Build for production
npm run build
 
# Output directory: dist/
# - Optimized and minified JavaScript
# - CSS extracted and optimized
# - Assets fingerprinted and cached

Build Verification

# Preview production build locally
npm run preview
# Runs on http://localhost:1302
 
# Test production build
- Verify all routes work
- Check authentication flow
- Test Rackspace email functionality
- Verify API proxy configuration

Build Output

dist/
├── index.html                 # Main HTML entry
├── assets/
│   ├── index-[hash].js       # Main application bundle
│   ├── vendor-[hash].js      # Third-party dependencies
│   ├── index-[hash].css      # Extracted CSS
│   └── ...                   # Additional chunks and assets
└── favicon.ico               # App favicon

Docker Deployment

Dockerfile

# /Users/jason/dev/mynatca/hub/Dockerfile
FROM node:18-alpine as build
 
WORKDIR /app
 
# Copy package files
COPY package*.json ./
 
# Install dependencies
RUN npm ci
 
# Copy source code
COPY . .
 
# Build application
RUN npm run build
 
# Production stage
FROM nginx:alpine
 
# Copy custom nginx config
COPY nginx.conf /etc/nginx/conf.d/default.conf
 
# Copy built application
COPY --from=build /app/dist /usr/share/nginx/html
 
# Expose port 80
EXPOSE 80
 
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --quiet --tries=1 --spider http://localhost/health || exit 1
 
CMD ["nginx", "-g", "daemon off;"]

Nginx Configuration

# /Users/jason/dev/mynatca/hub/nginx.conf
server {
    listen 80;
    server_name hub.natca.org;
 
    root /usr/share/nginx/html;
    index index.html;
 
    # Enable gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
 
    # 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;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
 
    # Serve Vue SPA
    location / {
        try_files $uri $uri/ /index.html;
    }
 
    # Proxy API requests to Platform
    location /api/ {
        proxy_pass http://platform.natca.org:1300;
        proxy_http_version 1.1;
 
        # Headers
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        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;
 
        # Cookie handling
        proxy_pass_header Set-Cookie;
        proxy_cookie_domain platform.natca.org hub.natca.org;
 
        # Buffering
        proxy_buffering off;
        proxy_cache_bypass $http_upgrade;
    }
 
    # Cache static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
 
    # Health check endpoint
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

Docker Compose

# /Users/jason/dev/mynatca/hub/docker-compose.yml
version: '3.8'
 
services:
  hub:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "80:80"
    environment:
      - NODE_ENV=production
    networks:
      - mynatca_network
    depends_on:
      - platform
    restart: unless-stopped
 
  platform:
    image: mynatca/platform:latest
    ports:
      - "1300:1300"
    environment:
      - NODE_ENV=production
      - TRUST_PROXY=1
    networks:
      - mynatca_network
    restart: unless-stopped
 
networks:
  mynatca_network:
    driver: bridge

Build and Run

# Build Docker image
docker build -t mynatca/hub:latest .
 
# Run container
docker run -d \
  -p 80:80 \
  --name hub \
  --network mynatca_network \
  mynatca/hub:latest
 
# Or use Docker Compose
docker-compose up -d
 
# View logs
docker logs -f hub
 
# Stop container
docker-compose down

Digital Ocean App Platform

App Specification

# /Users/jason/dev/mynatca/hub/.do/app.yaml
name: mynatca-hub
region: nyc
 
services:
  - name: hub
    github:
      repo: mynatca/hub
      branch: main
      deploy_on_push: true
 
    build_command: npm run build
 
    run_command: |
      npm install -g serve
      serve -s dist -l 8080
 
    http_port: 8080
    instance_count: 2
    instance_size_slug: basic-xs
 
    routes:
      - path: /
 
    envs:
      - key: NODE_ENV
        value: production
 
      - key: VITE_AUTH0_DOMAIN
        value: natca-prod.us.auth0.com
 
      - key: VITE_AUTH0_CLIENT_ID
        value: ${AUTH0_CLIENT_ID}
        type: SECRET
 
      - key: VITE_AUTH0_AUDIENCE
        value: https://platform.natca.org
 
      - key: VITE_AUTH0_REDIRECT_URI
        value: https://hub.natca.org/callback
 
      - key: VITE_SUPABASE_URL
        value: ${SUPABASE_URL}
        type: SECRET
 
      - key: VITE_SUPABASE_ANON_KEY
        value: ${SUPABASE_ANON_KEY}
        type: SECRET
 
      - key: VITE_API_URL
        value: https://platform.natca.org
 
      - key: VITE_ENABLE_RACKSPACE_EMAIL
        value: "true"
 
    health_check:
      http_path: /health
      initial_delay_seconds: 30
      period_seconds: 10
      timeout_seconds: 5
      success_threshold: 1
      failure_threshold: 3
 
static_sites:
  - name: hub-static
    github:
      repo: mynatca/hub
      branch: main
 
    build_command: npm run build
    output_dir: dist
 
    routes:
      - path: /
 
    catchall_document: index.html
 
    envs:
      - key: VITE_AUTH0_DOMAIN
        value: natca-prod.us.auth0.com
 
      - key: VITE_AUTH0_CLIENT_ID
        value: ${AUTH0_CLIENT_ID}
        type: SECRET

Deploy to Digital Ocean

# Install doctl CLI
brew install doctl
 
# Authenticate
doctl auth init
 
# Create app
doctl apps create --spec .do/app.yaml
 
# Update app
doctl apps update <app-id> --spec .do/app.yaml
 
# View logs
doctl apps logs <app-id> --type=run
 
# List deployments
doctl apps list-deployments <app-id>

Vercel Deployment

Vercel Configuration

// /Users/jason/dev/mynatca/hub/vercel.json
{
  "version": 2,
  "builds": [
    {
      "src": "package.json",
      "use": "@vercel/static-build",
      "config": {
        "distDir": "dist"
      }
    }
  ],
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "https://platform.natca.org/api/$1"
    },
    {
      "src": "/(.*)",
      "dest": "/index.html"
    }
  ],
  "env": {
    "VITE_AUTH0_DOMAIN": "natca-prod.us.auth0.com",
    "VITE_AUTH0_AUDIENCE": "https://platform.natca.org",
    "VITE_AUTH0_REDIRECT_URI": "https://hub.natca.org/callback"
  }
}

Deploy to Vercel

# Install Vercel CLI
npm i -g vercel
 
# Login
vercel login
 
# Deploy to preview
vercel
 
# Deploy to production
vercel --prod
 
# Set environment variables
vercel env add VITE_AUTH0_CLIENT_ID
vercel env add VITE_SUPABASE_ANON_KEY

Deployment Checklist

Pre-Deployment

  • Update environment variables for target environment
  • Run npm run build and verify no errors
  • Test production build locally with npm run preview
  • Verify Platform API is accessible at configured URL
  • Ensure Auth0 application has correct callback URLs
  • Verify Supabase RLS policies are configured
  • Test Rackspace email functionality in staging
  • Review and update CORS configuration on Platform

Deployment

  • Deploy Platform API first (if updated)
  • Wait for Platform health check to pass
  • Deploy Hub application
  • Verify Hub health check passes
  • Test authentication flow end-to-end
  • Verify API proxy is working correctly
  • Test Rackspace email card functionality
  • Check browser console for errors
  • Verify session persistence across page refreshes

Post-Deployment

  • Monitor application logs for errors
  • Check Platform API logs for proxy errors
  • Test with real user accounts
  • Verify Rackspace email creation works
  • Test password reset functionality
  • Monitor error rates in OpenSearch
  • Update deployment documentation if needed
  • Notify team of successful deployment

Port Configuration Summary

EnvironmentHub PortPlatform PortNotes
Development13021300Changed from 1301 to avoid conflicts
Preview13021300Local production preview
Production80/4431300Nginx/Load balancer handles SSL

Important: The Hub port was changed from 1301 to 1302 in both vite.config.ts and the package.json preview script to avoid conflicts with other MyNATCA ecosystem services.

Files Updated for Port Change

// vite.config.ts
export default defineConfig({
  server: {
    port: 1302, // Changed from 1301
    // ...
  }
});
// package.json
{
  "scripts": {
    "preview": "vite preview --port 1302" // Changed from 1301
  }
}

Rollback Procedure

Docker Rollback

# Tag previous working version
docker tag mynatca/hub:latest mynatca/hub:rollback
 
# Deploy previous version
docker pull mynatca/hub:v1.2.3
docker tag mynatca/hub:v1.2.3 mynatca/hub:latest
docker-compose up -d
 
# Verify rollback
curl https://hub.natca.org/health

Digital Ocean Rollback

# List deployments
doctl apps list-deployments <app-id>
 
# Rollback to specific deployment
doctl apps rollback <app-id> <deployment-id>
 
# Monitor rollback
doctl apps logs <app-id> --type=run --follow

Vercel Rollback

# List deployments
vercel ls
 
# Rollback to previous deployment
vercel rollback <deployment-url>
 
# Or use Vercel dashboard
# Navigate to Deployments → Select working deployment → Promote to Production

Troubleshooting Deployment Issues

Port Conflicts

Problem: Development server fails to start on port 1302

Solution:

# Check if port is in use
lsof -i :1302
 
# Kill process using port
kill -9 <PID>
 
# Or use alternative port
npm run dev -- --port 1303

API Proxy Errors

Problem: API requests fail with 502 Bad Gateway

Solution:

  1. Verify Platform API is running: curl http://localhost:1300/api/health
  2. Check Vite proxy configuration in vite.config.ts
  3. Ensure credentials: 'include' is set in all fetch requests
  4. Verify CORS configuration on Platform allows Hub origin

Authentication Issues

Problem: Users redirected to login after authentication

Solution:

  1. Verify Auth0 callback URL matches deployed URL
  2. Check Auth0 application settings for allowed origins
  3. Verify session cookies are being set (check browser DevTools)
  4. Ensure Platform has trust proxy enabled in production
  5. Check cookie domain configuration in nginx

Build Failures

Problem: npm run build fails with TypeScript errors

Solution:

# Clear cache and reinstall
rm -rf node_modules package-lock.json
npm install
 
# Check TypeScript configuration
npx tsc --noEmit
 
# Verify all environment variables are set

Related Documentation


Ensure Platform API is deployed and healthy before deploying the Member Hub. The Hub depends on Platform for authentication, session management, and API proxying.