⚠️ NOTE: This document covers custom script-based ephemeral environments.For standard pull request workflows, Railway now offers a native PR Environments feature that is simpler and recommended:
- See Railway Native PR Environments Guide for the recommended approach
- See Comparison Guide to understand the differences
This custom approach is maintained for:
- GitHub Copilot session environments
- Custom environment naming requirements
- Non-PR triggered deployments
- Advanced deployment strategies
This document describes the custom script-based ephemeral environment system for testing pull requests and GitHub Copilot sessions using Railway deployments.
The Yoto Smart Stream project supports ephemeral environments for:
- Pull Request (PR) Environments - Now handled by Railway's native feature (see note above)
- GitHub Copilot Session Environments - Custom script-based (this document)
These custom environments are:
- Ephemeral - Created on-demand via scripts and destroyed when no longer needed
- Isolated - Each environment has its own resources and configuration
- Cost-Effective - Resources are released immediately after use
- Flexible - Supports custom naming and non-PR workflows
┌─────────────────────────────────────────────────────────────┐
│ Railway Project │
│ (yoto-smart-stream) │
├─────────────────────────────────────────────────────────────┤
│ │
│ Long-lived Environments: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Production (main branch) │ │
│ │ - Always running │ │
│ │ - Full resources │ │
│ │ - Customer-facing │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Staging (develop branch) │ │
│ │ - Always running │ │
│ │ - Testing environment │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Ephemeral Environments (Auto-created/destroyed): │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ PR Environments (pr-123, pr-124, ...) │ │
│ │ - Created: On PR open │ │
│ │ - Destroyed: On PR close/merge │ │
│ │ - Minimal resources │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Copilot Environments (copilot-*, ...) │ │
│ │ - Created: On copilot branch push │ │
│ │ - Destroyed: On branch delete │ │
│ │ - Testing & development │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
When you open a pull request:
- GitHub Actions triggers - Detects PR creation
- Tests run - Linting, formatting, unit tests
- Environment created - Railway environment named
pr-{number} - Deployment - Application deployed to Railway
- Configuration - Environment variables set automatically
- Notification - PR comment with deployment URL
- Available for testing - Environment accessible via URL
When PR is closed or merged:
- GitHub Actions triggers - Detects PR closure
- Environment destroyed - Railway stops all services
- Resources released - All costs eliminated
- Notification - PR comment confirming cleanup
.github/workflows/railway-pr-environments.yml
- Pattern:
pr-{number} - Examples:
pr-123,pr-456
Via Railway Dashboard:
# Open Railway dashboard
railway open -e pr-123Via Direct URL:
https://yoto-smart-stream-pr-123.up.railway.app
Health Check:
curl https://yoto-smart-stream-pr-123.up.railway.app/healthEach PR environment automatically receives:
RAILWAY_ENVIRONMENT_NAME=pr-123 # Automatically set by Railway
DEBUG=true
LOG_LEVEL=debug
PR_NUMBER=123
PR_TITLE="Add new feature"
GIT_SHA=abc123def456
YOTO_CLIENT_ID={synced from GitHub Secrets}When Copilot creates a branch starting with copilot/:
- Push detected - GitHub Actions triggers on branch push
- Environment name generated - From branch name (e.g.,
copilot-feature-name) - Deployment - Application deployed to Railway
- Configuration - Environment variables set for testing
- Ready for use - Environment accessible for Copilot testing
When Copilot branch is deleted:
- Delete detected - GitHub Actions triggers on branch deletion
- Environment destroyed - Railway cleanup initiated
- Resources released - All costs eliminated
.github/workflows/railway-copilot-environments.yml
- Pattern:
copilot-{branch-name-normalized} - Examples:
- Branch
copilot/add-auth→ Environmentcopilot-add-auth - Branch
copilot/fix-bug-123→ Environmentcopilot-fix-bug-123
- Branch
You can also manually manage Copilot environments:
Via GitHub Actions UI:
- Go to Actions tab
- Select "Railway Copilot Session Environments"
- Click "Run workflow"
- Choose action:
deploy,test,status, ordestroy - Enter session ID
Via Script:
# From devcontainer or Codespaces
./scripts/railway_ephemeral_env.sh deploy copilot-my-session
./scripts/railway_ephemeral_env.sh test copilot-my-session
./scripts/railway_ephemeral_env.sh status copilot-my-session
./scripts/railway_ephemeral_env.sh destroy copilot-my-sessionEach Copilot environment automatically receives:
RAILWAY_ENVIRONMENT_NAME=copilot-feature-name # Automatically set by Railway
DEBUG=true
LOG_LEVEL=debug
SESSION_TYPE=copilot
BRANCH_NAME=copilot/feature-name
GIT_SHA=abc123def456
YOTO_CLIENT_ID={synced from GitHub Secrets}Configure these secrets in your GitHub repository:
Settings → Secrets and variables → Actions → New repository secret
Required secrets:
RAILWAY_TOKEN - Railway API token for deployments
YOTO_CLIENT_ID - Yoto API client ID (for testing)
To get RAILWAY_TOKEN:
- Go to https://railway.app/account/tokens
- Click "Create Token"
- Copy token and add to GitHub Secrets
For Copilot sessions in GitHub Codespaces to access Railway:
User Settings → Codespaces → Secrets → New secret
Add:
Name: RAILWAY_TOKEN
Value: {your Railway API token}
Repository access: {select this repository}
This allows Copilot sessions running in Codespaces to deploy and manage Railway environments directly.
Enable PR Deployments in Railway Dashboard:
- Go to Railway project settings
- Navigate to GitHub section
- Enable "PR Deploys"
- Check "Create ephemeral environment for each PR"
- Check "Auto-destroy on PR close/merge"
- Set Environment template: Use
stagingas base
The script scripts/railway_ephemeral_env.sh provides a CLI for managing environments.
# Create environment (optional, usually auto-created)
./scripts/railway_ephemeral_env.sh create pr-123
# Deploy to environment
./scripts/railway_ephemeral_env.sh deploy pr-123
# Test environment
./scripts/railway_ephemeral_env.sh test pr-123
# Check status
./scripts/railway_ephemeral_env.sh status pr-123
# Destroy environment
./scripts/railway_ephemeral_env.sh destroy pr-123
# Show help
./scripts/railway_ephemeral_env.sh helpThe script uses these environment variables:
RAILWAY_TOKEN # Railway API token (required for CI/CD)
YOTO_CLIENT_ID # Yoto API credentials (synced to Railway)For local development:
railway loginFor CI/CD (GitHub Actions):
export RAILWAY_TOKEN="your_token"For GitHub Codespaces:
- Set
RAILWAY_TOKENas a Codespace secret (user level) - Available automatically in all Codespaces
- Open PR - Environment auto-deploys
- Review PR comment - Contains deployment URL
- Wait 1-2 minutes - For deployment to complete
- Test your changes - Using the provided URL
- Check logs - Via Railway dashboard if needed
- Merge/Close PR - Environment auto-destroys
- Open PR page - View deployment comment
- Click deployment URL - Test the changes
- Verify functionality - Check health endpoint, test APIs
- Review logs - If issues found
- Approve/Request changes - Based on testing
Ephemeral environments are designed to minimize costs:
PR Environments:
- RAM: 512 MB (web service)
- CPU: 0.5 vCPU
- Storage: 1 GB (ephemeral PostgreSQL)
- Uptime: Only during PR lifecycle
Copilot Environments:
- RAM: 512 MB (web service)
- CPU: 0.5 vCPU
- Storage: 1 GB (if needed)
- Uptime: Only during development session
- PR environments: Destroyed on PR close/merge
- Copilot environments: Destroyed on branch delete
- No manual cleanup required
- Zero cost when not in use
Via Railway Dashboard:
- Go to Project Settings
- Click Usage
- Review Current Month usage
- Set up Billing Alerts
Via CLI:
railway status # Check resource usage
railway logs # Monitor activityCheck GitHub Actions logs:
- Go to Actions tab
- Click on failed workflow run
- Review deployment step logs
Check Railway logs:
railway logs -e pr-123 --tail 100Common issues:
- RAILWAY_TOKEN not set or invalid
- Build errors (check dependencies)
- Resource limits exceeded
- Railway service quota reached
Wait for deployment:
# Deployments take 1-2 minutes
railway status -e pr-123Check health endpoint:
curl https://yoto-smart-stream-pr-123.up.railway.app/healthView recent logs:
railway logs -e pr-123 --tail 50Manual cleanup:
./scripts/railway_ephemeral_env.sh destroy pr-123Or via Railway Dashboard:
- Go to project
- Select environment
- Click Delete Environment
Verify secret is set:
- Go to User Settings → Codespaces → Secrets
- Verify
RAILWAY_TOKENis listed - Check repository access is granted
Test in Codespace:
echo $RAILWAY_TOKEN # Should show token (or part of it)
railway whoami # Should show authenticated user✅ DO:
- Open PRs early to get automatic environments
- Test changes in PR environment before requesting review
- Use PR environment URL in PR description
- Close PRs when done to free resources
- Check logs if deployment fails
❌ DON'T:
- Leave PRs open indefinitely
- Try to use PR environments for production testing
- Share PR environment URLs with customers
- Store production data in PR environments
✅ DO:
- Use Copilot environments for AI-assisted development
- Set RAILWAY_TOKEN in Codespaces secrets
- Delete branches when session complete
- Use manual workflow triggers for control
❌ DON'T:
- Leave copilot branches indefinitely
- Use copilot environments for production testing
- Share copilot credentials
- GitHub Secrets - Secure storage for RAILWAY_TOKEN, YOTO_CLIENT_ID
- Railway Variables - Synced automatically, never exposed in logs
- Codespaces Secrets - User-level, not repository-level
- PR environments: Public URLs (treat as development)
- Copilot environments: Public URLs (treat as development)
- Production: Separate environment, different credentials
- Never use production data in PR/Copilot environments
- Use test data only
- Ephemeral databases - data lost on cleanup
- No backups for ephemeral environments
Via Railway Dashboard:
- View all active environments
- Check resource usage
- Monitor costs
Via CLI:
railway list # List all projects
railway status # Show current environment
railway status -e pr-123 # Show specific environmentReal-time logs:
railway logs -e pr-123 --followFiltered logs:
railway logs -e pr-123 --filter "ERROR"
railway logs -e pr-123 --filter "health"- Railway Documentation: https://docs.railway.app/
- Railway CLI Reference: https://docs.railway.app/reference/cli
- Railway Discord: https://discord.gg/railway
- GitHub Actions Docs: https://docs.github.com/en/actions
For Railway issues:
- Check Railway status: https://status.railway.app/
- Search Railway docs
- Ask in Railway Discord
For workflow issues:
- Check GitHub Actions logs
- Review this documentation
- Check script output
If you were manually deploying to Railway:
- Add RAILWAY_TOKEN to GitHub Secrets
- Workflows will handle deployments automatically
- No need to run
railway upmanually for PRs - Continue using CLI for production deployments
When modifying workflows:
- Test changes in a PR first
- Use
workflow_dispatchfor manual testing - Review Actions logs carefully
- Update documentation as needed
Q: How long does a PR environment take to deploy?
A: Typically 1-2 minutes from PR creation.
Q: What happens if I forget to close a PR?
A: The environment stays running and incurs costs. Close PRs promptly.
Q: Can I access PR environment from my local machine?
A: Yes, use the public URL provided in the PR comment.
Q: How do I get Railway token for Codespaces?
A: Create a token at https://railway.app/account/tokens and add to Codespaces secrets.
Q: Are PR environments secure?
A: They use public URLs. Don't use production data or credentials.
Q: How much do ephemeral environments cost?
A: Minimal - only ~$0.01-0.05 per hour per environment, auto-destroyed when done.
Q: Can I customize the environment configuration?
A: Yes, modify the workflow files or script as needed.
Q: What if deployment fails?
A: Check GitHub Actions logs and Railway logs for error details.
Q: Can I manually create an environment?
A: Yes, use the script: ./scripts/railway_ephemeral_env.sh create my-env
Last Updated: 2026-01-10
Version: 1.0.0