Monorepo Setup Plan¶
Overview¶
This document outlines the setup and configuration of a monorepo structure for the content generation system using GitHub, with deployments to Vercel (Next.js frontend) and Railway (Python services). The monorepo approach enables shared configurations, easier collaboration, and streamlined CI/CD.
Repository Structure¶
content-gen-monorepo/
├── apps/ # Main applications
│ ├── frontend/ # Next.js app (Vercel)
│ │ ├── src/
│ │ │ ├── app/ # App Router pages
│ │ │ ├── components/ # React components
│ │ │ ├── lib/ # Utilities
│ │ │ └── hooks/ # Custom hooks
│ │ ├── public/ # Static assets
│ │ ├── package.json
│ │ ├── next.config.js
│ │ ├── tsconfig.json
│ │ └── .env.local # Local env vars
│ ├── cpm/ # Content Production Module (Railway)
│ │ ├── app.py
│ │ ├── llm_client.py
│ │ ├── requirements.txt
│ │ ├── railway.json
│ │ └── .env
│ └── im/ # Instructions Module (Railway)
│ ├── app.py
│ ├── requirements.txt
│ ├── railway.json
│ └── .env
├── packages/ # Shared packages (V2)
│ └── shared-types/ # TypeScript types
├── docs/ # Documentation
│ ├── architecture.md
│ └── deployment.md
├── .github/ # GitHub Actions
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── package.json # Root package.json
├── pnpm-workspace.yaml # pnpm workspace config
├── turbo.json # Turborepo config
└── README.md
Initial Setup Steps¶
1. Create GitHub Repository¶
# Create new directory
mkdir content-gen-monorepo
cd content-gen-monorepo
# Initialize git
git init
# Create initial structure
mkdir -p apps/{frontend,cpm,im} packages docs .github/workflows
# Initialize root package.json
npm init -y
2. Configure pnpm Workspaces¶
Create pnpm-workspace.yaml:
Update root package.json:
{
"name": "content-gen-monorepo",
"version": "1.0.0",
"private": true,
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"dev": "turbo run dev",
"build": "turbo run build",
"test": "turbo run test",
"lint": "turbo run lint"
},
"devDependencies": {
"turbo": "^1.13.0"
},
"engines": {
"node": ">=18.0.0",
"pnpm": ">=8.0.0"
}
}
3. Configure Turborepo¶
Create turbo.json:
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**", "tests/**"]
},
"lint": {
"outputs": []
}
}
}
4. Setup Frontend (Next.js)¶
cd apps/frontend
# Initialize Next.js app
pnpm create next-app@latest . --typescript --tailwind --app --src-dir --import-alias "@/*"
# Add dependencies
pnpm add @supabase/supabase-js axios swr
pnpm add -D @types/node
Create apps/frontend/next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
env: {
NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,
NEXT_PUBLIC_SUPABASE_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
CPM_SERVICE_URL: process.env.CPM_SERVICE_URL,
IM_SERVICE_URL: process.env.IM_SERVICE_URL,
}
}
module.exports = nextConfig
5. Setup Python Services¶
CPM Setup¶
cd apps/cpm
# Create Python virtual environment (local development)
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# Create requirements.txt (see CPM plan for full list)
cat > requirements.txt << EOF
fastapi==0.111.0
uvicorn==0.30.1
pydantic==2.7.1
supabase==2.5.0
openai==1.35.0
anthropic==0.30.0
google-generativeai==0.6.0
httpx==0.27.0
python-dotenv==1.0.1
EOF
# Install dependencies
pip install -r requirements.txt
# Create railway.json
cat > railway.json << 'EOF'
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "NIXPACKS"
},
"deploy": {
"startCommand": "uvicorn app:app --host 0.0.0.0 --port $PORT",
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 3
}
}
EOF
IM Setup (similar structure)¶
6. Configure Git and GitHub¶
Create .gitignore:
# Dependencies
node_modules/
.pnpm-store/
# Python
__pycache__/
*.py[cod]
*$py.class
.venv/
venv/
.env
# Next.js
.next/
out/
dist/
# Testing
coverage/
.nyc_output/
# Turborepo
.turbo/
# OS
.DS_Store
Thumbs.db
# IDEs
.vscode/
.idea/
*.swp
*.swo
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Environment variables
.env
.env.local
.env.*.local
GitHub Actions CI/CD¶
Create .github/workflows/ci.yml:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: pnpm install
- name: Run lints
run: pnpm lint
- name: Run tests
run: pnpm test
- name: Build
run: pnpm build
python-tests:
runs-on: ubuntu-latest
strategy:
matrix:
service: [cpm, im]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
working-directory: apps/${{ matrix.service }}
run: |
pip install -r requirements.txt
pip install pytest pytest-asyncio
- name: Run tests
working-directory: apps/${{ matrix.service }}
run: pytest
Vercel Configuration¶
1. Connect Repository¶
- Go to Vercel Dashboard
- Click "Add New Project"
- Import from GitHub repository
- Select the monorepo
2. Configure Project Settings¶
- Framework Preset: Next.js
- Root Directory:
apps/frontend - Build Command:
cd ../.. && pnpm build --filter=frontend - Output Directory:
apps/frontend/.next - Install Command:
pnpm install
3. Environment Variables¶
Add in Vercel dashboard:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
CPM_SERVICE_URL=https://cpm.railway.app
IM_SERVICE_URL=https://im.railway.app
4. Configure Deployment Hooks¶
Create apps/frontend/vercel.json:
{
"buildCommand": "cd ../.. && pnpm build --filter=frontend",
"installCommand": "pnpm install",
"framework": "nextjs",
"outputDirectory": ".next"
}
Railway Configuration¶
1. Create Railway Project¶
- Go to Railway Dashboard
- Create new project
- Add services from GitHub repo
2. Configure CPM Service¶
- Source: GitHub repo
- Root Directory:
/apps/cpm - Watch Paths:
/apps/cpm/** - Start Command: Auto-detected from railway.json
Environment variables:
SUPABASE_URL=your_supabase_url
SUPABASE_KEY=your_supabase_service_key
OPENAI_API_KEY=your_openai_key
ANTHROPIC_API_KEY=your_anthropic_key
GOOGLE_API_KEY=your_google_key
IM_SERVICE_URL=https://im.railway.app
3. Configure IM Service¶
- Source: GitHub repo
- Root Directory:
/apps/im - Watch Paths:
/apps/im/** - Similar environment variables
4. Configure Domains¶
Railway will provide URLs like: - CPM: cpm-production.up.railway.app - IM: im-production.up.railway.app
Local Development Workflow¶
1. Install Dependencies¶
2. Setup Environment Variables¶
Create .env.local files:
apps/frontend/.env.local:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
CPM_SERVICE_URL=http://localhost:8000
IM_SERVICE_URL=http://localhost:8001
apps/cpm/.env:
SUPABASE_URL=your_supabase_url
SUPABASE_KEY=your_supabase_service_key
OPENAI_API_KEY=your_openai_key
IM_SERVICE_URL=http://localhost:8001
PORT=8000
apps/im/.env:
SUPABASE_URL=your_supabase_url
SUPABASE_KEY=your_supabase_service_key
OPENAI_API_KEY=your_openai_key
PORT=8001
3. Run Services¶
# Terminal 1: Frontend
cd apps/frontend
pnpm dev
# Terminal 2: CPM
cd apps/cpm
source .venv/bin/activate
uvicorn app:app --reload --port 8000
# Terminal 3: IM
cd apps/im
source .venv/bin/activate
uvicorn app:app --reload --port 8001
Or use Turborepo (requires additional setup):
Deployment Process¶
Automatic Deployments¶
- Development: Push to feature branch → Preview deployments
- Production: Merge to main → Production deployments
Manual Deployments¶
# Deploy frontend to Vercel
cd apps/frontend
vercel --prod
# Deploy to Railway via CLI
railway link
railway up
Monitoring and Maintenance¶
1. Setup Monitoring¶
- Vercel: Built-in analytics and monitoring
- Railway: View logs and metrics in dashboard
- Sentry: Add error tracking (optional)
2. Regular Updates¶
# Update dependencies
pnpm update
# Check for vulnerabilities
pnpm audit
# Update Python dependencies
cd apps/cpm && pip-compile --upgrade
3. Backup Strategy¶
- GitHub: Automatic code backups
- Supabase: Configure database backups
- Environment variables: Store securely in password manager
Troubleshooting¶
Common Issues¶
- Vercel Build Failures
- Check Node version compatibility
- Verify environment variables
-
Review build logs
-
Railway Deployment Issues
- Check Python version in runtime.txt
- Verify requirements.txt syntax
-
Review deployment logs
-
Local Development
- Port conflicts: Change ports in .env files
- CORS issues: Configure Next.js API routes as proxy
Debug Commands¶
# Check workspace structure
pnpm ls --depth 0
# Verify turbo pipeline
turbo run build --dry-run
# Test individual services
cd apps/frontend && pnpm build
cd apps/cpm && python -m pytest
Security Best Practices¶
- Environment Variables
- Never commit .env files
- Use different keys for dev/prod
-
Rotate keys regularly
-
API Security
- Implement rate limiting
- Add authentication headers
-
Validate all inputs
-
Dependency Management
- Regular security updates
- Use lockfiles (pnpm-lock.yaml)
- Audit dependencies
V2 Enhancements¶
1. Shared Packages¶
2. Docker Support¶
Add docker-compose.yml for local development:
version: '3.8'
services:
frontend:
build: ./apps/frontend
ports:
- "3000:3000"
environment:
- CPM_SERVICE_URL=http://cpm:8000
- IM_SERVICE_URL=http://im:8001
cpm:
build: ./apps/cpm
ports:
- "8000:8000"
environment:
- IM_SERVICE_URL=http://im:8001
im:
build: ./apps/im
ports:
- "8001:8001"
3. Advanced CI/CD¶
- Add E2E tests with Playwright
- Implement preview deployments for PRs
- Add performance budgets
Cost Optimization¶
Estimated Costs (Monthly)¶
- GitHub: Free for private repos
- Vercel: Free tier (100GB bandwidth)
- Railway: ~$5-20 (usage-based)
- Total: ~$5-20/month for MVP
Cost Saving Tips¶
- Use Vercel's edge functions for light API calls
- Optimize Railway resource usage
- Implement caching strategies
- Monitor and optimize LLM API calls