Preview Environment Lifecycle #
This guide explains the complete lifecycle of a Preview Environment, from creation to deletion, including automatic management and manual controls.
Lifecycle Stages #
┌───────────────────────────────────────────────────────────────┐
│ Stage 1: Creation │
│ Trigger: 'preview' label added to PR │
│ Duration: ~40 minutes │
│ Status: Building → Running → Healthy │
└───────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────┐
│ Stage 2: Active Use │
│ Duration: While PR is open │
│ Status: Running + Healthy │
│ Features: Auto-updates on push, persistent data │
└───────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────┐
│ Stage 3: Updates │
│ Trigger: New commits pushed to PR branch │
│ Duration: ~10 minutes per update │
│ Status: Restarting → Running → Healthy │
└───────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────┐
│ Stage 4: Auto-Stop (optional) │
│ Trigger: 30 hours of inactivity │
│ Status: Stopped │
│ Note: Can be manually restarted │
└───────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────┐
│ Stage 5: Cleanup │
│ Trigger: PR closed or merged │
│ Duration: ~2 minutes │
│ Status: Deleting → Deleted │
└───────────────────────────────────────────────────────────────┘
Automatic Management #
Auto-Creation #
When it happens:
- When you add the
previewlabel to a PR targetingmain
What happens automatically:
- GitHub Actions workflow triggered
- Coder workspace provisioned
- EC2 instance created
- System and tools installed
- Repository cloned from PR branch
- Services built and started
- Comment posted to PR with URLs
Timeline:
- Initial provisioning: 5-10 minutes
- System setup: 10-15 minutes
- Application build: 20-25 minutes
- Service startup: 5 minutes
- Total: ~40 minutes
Auto-Updates #
When it happens:
- When you push new commits to the PR branch
- Only if PR has the
previewlabel
What happens automatically:
- GitHub Actions detects new commits
- Coder workspace restarted
- Latest code pulled from branch
- Modified services rebuilt
- Services restarted with new code
- Comment posted to PR confirming update
Timeline:
- Pull latest code: 1-2 minutes
- Rebuild services: 5-7 minutes
- Service restart: 2-3 minutes
- Total: ~10 minutes
Data Persistence:
- ✅ Database data preserved
- ✅ File uploads preserved
- ✅ Environment variables preserved
- ❌ In-memory data cleared
- ❌ Active sessions ended
Auto-Stop #
When it happens:
- After 30 hours of workspace inactivity
- Inactivity = no active SSH sessions, no HTTP requests
What happens automatically:
- Workspace transitions to “Stopped” state
- All services shut down gracefully
- EC2 instance stopped (not terminated)
- Data preserved on disk
Cost Savings:
- Stopped workspaces only pay for storage (~$0.05/hour)
- Running workspaces cost ~$0.15/hour
- Can save ~$0.10/hour when stopped
Restarting:
# Via Coder Dashboard
Coder Dashboard → Workspace → Click "Start"
# Services start automatically
# Ready to use in ~2-3 minutes
Auto-Cleanup #
When it happens:
- Immediately when PR is closed (merged or not)
- Triggered by GitHub Actions
What happens automatically:
- GitHub Actions detects PR closed event
- Coder workspace deleted via API
- EC2 instance terminated
- All data permanently deleted
- Comment posted to PR confirming cleanup
Timeline:
- Workspace deletion: 1-2 minutes
- Resource cleanup: Immediate
- Total: ~2 minutes
What gets deleted:
- ❌ EC2 instance (terminated)
- ❌ All workspace data
- ❌ Database data
- ❌ File uploads
- ❌ Logs and history
- ✅ PR comments preserved (in GitHub)
Manual Controls #
Starting a Stopped Workspace #
Via Coder Dashboard:
1. Go to https://coder.internal.gotofu.com/workspaces
2. Find workspace: coder-preview-{PR-number}
3. Click "Start" button
4. Wait 2-3 minutes for services to start
Via Coder CLI:
# Install Coder CLI if needed
brew install coder/coder/coder
# Configure CLI
coder login https://coder.internal.gotofu.com
# Start workspace
coder start coder-preview-{PR-number}
Stopping a Running Workspace #
Why you might want to:
- Save costs during non-working hours
- Preserve environment state without deleting
- Troubleshoot by forcing clean restart
Via Coder Dashboard:
1. Go to workspace page
2. Click "Stop" button
3. Confirm action
4. Wait ~1 minute for graceful shutdown
Via Coder CLI:
coder stop coder-preview-{PR-number}
Note: Stopping is rarely needed as auto-stop handles this automatically.
Restarting a Running Workspace #
Why you might want to:
- Force rebuild with latest code
- Clear all in-memory state
- Recover from service crashes
- Apply configuration changes
Via Coder Dashboard:
1. Go to workspace page
2. Click "Restart" button
3. Wait ~10 minutes for rebuild
Via Coder CLI:
coder restart coder-preview-{PR-number} --yes
What happens:
- All services stopped
- Latest code pulled from branch
- Modified services rebuilt
- All services restarted
- Data preserved on disk
Manual Deletion #
When to use:
- You want to delete before PR is closed
- Environment has issues and needs recreation
- Testing cleanup process
Via Removing Label:
1. Go to PR on GitHub
2. Remove 'preview' label
3. Close PR (if done with it)
4. Workspace automatically deleted
Via Coder Dashboard (Admin only):
1. Go to workspace page
2. Click "Delete" in settings
3. Confirm deletion
4. Workspace permanently deleted
Note: Standard workflow is to let auto-cleanup handle deletion when PR closes.
Data Management #
What Persists Between Updates #
Preserved across restarts:
- ✅ Database data (PostgreSQL)
- ✅ File uploads (LocalStack S3)
- ✅ Redis data
- ✅ RabbitMQ queues
- ✅ Git repository state
- ✅ Environment configuration
Lost on restart:
- ❌ In-memory cache
- ❌ Active user sessions
- ❌ Running background jobs
- ❌ Temporary files in /tmp
- ❌ Process state
Backing Up Important Data #
If you have important test data:
# Backup database
docker exec database pg_dump -U postgres bonsai > preview-backup.sql
# Backup files from LocalStack
docker exec bonsai-localstack aws s3 sync s3://assets ./backup-assets --endpoint-url=http://localhost:4566
# Download backups
# Via Coder web terminal or SCP
Note: Backups should be saved outside the workspace if you need them after cleanup.
Restoring Data #
# Restore database
cat preview-backup.sql | docker exec -i database psql -U postgres bonsai
# Restore files to LocalStack
docker exec bonsai-localstack aws s3 sync ./backup-assets s3://assets --endpoint-url=http://localhost:4566
Cleaning Up Test Data #
To start fresh without full rebuild:
# Connect to workspace terminal
# Clear database (but keep schema)
docker exec database psql -U postgres bonsai -c "TRUNCATE TABLE users, organizations, invoices CASCADE;"
# Clear Redis
docker exec bonsai-redis redis-cli FLUSHALL
# Clear RabbitMQ queues
docker exec bonsai-rabbitmq rabbitmqctl purge_queue <queue-name>
# Clear LocalStack S3
docker exec bonsai-localstack aws s3 rm s3://assets --recursive --endpoint-url=http://localhost:4566
Cost Management #
Understanding Costs #
Running Workspace:
- EC2 t3.2xlarge: ~$0.13/hour
- EBS storage (500GB): ~$0.02/hour
- Total: ~$0.15/hour
Stopped Workspace:
- EC2 stopped: $0.00/hour
- EBS storage: ~$0.02/hour (still charged)
- Total: ~$0.02/hour
Monthly estimates:
- Running 8 hours/day, 5 days/week: ~$24/month
- Running 24/7: ~$108/month
- Stopped when not in use: ~$7/month for storage
Best Practices for Cost Savings #
-
Rely on Auto-Stop
- Configured for 30 hours of inactivity
- Automatically stops when not in use
- No action needed from you
-
Close PRs When Done
- Triggers automatic cleanup
- Deletes all resources
- Zero cost after deletion
-
Share Environments
- Multiple team members can use same preview
- Avoid creating duplicate environments
- Coordinate with your team
-
Manual Stop for Long Breaks
# Stop workspace before weekend/vacation Coder Dashboard → Workspace → Stop # Restart when you return Coder Dashboard → Workspace → Start -
Delete Unused Previews
# If you're done testing but PR still open # Option 1: Remove 'preview' label # Option 2: Close the PR
Monitoring Workspace Health #
Via Coder Dashboard #
Go to: https://coder.internal.gotofu.com/workspaces
Health indicators:
- 🟢 Green dot = Healthy + Running
- 🟡 Yellow dot = Starting or Stopping
- 🔴 Red dot = Unhealthy or Failed
- ⚫ Gray dot = Stopped
Build status:
- "Running" = Active and accessible
- "Failed" = Build errors (check logs)
- "Stopped" = Manually stopped or auto-stopped
Via GitHub Actions #
Go to: PR → Actions tab → "Preview Environment" workflow
Status indicators:
- ✅ Green checkmark = Success
- 🟡 Yellow dot = In progress
- ❌ Red X = Failed
- ⚪ Gray = Queued or canceled
Health Check Commands #
# Connect to workspace terminal
# Check all services
docker compose -f docker-compose.preview.yml ps
# Verify critical services are healthy
docker compose -f docker-compose.preview.yml ps | grep -E "(database|rabbitmq|redis|bonsapi|webapp)"
# Check resource usage
docker stats --no-stream
# Check disk space
df -h
# Check memory
free -h
Troubleshooting Lifecycle Issues #
Environment Stuck in “Building” State #
Symptoms:
- Workspace shows “Building” for >60 minutes
- No progress in build logs
Solutions:
- Check GitHub Actions logs for errors
- Check Coder build logs for stuck processes
- Cancel build and restart workspace
- If persists, delete and recreate
Auto-Update Not Triggering #
Symptoms:
- Pushed commits but environment doesn’t rebuild
- Old code still running after 15+ minutes
Check:
- PR still has
previewlabel - GitHub Actions workflow triggered
- Workspace is running (not stopped)
Solutions:
- Manually restart workspace
- Remove and re-add
previewlabel - Check GitHub Actions logs for errors
Auto-Stop Happening Too Soon #
Symptoms:
- Workspace stops while actively using it
Explanation:
- Auto-stop timer is based on Coder agent activity
- Sometimes resets unexpectedly
Solution:
- Simply restart the workspace
- Activity will reset the timer
- If it keeps happening, report to DevOps
Cleanup Not Triggering #
Symptoms:
- PR closed but workspace still exists
- No cleanup comment posted
Check:
- GitHub Actions “cleanup” job status
- Check workflow logs for errors
Solutions:
- Wait a few minutes (can be delayed)
- Manually delete via Coder dashboard
- Contact DevOps if workspace cannot be deleted
Lifecycle Best Practices #
For Developers #
- Create Early: Add
previewlabel as soon as PR is ready for review - Test Locally First: Verify changes work before creating preview
- Monitor Build: Check that initial build succeeds
- Update Regularly: Push commits to trigger auto-updates
- Close Promptly: Close PR when done to trigger cleanup
For QA Engineers #
- Wait for Ready: Don’t start testing until “Ready” comment posted
- Document Findings: Add comments to PR with test results
- Report Issues: Use GitHub issues or PR comments for bugs
- Verify Updates: Re-test after developer pushes fixes
- Sign Off: Approve PR or request changes
For Product Managers #
- Schedule Reviews: Coordinate timing with developers
- Plan Demos: Account for 40-minute initial setup time
- Share Feedback: Comment directly on PR
- Request Changes: Be specific about what needs adjustment
- Approve When Ready: Give explicit approval for merge
FAQ #
Q: Can I have multiple preview environments? #
A: Yes! Each PR gets its own independent environment:
- PR #123 →
coder-preview-123 - PR #124 →
coder-preview-124 - Both can run simultaneously
Q: What happens to data when I push updates? #
A: Database and files are preserved. Only code is updated.
- ✅ Database data kept
- ✅ Uploaded files kept
- ✅ Configuration kept
- ❌ In-memory data cleared
Q: Can I manually trigger a rebuild? #
A: Yes, via Coder dashboard:
Workspace page → Restart → Confirm
Q: How long does environment persist? #
A: Until PR is closed:
- While PR open: Indefinitely (with auto-stop after 30h inactivity)
- When PR closed: Immediately deleted
Q: Can I prevent auto-stop? #
A: No, but you can easily restart:
- Auto-stop after 30 hours is by design
- Restarting takes only 2-3 minutes
- Data is preserved when stopped
Q: What if I need environment after PR closes? #
A: Options:
- Don’t close PR yet
- Backup important data before closing
- Recreate in staging environment
- Create new PR if needed
Q: Can I share workspace with external users? #
A: No, preview environments are internal only:
- Requires company authentication
- Internal VPN access needed
- For external demos, use staging
Next Steps #
- Creating Preview Environments - Get started
- Troubleshooting - Resolve issues
- Integration Setup - Configure external services