Fix Railway deployment: Add Node version config and remove npm engine requirement
This commit is contained in:
parent
7d4259ede8
commit
87c53e4f7c
18 changed files with 1589 additions and 5 deletions
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
24
|
||||||
162
DEPLOYMENT_CHECKLIST.md
Normal file
162
DEPLOYMENT_CHECKLIST.md
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
# 🚀 Deployment Checklist for aethex.live
|
||||||
|
|
||||||
|
Use this checklist to launch your live streaming platform to production.
|
||||||
|
|
||||||
|
## Pre-Launch
|
||||||
|
|
||||||
|
### Streaming Infrastructure
|
||||||
|
- [ ] Streaming provider account created (Cloudflare/Mux/AWS)
|
||||||
|
- [ ] RTMP ingest URL obtained
|
||||||
|
- [ ] HLS playback URL obtained
|
||||||
|
- [ ] OBS Studio installed and configured
|
||||||
|
- [ ] Test stream successfully running
|
||||||
|
- [ ] Stream quality settings optimized (1080p/720p)
|
||||||
|
- [ ] Backup streaming key secured
|
||||||
|
|
||||||
|
### Frontend Configuration
|
||||||
|
- [ ] `.env.local` created with all variables
|
||||||
|
- [ ] `NEXT_PUBLIC_STREAM_URL` set correctly
|
||||||
|
- [ ] Brand name updated in `app/page.tsx`
|
||||||
|
- [ ] Favicon replaced in `app/`
|
||||||
|
- [ ] Social links updated in config
|
||||||
|
- [ ] Color scheme customized (if desired)
|
||||||
|
- [ ] All tests passing locally
|
||||||
|
- [ ] Mobile responsiveness verified
|
||||||
|
|
||||||
|
### Backend Setup (Optional but Recommended)
|
||||||
|
- [ ] Database chosen and provisioned
|
||||||
|
- [ ] Authentication provider selected
|
||||||
|
- [ ] Chat backend implemented
|
||||||
|
- [ ] Firebase / WebSocket / Pusher configured
|
||||||
|
- [ ] Rate limiting enabled
|
||||||
|
- [ ] Moderation tools ready
|
||||||
|
- [ ] API routes tested
|
||||||
|
- [ ] CORS configured properly
|
||||||
|
- [ ] Error logging set up
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Vercel Deployment
|
||||||
|
- [ ] GitHub repository created and pushed
|
||||||
|
- [ ] Vercel account connected to GitHub
|
||||||
|
- [ ] Project imported to Vercel
|
||||||
|
- [ ] Environment variables added to Vercel:
|
||||||
|
- [ ] `NEXT_PUBLIC_STREAM_URL`
|
||||||
|
- [ ] Any API keys
|
||||||
|
- [ ] Database URLs
|
||||||
|
- [ ] Authentication secrets
|
||||||
|
- [ ] Production build successful
|
||||||
|
- [ ] Preview deployment tested
|
||||||
|
|
||||||
|
### Domain Configuration
|
||||||
|
- [ ] Custom domain purchased (aethex.live)
|
||||||
|
- [ ] Domain added in Vercel dashboard
|
||||||
|
- [ ] DNS records updated:
|
||||||
|
- [ ] A record or CNAME pointing to Vercel
|
||||||
|
- [ ] SSL certificate issued (auto by Vercel)
|
||||||
|
- [ ] HTTPS working correctly
|
||||||
|
- [ ] Redirects configured (www → non-www)
|
||||||
|
|
||||||
|
### Performance & Monitoring
|
||||||
|
- [ ] Analytics integrated (Vercel/Google/Plausible)
|
||||||
|
- [ ] Error tracking set up (Sentry/LogRocket)
|
||||||
|
- [ ] Performance monitoring enabled
|
||||||
|
- [ ] Uptime monitoring configured
|
||||||
|
- [ ] CDN caching verified
|
||||||
|
- [ ] Image optimization enabled
|
||||||
|
|
||||||
|
## Post-Launch
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- [ ] Stream loads on desktop browsers
|
||||||
|
- [ ] Stream loads on mobile devices
|
||||||
|
- [ ] Chat functionality working
|
||||||
|
- [ ] Viewer count updating
|
||||||
|
- [ ] All links working
|
||||||
|
- [ ] Social sharing working
|
||||||
|
- [ ] SEO metadata correct
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- [ ] Environment variables secured (not in git)
|
||||||
|
- [ ] API routes protected
|
||||||
|
- [ ] Rate limiting active
|
||||||
|
- [ ] CORS properly configured
|
||||||
|
- [ ] Authentication working (if implemented)
|
||||||
|
- [ ] Admin access secured
|
||||||
|
|
||||||
|
### Content & Community
|
||||||
|
- [ ] Stream schedule created
|
||||||
|
- [ ] Social media accounts set up
|
||||||
|
- [ ] Community guidelines posted
|
||||||
|
- [ ] Announcement made
|
||||||
|
- [ ] Discord/Chat community ready
|
||||||
|
|
||||||
|
### Optimization
|
||||||
|
- [ ] lighthouse score > 90
|
||||||
|
- [ ] Page load time < 3s
|
||||||
|
- [ ] Stream latency optimized
|
||||||
|
- [ ] Mobile experience smooth
|
||||||
|
- [ ] Caching strategy implemented
|
||||||
|
|
||||||
|
## Backup & Recovery
|
||||||
|
- [ ] Database backups automated
|
||||||
|
- [ ] Stream recording enabled (if needed)
|
||||||
|
- [ ] Disaster recovery plan documented
|
||||||
|
- [ ] Alternative streaming setup ready
|
||||||
|
- [ ] Contact info for critical services saved
|
||||||
|
|
||||||
|
## Growth Features (Future)
|
||||||
|
|
||||||
|
### Phase 2
|
||||||
|
- [ ] VOD (Video on Demand) archives
|
||||||
|
- [ ] User registration and profiles
|
||||||
|
- [ ] Multi-channel support
|
||||||
|
- [ ] Enhanced chat (emotes, badges)
|
||||||
|
- [ ] Mobile app (PWA or native)
|
||||||
|
|
||||||
|
### Phase 3
|
||||||
|
- [ ] Subscriptions & memberships
|
||||||
|
- [ ] Donations/tips integration
|
||||||
|
- [ ] Private/premium streams
|
||||||
|
- [ ] Advanced analytics dashboard
|
||||||
|
- [ ] Stream clips & highlights
|
||||||
|
|
||||||
|
### Phase 4
|
||||||
|
- [ ] Multi-streaming (simulcast)
|
||||||
|
- [ ] Co-streaming features
|
||||||
|
- [ ] Stream overlays & widgets
|
||||||
|
- [ ] API for third-party integrations
|
||||||
|
- [ ] White-label options
|
||||||
|
|
||||||
|
## 📊 Success Metrics
|
||||||
|
|
||||||
|
Track these KPIs:
|
||||||
|
- [ ] Concurrent viewers
|
||||||
|
- [ ] Average watch time
|
||||||
|
- [ ] Chat messages per minute
|
||||||
|
- [ ] New vs returning visitors
|
||||||
|
- [ ] Stream uptime percentage
|
||||||
|
- [ ] Mobile vs desktop split
|
||||||
|
|
||||||
|
## 🛟 Emergency Contacts
|
||||||
|
|
||||||
|
Document these for quick access:
|
||||||
|
- Streaming provider support: ________________
|
||||||
|
- Hosting provider support: ________________
|
||||||
|
- DNS provider support: ________________
|
||||||
|
- Database provider support: ________________
|
||||||
|
- Your team contacts: ________________
|
||||||
|
|
||||||
|
## 🎉 Launch!
|
||||||
|
|
||||||
|
When all critical items are checked:
|
||||||
|
|
||||||
|
1. Do a final test stream
|
||||||
|
2. Announce the launch
|
||||||
|
3. Monitor the first stream closely
|
||||||
|
4. Collect user feedback
|
||||||
|
5. Iterate and improve
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Ready to go live?** Double-check the "Pre-Launch" and "Deployment" sections, then hit that stream button! 🎥✨
|
||||||
1
Procfile
Normal file
1
Procfile
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
web: npm start
|
||||||
130
QUICKSTART.md
Normal file
130
QUICKSTART.md
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
# Quick Start: Making aethex.live Your Streaming Platform
|
||||||
|
|
||||||
|
## 🚀 5-Minute Setup
|
||||||
|
|
||||||
|
### Step 1: Choose Your Streaming Provider
|
||||||
|
|
||||||
|
**Easiest Option - Cloudflare Stream:**
|
||||||
|
1. Go to https://dash.cloudflare.com/
|
||||||
|
2. Select "Stream" from the sidebar
|
||||||
|
3. Create a new live input
|
||||||
|
4. Copy your HLS playback URL
|
||||||
|
|
||||||
|
**Alternative Options:**
|
||||||
|
- **Mux** - https://mux.com (great developer experience)
|
||||||
|
- **AWS IVS** - https://aws.amazon.com/ivs/ (scalable)
|
||||||
|
- **Self-hosted** - See STREAMING_SETUP.md
|
||||||
|
|
||||||
|
### Step 2: Configure Your Stream
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create your environment file
|
||||||
|
cp .env.example .env.local
|
||||||
|
|
||||||
|
# Edit .env.local and add your stream URL:
|
||||||
|
NEXT_PUBLIC_STREAM_URL=your-hls-stream-url-here.m3u8
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Test Locally
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Visit http://localhost:3000 - your stream should appear!
|
||||||
|
|
||||||
|
### Step 4: Set Up OBS Studio
|
||||||
|
|
||||||
|
1. Download OBS: https://obsproject.com/
|
||||||
|
2. In OBS: Settings → Stream
|
||||||
|
3. Add your RTMP URL and Stream Key (from your provider)
|
||||||
|
4. Click "Start Streaming"
|
||||||
|
|
||||||
|
### Step 5: Deploy to Production
|
||||||
|
|
||||||
|
**Deploy to Vercel (Recommended):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Vercel CLI
|
||||||
|
npm i -g vercel
|
||||||
|
|
||||||
|
# Deploy
|
||||||
|
vercel
|
||||||
|
|
||||||
|
# Add your environment variables in Vercel dashboard
|
||||||
|
# Settings → Environment Variables → Add NEXT_PUBLIC_STREAM_URL
|
||||||
|
```
|
||||||
|
|
||||||
|
**Or use the Vercel button:**
|
||||||
|
- Push to GitHub
|
||||||
|
- Click "Deploy with Vercel" button in README
|
||||||
|
- Add environment variables
|
||||||
|
|
||||||
|
## ✅ You're Live!
|
||||||
|
|
||||||
|
Your platform is now running at: `https://your-project.vercel.app`
|
||||||
|
|
||||||
|
## 🎯 Next Steps
|
||||||
|
|
||||||
|
### Make It Yours
|
||||||
|
|
||||||
|
1. **Update Branding**
|
||||||
|
- Edit `app/page.tsx` - Change "AeThex LABS" to your brand
|
||||||
|
- Replace favicon in `app/favicon.ico`
|
||||||
|
- Update colors in the components
|
||||||
|
|
||||||
|
2. **Add Real Chat** (Currently mock)
|
||||||
|
- Firebase: See `docs/FIREBASE_CHAT.md`
|
||||||
|
- WebSocket: See `docs/WEBSOCKET_CHAT.md`
|
||||||
|
- Use API routes in `app/api/chat/`
|
||||||
|
|
||||||
|
3. **Connect Custom Domain**
|
||||||
|
- In Vercel: Settings → Domains
|
||||||
|
- Add `aethex.live`
|
||||||
|
- Update DNS records
|
||||||
|
|
||||||
|
4. **Add Features**
|
||||||
|
- [ ] User authentication
|
||||||
|
- [ ] VOD archives
|
||||||
|
- [ ] Multiple channels
|
||||||
|
- [ ] Subscriptions/donations
|
||||||
|
- [ ] Analytics dashboard
|
||||||
|
|
||||||
|
## 📊 Monitor Your Stream
|
||||||
|
|
||||||
|
- **Viewer Count**: Update `components/ViewerCount.tsx` with real data
|
||||||
|
- **Stream Status**: Use `/api/stream/status` endpoint
|
||||||
|
- **Chat History**: Use `/api/chat/messages` endpoint
|
||||||
|
|
||||||
|
## 🛟 Common Issues
|
||||||
|
|
||||||
|
**Stream won't load:**
|
||||||
|
- Check your HLS URL is correct
|
||||||
|
- Verify CORS is enabled on your stream
|
||||||
|
- Check browser console for errors
|
||||||
|
|
||||||
|
**Chat not working:**
|
||||||
|
- Currently uses mock data
|
||||||
|
- Implement real backend (see API routes)
|
||||||
|
- Add WebSocket or Firebase
|
||||||
|
|
||||||
|
**Deployment fails:**
|
||||||
|
- Verify environment variables are set
|
||||||
|
- Check build logs in Vercel
|
||||||
|
- Ensure all dependencies are installed
|
||||||
|
|
||||||
|
## 📚 Additional Resources
|
||||||
|
|
||||||
|
- **Streaming Setup**: `STREAMING_SETUP.md`
|
||||||
|
- **Config Reference**: `config/streaming.ts`
|
||||||
|
- **API Routes**: `app/api/`
|
||||||
|
|
||||||
|
## 💬 Need Help?
|
||||||
|
|
||||||
|
- Check GitHub Issues
|
||||||
|
- Join our Discord (if configured)
|
||||||
|
- Review Next.js docs: https://nextjs.org/docs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**You're all set!** Start streaming and building your community on aethex.live! 🎉
|
||||||
211
RAILWAY_DEPLOYMENT.md
Normal file
211
RAILWAY_DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
# Deploying aethex.live to Railway
|
||||||
|
|
||||||
|
Railway is a great platform for hosting full-stack applications. Here's how to get your streaming platform running on Railway.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Railway.app account (https://railway.app)
|
||||||
|
- GitHub repository connected to Railway
|
||||||
|
- Your streaming provider HLS URL
|
||||||
|
|
||||||
|
## Quick Deploy
|
||||||
|
|
||||||
|
### Option 1: Deploy from GitHub (Easiest)
|
||||||
|
|
||||||
|
1. Go to https://railway.app/dashboard
|
||||||
|
2. Click "New Project"
|
||||||
|
3. Select "Deploy from GitHub repo"
|
||||||
|
4. Choose your `aethex.live` repository
|
||||||
|
5. Configure:
|
||||||
|
- **Build Command**: `npm install && npm run build`
|
||||||
|
- **Start Command**: `npm start`
|
||||||
|
- **Port**: `3000`
|
||||||
|
|
||||||
|
### Option 2: Deploy with Railway CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Railway CLI
|
||||||
|
npm install -g @railway/cli
|
||||||
|
|
||||||
|
# Login to Railway
|
||||||
|
railway login
|
||||||
|
|
||||||
|
# Initialize Railway in your project
|
||||||
|
railway init
|
||||||
|
|
||||||
|
# Deploy
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables in Railway
|
||||||
|
|
||||||
|
1. Go to your Railway project dashboard
|
||||||
|
2. Click "Variables" tab
|
||||||
|
3. Add these environment variables:
|
||||||
|
|
||||||
|
```
|
||||||
|
NEXT_PUBLIC_STREAM_URL=your-hls-stream-url.m3u8
|
||||||
|
NODE_ENV=production
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional (if implementing backends):
|
||||||
|
|
||||||
|
```
|
||||||
|
# Firebase
|
||||||
|
NEXT_PUBLIC_FIREBASE_API_KEY=...
|
||||||
|
NEXT_PUBLIC_FIREBASE_PROJECT_ID=...
|
||||||
|
|
||||||
|
# Database
|
||||||
|
DATABASE_URL=postgresql://...
|
||||||
|
|
||||||
|
# Chat
|
||||||
|
NEXT_PUBLIC_WEBSOCKET_URL=wss://your-railway-app.railway.app
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
NEXTAUTH_URL=https://your-railway-domain.railway.app
|
||||||
|
NEXTAUTH_SECRET=your-secret-key
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Setup (Optional)
|
||||||
|
|
||||||
|
If you want to use a database on Railway:
|
||||||
|
|
||||||
|
1. In your Railway project, click "Database"
|
||||||
|
2. Select **PostgreSQL**
|
||||||
|
3. Railway will automatically set `DATABASE_URL` environment variable
|
||||||
|
4. Connect your app to the database
|
||||||
|
|
||||||
|
## Custom Domain
|
||||||
|
|
||||||
|
1. Go to Railway project → Settings
|
||||||
|
2. Look for "Domains"
|
||||||
|
3. Add your custom domain: `aethex.live`
|
||||||
|
4. Update your DNS records to point to Railway's nameservers
|
||||||
|
|
||||||
|
Or use CNAME:
|
||||||
|
```
|
||||||
|
Name: aethex
|
||||||
|
Type: CNAME
|
||||||
|
Value: (provided by Railway)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring & Logs
|
||||||
|
|
||||||
|
- **View Logs**: Railway Dashboard → Logs tab
|
||||||
|
- **Monitor Resources**: Railway Dashboard → Metrics tab
|
||||||
|
- **Configure Alerts**: Railway Dashboard → Settings → Alerts
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Build fails
|
||||||
|
- Check build logs in Railway dashboard
|
||||||
|
- Verify `package.json` has all dependencies
|
||||||
|
- Ensure Node version is 20+ (Railway default is recent)
|
||||||
|
|
||||||
|
### Stream not loading
|
||||||
|
- Check `NEXT_PUBLIC_STREAM_URL` is set correctly
|
||||||
|
- Verify HLS URL is publicly accessible
|
||||||
|
- Check if CORS is enabled on your stream provider
|
||||||
|
|
||||||
|
### App crashes
|
||||||
|
- View logs in Railway for error messages
|
||||||
|
- Check if PORT is correctly set to 3000
|
||||||
|
- Ensure memory limit is sufficient (512MB+ recommended)
|
||||||
|
|
||||||
|
### Domain issues
|
||||||
|
- DNS changes can take 24-48 hours to propagate
|
||||||
|
- Verify CNAME/A record points to Railway
|
||||||
|
- Test with `nslookup aethex.live`
|
||||||
|
|
||||||
|
## Advanced Railway Configuration
|
||||||
|
|
||||||
|
Create a `railway.json` file for automatic deployments:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"$schema": "https://railway.app/schema.json",
|
||||||
|
"build": {
|
||||||
|
"builder": "nixpacks"
|
||||||
|
},
|
||||||
|
"deploy": {
|
||||||
|
"startCommand": "npm start",
|
||||||
|
"restartPolicyType": "on_failure",
|
||||||
|
"restartPolicyMaxRetries": 3,
|
||||||
|
"numReplicas": 1,
|
||||||
|
"healthcheckPath": "/",
|
||||||
|
"healthcheckTimeout": 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scaling
|
||||||
|
|
||||||
|
As your stream grows:
|
||||||
|
|
||||||
|
1. **Increase Memory**: Railway Dashboard → Settings → Instance Size
|
||||||
|
2. **Add More Instances**: Set `numReplicas` in railway.json
|
||||||
|
3. **Add CDN**: Use Cloudflare in front of Railway
|
||||||
|
4. **Database Optimization**: Add indexes, optimize queries
|
||||||
|
|
||||||
|
## Cost Optimization
|
||||||
|
|
||||||
|
Railway charges per hour for usage:
|
||||||
|
- **CPU**: $0.07/month per 1 CPU per hour active
|
||||||
|
- **Memory**: $0.07/month per 1GB per hour active
|
||||||
|
|
||||||
|
Estimate: ~$5-15/month for a small streaming app
|
||||||
|
|
||||||
|
Tips:
|
||||||
|
- Stop unused projects
|
||||||
|
- Use Railway's free tier ($5 credit/month)
|
||||||
|
- Monitor resource usage in Metrics tab
|
||||||
|
- Optimize build size: Use production builds
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
Railway automatically deploys when you push to main:
|
||||||
|
|
||||||
|
1. Push code to GitHub
|
||||||
|
2. Railway detects changes
|
||||||
|
3. Auto-builds and deploys
|
||||||
|
4. Preview deployments for pull requests
|
||||||
|
|
||||||
|
Disable auto-deploy: Railway Dashboard → Settings → Auto Deploy
|
||||||
|
|
||||||
|
## Useful Railway Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View project status
|
||||||
|
railway status
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
railway logs
|
||||||
|
|
||||||
|
# Open dashboard
|
||||||
|
railway open
|
||||||
|
|
||||||
|
# Set environment variable
|
||||||
|
railway variables set NEXT_PUBLIC_STREAM_URL=your-url
|
||||||
|
|
||||||
|
# Deploy specific branch
|
||||||
|
railway deploy --branch staging
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. ✅ Deploy to Railway
|
||||||
|
2. ✅ Add custom domain
|
||||||
|
3. Implement real chat backend (Firebase/WebSocket)
|
||||||
|
4. Add user authentication
|
||||||
|
5. Set up analytics
|
||||||
|
6. Monitor stream performance
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
- Railway Docs: https://docs.railway.app
|
||||||
|
- Next.js on Railway: https://docs.railway.app/guides/nextjs
|
||||||
|
- Community: https://discord.gg/railway
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Your stream is now on Railway! 🚀**
|
||||||
62
README.md
62
README.md
|
|
@ -49,12 +49,22 @@ npm run dev
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
To use your own HLS stream, edit `app/page.tsx` and update the `streamUrl` variable:
|
To use your own HLS stream:
|
||||||
|
|
||||||
```typescript
|
1. Copy the environment template:
|
||||||
const streamUrl = 'YOUR_HLS_STREAM_URL.m3u8';
|
```bash
|
||||||
|
cp .env.example .env.local
|
||||||
```
|
```
|
||||||
|
|
||||||
|
2. Add your stream URL:
|
||||||
|
```env
|
||||||
|
NEXT_PUBLIC_STREAM_URL=your-hls-stream-url.m3u8
|
||||||
|
```
|
||||||
|
|
||||||
|
3. (Optional) Customize settings in `config/streaming.ts`
|
||||||
|
|
||||||
|
**📖 See [QUICKSTART.md](QUICKSTART.md) for a complete setup guide!**
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
Create an optimized production build:
|
Create an optimized production build:
|
||||||
|
|
@ -64,6 +74,52 @@ npm run build
|
||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 🚀 Making It Your Platform
|
||||||
|
|
||||||
|
This is ready to become your live streaming hub! Check out these guides:
|
||||||
|
|
||||||
|
- **[QUICKSTART.md](QUICKSTART.md)** - Get streaming in 5 minutes
|
||||||
|
- **[STREAMING_SETUP.md](STREAMING_SETUP.md)** - Full platform setup guide
|
||||||
|
- **[config/streaming.ts](config/streaming.ts)** - Configuration reference
|
||||||
|
|
||||||
|
### Ready-to-Use Features
|
||||||
|
|
||||||
|
✅ HLS video player with auto-recovery
|
||||||
|
✅ Responsive design (mobile & desktop)
|
||||||
|
✅ Chat sidebar UI (connect your backend)
|
||||||
|
✅ Viewer count display
|
||||||
|
✅ Now playing metadata
|
||||||
|
✅ API routes for stream status & chat
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
|
||||||
|
1. Get a streaming provider (Cloudflare/Mux/AWS)
|
||||||
|
2. Set up OBS Studio
|
||||||
|
3. Add your stream URL to `.env.local`
|
||||||
|
4. Choose your platform and deploy
|
||||||
|
5. Point your domain to your hosting provider
|
||||||
|
|
||||||
|
## 🚀 Deployment Options
|
||||||
|
|
||||||
|
### Vercel (Recommended for Beginners)
|
||||||
|
Automatic deployments, zero config:
|
||||||
|
```bash
|
||||||
|
npm i -g vercel
|
||||||
|
vercel
|
||||||
|
```
|
||||||
|
|
||||||
|
### Railway (Full Control & Backend)
|
||||||
|
Great for custom backends and databases:
|
||||||
|
```bash
|
||||||
|
npm i -g @railway/cli
|
||||||
|
railway login
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
See [RAILWAY_DEPLOYMENT.md](RAILWAY_DEPLOYMENT.md) for detailed setup.
|
||||||
|
|
||||||
|
### Other Platforms
|
||||||
|
Next.js can deploy to AWS, Netlify, Cloudflare Pages, and more. Check [Next.js deployment docs](https://nextjs.org/docs/app/building-your-application/deploying).
|
||||||
|
|
||||||
## Scripts
|
## Scripts
|
||||||
|
|
||||||
- `npm run dev` - Start development server
|
- `npm run dev` - Start development server
|
||||||
|
|
|
||||||
135
STREAMING_SETUP.md
Normal file
135
STREAMING_SETUP.md
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
# Live Streaming Setup Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Transform aethex.live into a fully functional live streaming platform.
|
||||||
|
|
||||||
|
## 🎥 Streaming Options
|
||||||
|
|
||||||
|
### Option 1: OBS Studio → Streaming Service
|
||||||
|
**Recommended for beginners**
|
||||||
|
|
||||||
|
#### Services to consider:
|
||||||
|
- **Cloudflare Stream** - $5/month, easy setup, global CDN
|
||||||
|
- **Mux** - Pay-as-you-go, developer-friendly
|
||||||
|
- **AWS IVS** - Scalable, AWS infrastructure
|
||||||
|
- **Twitch API** - If you want to use Twitch as backend
|
||||||
|
|
||||||
|
#### Setup with Cloudflare Stream:
|
||||||
|
1. Sign up at cloudflare.com/products/cloudflare-stream
|
||||||
|
2. Get your Stream URL and Key
|
||||||
|
3. Configure OBS Studio:
|
||||||
|
- Settings → Stream
|
||||||
|
- Service: Custom
|
||||||
|
- Server: Your Cloudflare RTMP URL
|
||||||
|
- Stream Key: Your key
|
||||||
|
4. Update `app/page.tsx` with your HLS playback URL
|
||||||
|
|
||||||
|
### Option 2: Self-Hosted (Advanced)
|
||||||
|
**For full control**
|
||||||
|
|
||||||
|
#### Requirements:
|
||||||
|
- VPS/Server (DigitalOcean, AWS, etc.)
|
||||||
|
- Nginx with RTMP module
|
||||||
|
- Domain with SSL
|
||||||
|
|
||||||
|
#### Stack:
|
||||||
|
```bash
|
||||||
|
# Install on Ubuntu server
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install nginx libnginx-mod-rtmp
|
||||||
|
```
|
||||||
|
|
||||||
|
See `docs/SELF_HOSTED_SETUP.md` for full guide.
|
||||||
|
|
||||||
|
### Option 3: Multiple Stream Sources
|
||||||
|
Support streaming from:
|
||||||
|
- OBS Studio
|
||||||
|
- StreamLabs
|
||||||
|
- Mobile apps
|
||||||
|
- Pre-recorded content
|
||||||
|
|
||||||
|
## 💬 Real-Time Features
|
||||||
|
|
||||||
|
### Chat Implementation
|
||||||
|
**Option A: Firebase (Quickest)**
|
||||||
|
```bash
|
||||||
|
npm install firebase
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option B: WebSocket Server**
|
||||||
|
```bash
|
||||||
|
npm install socket.io
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option C: Third-party (Pusher, Ably)**
|
||||||
|
|
||||||
|
### Viewer Count
|
||||||
|
- WebSocket connections
|
||||||
|
- Analytics services
|
||||||
|
- Real-time database
|
||||||
|
|
||||||
|
## 🚀 Deployment
|
||||||
|
|
||||||
|
### Deploy Frontend to Vercel
|
||||||
|
```bash
|
||||||
|
npm install -g vercel
|
||||||
|
vercel
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploy to Custom Domain
|
||||||
|
1. Point DNS to Vercel
|
||||||
|
2. Add domain in Vercel dashboard
|
||||||
|
3. SSL auto-configured
|
||||||
|
|
||||||
|
### Alternative Platforms:
|
||||||
|
- **Netlify** - Similar to Vercel
|
||||||
|
- **Cloudflare Pages** - Free tier, fast global CDN
|
||||||
|
- **AWS Amplify** - If using AWS for streaming
|
||||||
|
|
||||||
|
## 🔐 Backend Needs
|
||||||
|
|
||||||
|
### Essential APIs:
|
||||||
|
1. **Authentication** - Clerk, Auth0, or NextAuth.js
|
||||||
|
2. **Database** - Supabase, Firebase, or PostgreSQL
|
||||||
|
3. **Chat Storage** - Real-time DB or Redis
|
||||||
|
4. **Analytics** - Track views, engagement
|
||||||
|
|
||||||
|
### Example Backend Stack:
|
||||||
|
```
|
||||||
|
Frontend: Next.js (current)
|
||||||
|
Auth: Clerk
|
||||||
|
Database: Supabase
|
||||||
|
Storage: Cloudflare R2
|
||||||
|
Streaming: Cloudflare Stream
|
||||||
|
Chat: WebSocket (socket.io)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Monetization Features (Future)
|
||||||
|
|
||||||
|
- Subscriptions (Stripe)
|
||||||
|
- Donations/Tips
|
||||||
|
- Private streams
|
||||||
|
- VOD content
|
||||||
|
- Channel memberships
|
||||||
|
|
||||||
|
## 🎯 Quick Start Checklist
|
||||||
|
|
||||||
|
- [ ] Choose streaming service
|
||||||
|
- [ ] Set up OBS Studio
|
||||||
|
- [ ] Get HLS stream URL
|
||||||
|
- [ ] Update streamUrl in app/page.tsx
|
||||||
|
- [ ] Set up backend for chat
|
||||||
|
- [ ] Add authentication
|
||||||
|
- [ ] Deploy to Vercel
|
||||||
|
- [ ] Configure custom domain
|
||||||
|
- [ ] Test stream end-to-end
|
||||||
|
- [ ] Set up analytics
|
||||||
|
|
||||||
|
## 🛠️ Next Steps
|
||||||
|
|
||||||
|
Run the setup wizard to configure your platform:
|
||||||
|
```bash
|
||||||
|
npm run setup:streaming
|
||||||
|
```
|
||||||
|
|
||||||
|
Or manually update configuration in `config/streaming.ts`
|
||||||
75
app/api/chat/messages/route.ts
Normal file
75
app/api/chat/messages/route.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
// Example API route for chat messages
|
||||||
|
// Access at: /api/chat/messages
|
||||||
|
|
||||||
|
// In-memory storage (replace with a real database)
|
||||||
|
let messages: Array<{
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
message: string;
|
||||||
|
timestamp: string;
|
||||||
|
}> = [];
|
||||||
|
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
// Return recent chat messages
|
||||||
|
return NextResponse.json({
|
||||||
|
messages: messages.slice(-100), // Last 100 messages
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const body = await request.json();
|
||||||
|
const { username, message } = body;
|
||||||
|
|
||||||
|
// Basic validation
|
||||||
|
if (!username || !message) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Username and message required' },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.length > 500) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Message too long' },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new message
|
||||||
|
const newMessage = {
|
||||||
|
id: Math.random().toString(36).substring(7),
|
||||||
|
username,
|
||||||
|
message,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
messages.push(newMessage);
|
||||||
|
|
||||||
|
// Keep only last 1000 messages
|
||||||
|
if (messages.length > 1000) {
|
||||||
|
messages = messages.slice(-1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: newMessage,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Failed to post message' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DELETE(request: NextRequest) {
|
||||||
|
// Clear all messages (admin only)
|
||||||
|
messages = [];
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Chat cleared',
|
||||||
|
});
|
||||||
|
}
|
||||||
34
app/api/stream/status/route.ts
Normal file
34
app/api/stream/status/route.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
// Example API route for stream status
|
||||||
|
// Access at: /api/stream/status
|
||||||
|
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
// TODO: Replace with your actual stream status check
|
||||||
|
// This could connect to your streaming provider's API
|
||||||
|
|
||||||
|
const status = {
|
||||||
|
isLive: true,
|
||||||
|
viewers: Math.floor(Math.random() * 1000) + 100, // Mock data
|
||||||
|
startedAt: new Date().toISOString(),
|
||||||
|
title: 'AeThex LABS Live Stream',
|
||||||
|
uptime: '2h 34m',
|
||||||
|
};
|
||||||
|
|
||||||
|
return NextResponse.json(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
// Handle stream start/stop events
|
||||||
|
const body = await request.json();
|
||||||
|
|
||||||
|
// TODO: Implement stream control logic
|
||||||
|
// - Start/stop recording
|
||||||
|
// - Update stream metadata
|
||||||
|
// - Trigger notifications
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Stream updated',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -5,12 +5,13 @@ import HLSPlayer from '@/components/HLSPlayer';
|
||||||
import ViewerCount from '@/components/ViewerCount';
|
import ViewerCount from '@/components/ViewerCount';
|
||||||
import NowPlaying from '@/components/NowPlaying';
|
import NowPlaying from '@/components/NowPlaying';
|
||||||
import ChatSidebar from '@/components/ChatSidebar';
|
import ChatSidebar from '@/components/ChatSidebar';
|
||||||
|
import streamingConfig from '@/config/streaming';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [showChat, setShowChat] = useState(true);
|
const [showChat, setShowChat] = useState(true);
|
||||||
|
|
||||||
// Demo HLS stream URL - replace with your actual stream URL
|
// Stream URL from config - set NEXT_PUBLIC_STREAM_URL in .env.local
|
||||||
const streamUrl = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
|
const streamUrl = streamingConfig.streamUrl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-b from-black to-slate-900 text-white">
|
<div className="min-h-screen bg-gradient-to-b from-black to-slate-900 text-white">
|
||||||
|
|
|
||||||
51
config/streaming.ts
Normal file
51
config/streaming.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Streaming Platform Configuration
|
||||||
|
// Update these values for your live streaming setup
|
||||||
|
|
||||||
|
export const streamingConfig = {
|
||||||
|
// Your HLS stream URL - get this from your streaming provider
|
||||||
|
// Examples:
|
||||||
|
// Cloudflare Stream: https://customer-xxxxx.cloudflarestream.com/xxxxx/manifest/video.m3u8
|
||||||
|
// Mux: https://stream.mux.com/xxxxx.m3u8
|
||||||
|
// AWS IVS: https://xxxxx.us-west-2.playback.live-video.net/api/video/v1/xxxxx.m3u8
|
||||||
|
streamUrl: process.env.NEXT_PUBLIC_STREAM_URL || 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
|
||||||
|
|
||||||
|
// Stream metadata
|
||||||
|
stream: {
|
||||||
|
title: 'AeThex LABS Live',
|
||||||
|
description: 'Live streaming content 24/7',
|
||||||
|
defaultThumbnail: '/stream-thumbnail.jpg',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Feature flags
|
||||||
|
features: {
|
||||||
|
chat: true,
|
||||||
|
viewerCount: true,
|
||||||
|
nowPlaying: true,
|
||||||
|
donations: false,
|
||||||
|
subscriptions: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Chat configuration
|
||||||
|
chat: {
|
||||||
|
enabled: true,
|
||||||
|
// Choose: 'firebase' | 'websocket' | 'pusher' | 'mock'
|
||||||
|
provider: 'mock',
|
||||||
|
maxMessageLength: 500,
|
||||||
|
rateLimit: 2, // messages per second
|
||||||
|
},
|
||||||
|
|
||||||
|
// Analytics
|
||||||
|
analytics: {
|
||||||
|
enabled: false,
|
||||||
|
provider: 'vercel', // or 'google' | 'plausible'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Social links
|
||||||
|
social: {
|
||||||
|
twitter: 'https://twitter.com/aethexlabs',
|
||||||
|
discord: 'https://discord.gg/aethexlabs',
|
||||||
|
github: 'https://github.com/AeThex-LABS',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default streamingConfig;
|
||||||
391
docs/RAILWAY_COMPLETE_GUIDE.md
Normal file
391
docs/RAILWAY_COMPLETE_GUIDE.md
Normal file
|
|
@ -0,0 +1,391 @@
|
||||||
|
# Railway Deployment Guide for aethex.live
|
||||||
|
|
||||||
|
Since you're already using Railway, here's everything you need to deploy your streaming platform there.
|
||||||
|
|
||||||
|
## 📋 Table of Contents
|
||||||
|
1. [Quick Start](#quick-start)
|
||||||
|
2. [Full Setup](#full-setup)
|
||||||
|
3. [Adding Services](#adding-services)
|
||||||
|
4. [Environment Setup](#environment-setup)
|
||||||
|
5. [Monitoring & Debugging](#monitoring--debugging)
|
||||||
|
6. [Production Scaling](#production-scaling)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
The fastest way to get running:
|
||||||
|
|
||||||
|
### Step 1: Deploy the App
|
||||||
|
```bash
|
||||||
|
npm i -g @railway/cli
|
||||||
|
railway login
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Add Stream URL
|
||||||
|
In Railway Dashboard → Variables:
|
||||||
|
```
|
||||||
|
NEXT_PUBLIC_STREAM_URL=your-hls-stream-url.m3u8
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Add Domain
|
||||||
|
In Railway Dashboard → Domains → Add:
|
||||||
|
- Domain: `aethex.live`
|
||||||
|
- Add DNS CNAME record to your domain registrar
|
||||||
|
|
||||||
|
**Done!** Your app is live. 🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Full Setup
|
||||||
|
|
||||||
|
### Project Structure on Railway
|
||||||
|
|
||||||
|
```
|
||||||
|
aethex.live
|
||||||
|
├── Web Service (Next.js app)
|
||||||
|
├── PostgreSQL (optional - for chat/data)
|
||||||
|
├── Redis (optional - for viewer count/cache)
|
||||||
|
└── Environment Variables
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 1: Connect GitHub
|
||||||
|
|
||||||
|
1. Go to https://railway.app/dashboard
|
||||||
|
2. Click "New Project"
|
||||||
|
3. Select "Deploy from GitHub"
|
||||||
|
4. Choose `aethex.live` repository
|
||||||
|
5. Connect and authorize
|
||||||
|
|
||||||
|
### Step 2: Configure Environment
|
||||||
|
|
||||||
|
Add these environment variables:
|
||||||
|
|
||||||
|
**Required:**
|
||||||
|
```
|
||||||
|
NEXT_PUBLIC_STREAM_URL=your-hls-stream-url.m3u8
|
||||||
|
NODE_ENV=production
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional (for features):**
|
||||||
|
```
|
||||||
|
# If using database
|
||||||
|
DATABASE_URL=<auto-set by Railway if you add PostgreSQL>
|
||||||
|
|
||||||
|
# If adding authentication
|
||||||
|
NEXTAUTH_URL=https://aethex.live
|
||||||
|
NEXTAUTH_SECRET=generate-random-secret-here
|
||||||
|
|
||||||
|
# If using WebSocket
|
||||||
|
NEXT_PUBLIC_WEBSOCKET_URL=wss://aethex.live/socket.io
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Deploy
|
||||||
|
|
||||||
|
Railway auto-deploys on push to main:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
Or manually trigger:
|
||||||
|
```bash
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adding Services
|
||||||
|
|
||||||
|
### Add Database (PostgreSQL)
|
||||||
|
|
||||||
|
Perfect for storing chat, users, streams, etc.
|
||||||
|
|
||||||
|
1. Railway Dashboard → Click "+" → Add Database
|
||||||
|
2. Select **PostgreSQL**
|
||||||
|
3. Railway auto-sets `DATABASE_URL` environment variable
|
||||||
|
4. Use examples from `docs/RAILWAY_POSTGRES_EXAMPLE.tsx`
|
||||||
|
|
||||||
|
Then initialize your database:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Run this once to create the messages table
|
||||||
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
username VARCHAR(255) NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_timestamp ON messages(timestamp DESC);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Redis (Caching & Real-Time)
|
||||||
|
|
||||||
|
Great for viewer count and caching:
|
||||||
|
|
||||||
|
1. Railway Dashboard → Click "+" → Add Service
|
||||||
|
2. Marketplace → Search "Upstash Redis"
|
||||||
|
3. Add to project
|
||||||
|
4. Railway sets `UPSTASH_REDIS_*` variables automatically
|
||||||
|
|
||||||
|
See `docs/VIEWER_COUNT_EXAMPLE.ts` for usage.
|
||||||
|
|
||||||
|
### Connect External Services
|
||||||
|
|
||||||
|
If using external services (Cloudflare, Stripe, etc.):
|
||||||
|
|
||||||
|
1. Get API keys from the service
|
||||||
|
2. Add as environment variables in Railway
|
||||||
|
3. Use in your code via `process.env.YOUR_API_KEY`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment Setup
|
||||||
|
|
||||||
|
### Local Development
|
||||||
|
|
||||||
|
Copy Railway's env vars locally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
railway vars fetch >> .env.local
|
||||||
|
```
|
||||||
|
|
||||||
|
This pulls all environment variables from Railway into your local `.env.local`.
|
||||||
|
|
||||||
|
### Environment Variables Explained
|
||||||
|
|
||||||
|
| Variable | Purpose | Example |
|
||||||
|
|----------|---------|---------|
|
||||||
|
| `NEXT_PUBLIC_STREAM_URL` | HLS stream URL | `https://...m3u8` |
|
||||||
|
| `DATABASE_URL` | PostgreSQL connection | Set by Railway |
|
||||||
|
| `NEXTAUTH_SECRET` | Auth secret | `random-key-here` |
|
||||||
|
| `NODE_ENV` | Environment | `production` |
|
||||||
|
| `UPSTASH_REDIS_REST_URL` | Redis endpoint | Set by Railway |
|
||||||
|
|
||||||
|
**Important:** Variables starting with `NEXT_PUBLIC_` are exposed to the browser. Never put secrets there!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Monitoring & Debugging
|
||||||
|
|
||||||
|
### View Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Live logs
|
||||||
|
railway logs
|
||||||
|
|
||||||
|
# Or in dashboard: Deployments → View Logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitor Performance
|
||||||
|
|
||||||
|
Railway Dashboard → Deployments → Metrics:
|
||||||
|
- CPU usage
|
||||||
|
- Memory usage
|
||||||
|
- Network I/O
|
||||||
|
- Build time
|
||||||
|
|
||||||
|
### Troubleshoot Issues
|
||||||
|
|
||||||
|
| Problem | Solution |
|
||||||
|
|---------|----------|
|
||||||
|
| App crashes on startup | Check logs for errors, verify `npm start` works |
|
||||||
|
| Can't connect to database | Verify `DATABASE_URL` is set, check firewall |
|
||||||
|
| Stream won't load | Verify `NEXT_PUBLIC_STREAM_URL` is correct |
|
||||||
|
| High memory usage | Check for memory leaks, consider caching |
|
||||||
|
| Slow builds | Check dependencies, consider build optimization |
|
||||||
|
|
||||||
|
### Enable Debug Mode
|
||||||
|
|
||||||
|
Add to environment:
|
||||||
|
```
|
||||||
|
DEBUG=*
|
||||||
|
NODE_ENV=development
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Production Scaling
|
||||||
|
|
||||||
|
### Handle Growth
|
||||||
|
|
||||||
|
As your viewers increase:
|
||||||
|
|
||||||
|
#### 1. Upgrade Instance Size
|
||||||
|
```
|
||||||
|
Railway Dashboard → Settings → Instance Size
|
||||||
|
- Standard ($5-20/month): Great for streaming
|
||||||
|
- Pro: For high traffic
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Add Multiple Replicas
|
||||||
|
|
||||||
|
In Railway Dashboard → Settings → Deploy:
|
||||||
|
- Set `numReplicas: 2` or higher for load balancing
|
||||||
|
|
||||||
|
Or in `railway.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"deploy": {
|
||||||
|
"numReplicas": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Add CDN (Cloudflare)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Add Cloudflare in front of Railway
|
||||||
|
2. Points: aethex.live → Cloudflare → Railway
|
||||||
|
3. Benefits: Caching, DDoS protection, global speed
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Database Optimization
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Add indexes for common queries
|
||||||
|
CREATE INDEX idx_messages_username ON messages(username);
|
||||||
|
CREATE INDEX idx_messages_timestamp ON messages(timestamp DESC);
|
||||||
|
|
||||||
|
-- Monitor slow queries
|
||||||
|
EXPLAIN ANALYZE SELECT * FROM messages WHERE ...;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. Caching Strategy
|
||||||
|
|
||||||
|
Use Redis for:
|
||||||
|
- Session data
|
||||||
|
- View count
|
||||||
|
- Popular chat messages
|
||||||
|
- API responses
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cost Management
|
||||||
|
|
||||||
|
Railway pricing:
|
||||||
|
|
||||||
|
- **Compute**: $0.07/month per CPU-hour
|
||||||
|
- **Memory**: $0.07/month per GB-hour
|
||||||
|
- **Databases**: $15-30/month depending on size
|
||||||
|
|
||||||
|
**Estimated monthly cost:**
|
||||||
|
- Small app: $5-10/month
|
||||||
|
- Medium app: $20-50/month
|
||||||
|
- Large app: $50+/month
|
||||||
|
|
||||||
|
**Save money:**
|
||||||
|
- Stop unused projects
|
||||||
|
- Use free tier ($5 credit/month)
|
||||||
|
- Use Railway's managed Redis instead of self-hosted
|
||||||
|
- Enable auto-scaling instead of always-on
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Checklist
|
||||||
|
|
||||||
|
Before going live:
|
||||||
|
|
||||||
|
- [ ] Stream URL configured
|
||||||
|
- [ ] Environment variables set
|
||||||
|
- [ ] Domain configured
|
||||||
|
- [ ] SSL certificate active (auto)
|
||||||
|
- [ ] Logs reviewed for errors
|
||||||
|
- [ ] Test stream verified
|
||||||
|
- [ ] Chat working (if enabled)
|
||||||
|
- [ ] Mobile responsive
|
||||||
|
- [ ] Analytics enabled
|
||||||
|
- [ ] Monitoring configured
|
||||||
|
- [ ] Backup plan documented
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Continuous Deployment
|
||||||
|
|
||||||
|
Railway auto-deploys on push:
|
||||||
|
|
||||||
|
```
|
||||||
|
You push → GitHub → Railway detects → Auto builds → Auto deploys → Live!
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable auto-deploy if needed:
|
||||||
|
```
|
||||||
|
Dashboard → Settings → Disable Auto Deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
Then manually deploy:
|
||||||
|
```bash
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Useful Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status
|
||||||
|
railway status
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
railway logs -f # follow mode
|
||||||
|
|
||||||
|
# Open dashboard
|
||||||
|
railway open
|
||||||
|
|
||||||
|
# Set variable
|
||||||
|
railway variables set KEY=value
|
||||||
|
|
||||||
|
# Pull all vars
|
||||||
|
railway vars fetch
|
||||||
|
|
||||||
|
# Redeploy
|
||||||
|
railway up
|
||||||
|
|
||||||
|
# Stop project
|
||||||
|
railway stop
|
||||||
|
|
||||||
|
# View project info
|
||||||
|
railway whoami
|
||||||
|
railway projects list
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. ✅ Deploy to Railway (this guide)
|
||||||
|
2. ✅ Configure your stream URL
|
||||||
|
3. **Next**: Add real-time features
|
||||||
|
- Chat with PostgreSQL (see `docs/RAILWAY_POSTGRES_EXAMPLE.tsx`)
|
||||||
|
- WebSocket support (see `docs/WEBSOCKET_EXAMPLE.ts`)
|
||||||
|
- Real-time viewer count (see `docs/VIEWER_COUNT_EXAMPLE.ts`)
|
||||||
|
4. Add user authentication
|
||||||
|
5. Set up analytics
|
||||||
|
6. Monetize (subscriptions, donations)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
- **Railway Docs**: https://docs.railway.app
|
||||||
|
- **Railway CLI**: https://docs.railway.app/reference/cli
|
||||||
|
- **Next.js on Railway**: https://docs.railway.app/guides/nextjs
|
||||||
|
- **Railway Community**: https://discord.gg/railway
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
Having issues?
|
||||||
|
|
||||||
|
1. Check logs: `railway logs`
|
||||||
|
2. Review this guide for your use case
|
||||||
|
3. Check Railway docs
|
||||||
|
4. Community Discord: https://discord.gg/railway
|
||||||
|
5. Railway support: https://railway.app/support
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Your streaming platform is now on Railway! 🚀 Start streaming!**
|
||||||
87
docs/RAILWAY_POSTGRES_EXAMPLE.tsx
Normal file
87
docs/RAILWAY_POSTGRES_EXAMPLE.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Example: PostgreSQL Chat Implementation for Railway
|
||||||
|
// This uses the DATABASE_URL that Railway provides automatically
|
||||||
|
|
||||||
|
import { sql } from '@vercel/postgres';
|
||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
// GET recent messages
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const result = await sql`
|
||||||
|
SELECT id, username, message, timestamp
|
||||||
|
FROM messages
|
||||||
|
ORDER BY timestamp DESC
|
||||||
|
LIMIT 100
|
||||||
|
`;
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
messages: result.rows.reverse(),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Database error:', error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Failed to fetch messages' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST new message
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const body = await request.json();
|
||||||
|
const { username, message } = body;
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
if (!username || !message) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Username and message required' },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.length > 500) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Message too long' },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert into database
|
||||||
|
const result = await sql`
|
||||||
|
INSERT INTO messages (username, message, timestamp)
|
||||||
|
VALUES (${username}, ${message}, NOW())
|
||||||
|
RETURNING id, username, message, timestamp
|
||||||
|
`;
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: result.rows[0],
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Database error:', error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Failed to post message' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// You'll need to initialize the database with this schema once:
|
||||||
|
/*
|
||||||
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
username VARCHAR(255) NOT NULL,
|
||||||
|
message TEXT NOT NULL,
|
||||||
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_messages_timestamp ON messages(timestamp DESC);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Setup instructions:
|
||||||
|
// 1. In Railway dashboard, add PostgreSQL database to your project
|
||||||
|
// 2. Railway auto-sets DATABASE_URL environment variable
|
||||||
|
// 3. Run the schema creation query once
|
||||||
|
// 4. Update your chat component to use this API
|
||||||
86
docs/RAILWAY_QUICK_START.md
Normal file
86
docs/RAILWAY_QUICK_START.md
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
# Railway Setup - Quick Reference
|
||||||
|
|
||||||
|
## One-Command Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i -g @railway/cli && railway login && railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
## Manual Steps
|
||||||
|
|
||||||
|
1. **Create Project on Railway**
|
||||||
|
- Go to https://railway.app/dashboard
|
||||||
|
- Click "New Project" → "Deploy from GitHub"
|
||||||
|
- Select your `aethex.live` repository
|
||||||
|
|
||||||
|
2. **Add Environment Variables**
|
||||||
|
- Project Settings → Variables
|
||||||
|
- Add: `NEXT_PUBLIC_STREAM_URL=your-hls-url.m3u8`
|
||||||
|
- Save
|
||||||
|
|
||||||
|
3. **Wait for Deployment**
|
||||||
|
- Railway auto-builds and deploys
|
||||||
|
- Check Deployments tab for status
|
||||||
|
- Live URL appears when ready
|
||||||
|
|
||||||
|
4. **Add Custom Domain**
|
||||||
|
- Settings → Domains
|
||||||
|
- Add `aethex.live`
|
||||||
|
- Update DNS records (CNAME)
|
||||||
|
|
||||||
|
## Environment Variables Needed
|
||||||
|
|
||||||
|
**Required:**
|
||||||
|
```
|
||||||
|
NEXT_PUBLIC_STREAM_URL=your-hls-stream-url.m3u8
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional (backend features):**
|
||||||
|
```
|
||||||
|
DATABASE_URL=postgresql://... # if using database
|
||||||
|
NEXTAUTH_URL=https://aethex.live # if using auth
|
||||||
|
NEXTAUTH_SECRET=random-secret-key # if using auth
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Your Deployment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via Railway CLI
|
||||||
|
railway open
|
||||||
|
|
||||||
|
# Or visit the URL provided in Railway Dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Issue | Fix |
|
||||||
|
|-------|-----|
|
||||||
|
| Build fails | Check build logs in Railway dashboard |
|
||||||
|
| Stream won't load | Verify `NEXT_PUBLIC_STREAM_URL` is set |
|
||||||
|
| Domain not working | Wait 24hrs for DNS, check CNAME record |
|
||||||
|
| App keeps crashing | View logs, check if PORT=3000 is used |
|
||||||
|
|
||||||
|
## Useful Railway CLI Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
railway login # Login to Railway
|
||||||
|
railway up # Deploy current project
|
||||||
|
railway logs # View live logs
|
||||||
|
railway variables set KEY=value # Set env var
|
||||||
|
railway open # Open project in browser
|
||||||
|
railway status # Check deployment status
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Time You Deploy
|
||||||
|
|
||||||
|
Just push to GitHub and Railway auto-deploys! Or:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Your stream is live on Railway!** 🚀
|
||||||
|
|
||||||
|
For more: See `RAILWAY_DEPLOYMENT.md` or visit https://docs.railway.app
|
||||||
74
docs/VIEWER_COUNT_EXAMPLE.ts
Normal file
74
docs/VIEWER_COUNT_EXAMPLE.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Example: Real-Time Viewer Count with Railway
|
||||||
|
// Uses WebSocket to broadcast viewer count updates
|
||||||
|
|
||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
// In-memory viewer count (in production, use Redis or database)
|
||||||
|
let viewerCount = Math.floor(Math.random() * 1000) + 100;
|
||||||
|
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
return NextResponse.json({
|
||||||
|
viewers: viewerCount,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const body = await request.json();
|
||||||
|
const { action, count } = body;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'increment':
|
||||||
|
viewerCount = Math.max(0, viewerCount + 1);
|
||||||
|
break;
|
||||||
|
case 'decrement':
|
||||||
|
viewerCount = Math.max(0, viewerCount - 1);
|
||||||
|
break;
|
||||||
|
case 'set':
|
||||||
|
if (typeof count === 'number' && count >= 0) {
|
||||||
|
viewerCount = count;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Invalid action' },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In production: broadcast via WebSocket
|
||||||
|
// io.emit('viewer-count-update', viewerCount);
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
viewers: viewerCount,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Failed to update viewer count' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Production setup with Redis (recommended for Railway):
|
||||||
|
/*
|
||||||
|
import { Redis } from '@upstash/redis';
|
||||||
|
|
||||||
|
const redis = new Redis({
|
||||||
|
url: process.env.UPSTASH_REDIS_REST_URL,
|
||||||
|
token: process.env.UPSTASH_REDIS_REST_TOKEN,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then use Redis instead of in-memory:
|
||||||
|
export async function GET() {
|
||||||
|
const viewers = await redis.get('viewer-count') || 0;
|
||||||
|
return NextResponse.json({ viewers });
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Redis setup on Railway:
|
||||||
|
// 1. Add Upstash Redis service to Railway project
|
||||||
|
// 2. Set environment variables
|
||||||
|
// 3. Use the client as shown above
|
||||||
72
docs/WEBSOCKET_EXAMPLE.ts
Normal file
72
docs/WEBSOCKET_EXAMPLE.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Example: WebSocket Chat for Real-Time Messages
|
||||||
|
// This example uses socket.io which works great on Railway
|
||||||
|
|
||||||
|
import { Server as HTTPServer } from 'http';
|
||||||
|
import { Socket as ServerSocket } from 'socket.io';
|
||||||
|
import { createServer } from 'http';
|
||||||
|
|
||||||
|
interface Message {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
message: string;
|
||||||
|
timestamp: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
let messages: Message[] = [];
|
||||||
|
const maxMessages = 1000;
|
||||||
|
|
||||||
|
export async function initializeWebSocket(server: HTTPServer) {
|
||||||
|
const io = new (await import('socket.io')).Server(server, {
|
||||||
|
cors: {
|
||||||
|
origin: process.env.NODE_ENV === 'production'
|
||||||
|
? process.env.NEXT_PUBLIC_APP_URL || 'https://aethex.live'
|
||||||
|
: 'http://localhost:3000',
|
||||||
|
methods: ['GET', 'POST'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
io.on('connection', (socket: ServerSocket) => {
|
||||||
|
console.log(`User connected: ${socket.id}`);
|
||||||
|
|
||||||
|
// Send recent messages to new user
|
||||||
|
socket.emit('load-messages', messages);
|
||||||
|
|
||||||
|
// Handle incoming messages
|
||||||
|
socket.on('send-message', (data: { username: string; message: string }) => {
|
||||||
|
const { username, message } = data;
|
||||||
|
|
||||||
|
if (!username || !message || message.length > 500) {
|
||||||
|
socket.emit('error', 'Invalid message');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newMessage: Message = {
|
||||||
|
id: Math.random().toString(36).substring(7),
|
||||||
|
username,
|
||||||
|
message,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
messages.push(newMessage);
|
||||||
|
if (messages.length > maxMessages) {
|
||||||
|
messages = messages.slice(-maxMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast to all connected users
|
||||||
|
io.emit('new-message', newMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle user disconnect
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
console.log(`User disconnected: ${socket.id}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
|
||||||
|
// To use this:
|
||||||
|
// 1. Install: npm install socket.io
|
||||||
|
// 2. Create next.config.ts with WebSocket support
|
||||||
|
// 3. Create a WebSocket server in pages/api/socket.ts
|
||||||
|
// 4. In client, use socket.io-client to connect
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
"name": "aethex-live",
|
"name": "aethex-live",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.9.0"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
|
|
|
||||||
14
railway.json
Normal file
14
railway.json
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://railway.app/schema.json",
|
||||||
|
"build": {
|
||||||
|
"builder": "nixpacks"
|
||||||
|
},
|
||||||
|
"deploy": {
|
||||||
|
"startCommand": "npm start",
|
||||||
|
"restartPolicyType": "on_failure",
|
||||||
|
"restartPolicyMaxRetries": 3,
|
||||||
|
"numReplicas": 1,
|
||||||
|
"healthcheckPath": "/",
|
||||||
|
"healthcheckTimeout": 30
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue