Skip to content

Iterative Development

Learn how to use on-demand environments for safe, efficient development and testing workflows before promoting changes to your default environment.


Overview

Iterative development on Airbase means:

  1. Deploy to on-demand environments - Test changes in isolated environments (e.g., staging, development)
  2. Verify functionality - Test thoroughly without affecting your stable deployment
  3. Promote to default environment - Deploy tested changes confidently

Key benefit: Catch issues before they reach your default (stable) environment.

About Default Environments

Your default environment is the primary deployment for your project. While this is often your "production" environment, it serves as your stable, main deployment regardless of your actual production setup.


Quick Reference

# Standard iterative workflow
airbase container build
airbase container deploy --yes staging   # Test in on-demand environment
airbase container deploy --yes           # Promote to default environment

Why Use On-Demand Environments?

Problems On-Demand Environments Solve

โŒ Without on-demand environments: - Bugs reach your stable deployment - No safe testing environment - Rollback is the only option - High-risk deployments

โœ… With on-demand environments: - Test changes in isolated environments - Catch bugs early - Deploy with confidence - Easy iteration and experimentation

When to Use On-Demand Environments

Always create on-demand environments for: - New features - Bug fixes - Dependency updates - Configuration changes - Infrastructure changes

Can skip on-demand environments for: - Typo fixes in documentation - Non-functional copy changes - Already tested hotfixes (rare)


Basic Iterative Workflow

Step 1: Make Changes

Edit your code:

# Example: Add new API endpoint
vim src/api/users.js

Step 2: Build

Build your container:

airbase container build

Expected output:

Building container...
[+] Building 32.1s (12/12) FINISHED
โœ“ Build complete
โœ“ Image pushed to registry

Step 3: Deploy to On-Demand Environment

Deploy to an on-demand environment (e.g., staging):

airbase container deploy --yes staging

Expected output:

Deploying to staging environment...
โœ“ Deployment successful
โœ“ Application is live at: https://staging--myproject.app.tc1.airbase.sg

Step 4: Test Your Changes

Test your changes at the environment URL:

# Open in browser
open https://staging--myproject.app.tc1.airbase.sg

# Or test with curl
curl https://staging--myproject.app.tc1.airbase.sg/api/users

Test checklist: - [ ] New feature works as expected - [ ] Existing features still work - [ ] No console errors (check browser dev tools) - [ ] No CSP violations - [ ] API endpoints respond correctly - [ ] Database connections work - [ ] Environment variables loaded correctly

Step 5: If Issues Found

Fix and repeat:

# Make fixes
vim src/api/users.js

# Rebuild and redeploy to on-demand environment
airbase container build
airbase container deploy --yes staging

# Test again

Iterate until everything works perfectly.

Step 6: Promote to Default Environment

When your tests pass:

airbase container deploy --yes

No rebuild needed - deploys same image that passed your tests.


Complete Workflow Example

Scenario: Adding User Profile Feature

Initial state: Default environment is stable, need to add user profiles.

Step 1: Create feature branch (optional)

git checkout -b feature/user-profiles

Step 2: Develop locally

# Make changes
vim src/components/UserProfile.jsx
vim src/api/profile.js

# Test locally
npm start
# Test at http://localhost:3000

Step 3: Deploy to on-demand environment

# Build and deploy to staging (on-demand environment)
airbase container build
airbase container deploy --yes staging

Environment URL: https://staging--myproject.app.tc1.airbase.sg

Step 4: Test your changes

# Test user profile page
open https://staging--myproject.app.tc1.airbase.sg/profile

# Test API
curl https://staging--myproject.app.tc1.airbase.sg/api/profile/123

Discovered issues: - โŒ Profile image not displaying - โŒ API returns 500 error for missing users

Step 5: Fix issues

# Fix image path
vim src/components/UserProfile.jsx

# Fix error handling
vim src/api/profile.js

# Rebuild and redeploy to on-demand environment
airbase container build
airbase container deploy --yes staging

Step 6: Retest

# Test again
open https://staging--myproject.app.tc1.airbase.sg/profile

Results: - โœ… Profile image displays correctly - โœ… API handles missing users gracefully - โœ… No console errors - โœ… All existing features still work

Step 7: Promote to default environment

# Same image that passed your tests
airbase container deploy --yes

Default environment URL: https://myproject.app.tc1.airbase.sg

Step 8: Verify deployment

# Quick smoke test
curl https://myproject.app.tc1.airbase.sg/api/profile/123

โœ… Success! User profile feature is live.

Step 9: Clean up (optional)

# Remove staging deployment to free resources
airbase container destroy --yes staging

# Merge feature branch
git checkout main
git merge feature/user-profiles
git push

Multi-Environment Workflow

Three-Stage Pipeline

Environments: 1. Development (on-demand) - Active development and experimentation 2. Staging (on-demand) - Pre-release testing 3. Default (stable) - Your main stable deployment

Workflow:

# Step 1: Deploy to development environment
airbase container build
airbase container deploy --yes development

# Step 2: Test in development
# Quick sanity checks

# Step 3: Deploy to staging environment
airbase container deploy --yes staging

# Step 4: Test in staging
# Thorough testing, QA review

# Step 5: Promote to default environment
airbase container deploy --yes

Environment URLs: - Development: https://development--myproject.app.tc1.airbase.sg - Staging: https://staging--myproject.app.tc1.airbase.sg - Default: https://myproject.app.tc1.airbase.sg

When to Use Each Environment

Development (on-demand): - Experimental features - Breaking changes - Integration work - Team demos

Staging (on-demand): - Final testing before promotion - QA review - Stakeholder approval - Performance testing

Default (stable): - Live application - End users only - Stable, tested code only


Environment-Specific Configuration

Using Different .env Files

Create environment-specific configuration:

project-root/
โ”œโ”€โ”€ .env                 # Production config
โ”œโ”€โ”€ .env.staging         # Staging config
โ”œโ”€โ”€ .env.development     # Development config
โ””โ”€โ”€ airbase.json

.env (production):

PORT=3000
DATABASE_URL=postgresql://prod-db.company.com/myapp
API_KEY=prod-key-abc123
NODE_ENV=production
LOG_LEVEL=error

.env.staging:

PORT=3000
DATABASE_URL=postgresql://staging-db.company.com/myapp
API_KEY=staging-key-xyz789
NODE_ENV=staging
LOG_LEVEL=debug

.env.development:

PORT=3000
DATABASE_URL=postgresql://dev-db.company.com/myapp
API_KEY=dev-key-test456
NODE_ENV=development
LOG_LEVEL=debug
ENABLE_DEBUG_TOOLS=true

Deployment automatically uses the correct .env file:

# Uses .env.staging
airbase container deploy --yes staging

# Uses .env (production)
airbase container deploy --yes

Testing Strategies

Manual Testing Checklist

Functional testing: - [ ] New features work as expected - [ ] Edge cases handled - [ ] Error messages are clear - [ ] Forms validate correctly - [ ] API responses are correct

Regression testing: - [ ] Existing features still work - [ ] Navigation works - [ ] Authentication works - [ ] Data persistence works

Security testing: - [ ] No CSP violations in console - [ ] No exposed secrets - [ ] Authentication required where needed - [ ] Input validation working

Performance testing: - [ ] Page loads reasonably fast - [ ] No memory leaks - [ ] API responses are timely

Automated Testing

Run tests before deploying:

# Run unit tests
npm test

# Run integration tests
npm run test:integration

# Run e2e tests against staging
STAGING_URL=https://staging--myproject.app.tc1.airbase.sg npm run test:e2e

Example e2e test (Playwright):

// tests/e2e/user-profile.spec.js
const { test, expect } = require('@playwright/test');

test('user profile displays correctly', async ({ page }) => {
  // Test against staging
  await page.goto('https://staging--myproject.app.tc1.airbase.sg/profile');

  // Check profile loads
  await expect(page.locator('.profile-name')).toBeVisible();
  await expect(page.locator('.profile-image')).toBeVisible();

  // Check no CSP errors
  const errors = [];
  page.on('console', msg => {
    if (msg.type() === 'error') errors.push(msg.text());
  });

  await page.reload();
  expect(errors.filter(e => e.includes('Content Security Policy'))).toHaveLength(0);
});

Common Workflows

Workflow 1: Quick Bug Fix

# Fix bug in code
vim src/api/users.js

# Test in staging
airbase container build
airbase container deploy --yes staging

# Verify fix works
curl https://staging--myproject.app.tc1.airbase.sg/api/users

# Deploy to production
airbase container deploy --yes

Time: 5-10 minutes

Workflow 2: New Feature Development

# Develop feature
# ... multiple code changes ...

# Deploy to dev for team review
airbase container build
airbase container deploy --yes development

# After team review, deploy to staging
airbase container deploy --yes staging

# Thorough testing in staging
# ... test all scenarios ...

# Deploy to production
airbase container deploy --yes

Time: Days to weeks (multiple iterations)

Workflow 3: Dependency Update

# Update dependencies
npm update

# Check for breaking changes
npm test

# Deploy to staging
airbase container build
airbase container deploy --yes staging

# Test all features work
# ... comprehensive testing ...

# Deploy to production
airbase container deploy --yes

Time: 30 minutes - 2 hours

Workflow 4: Configuration Change

# Update .env.staging
vim .env.staging

# Redeploy to staging (no rebuild needed)
airbase container deploy --yes staging

# Verify new config works
curl https://staging--myproject.app.tc1.airbase.sg/health

# Update .env (production)
vim .env

# Deploy to production
airbase container deploy --yes

Time: 5 minutes


Team Collaboration

Parallel Feature Development

Scenario: 3 developers working on different features.

Developer A (Auth feature):

git checkout -b feature/auth
# ... develop auth ...
airbase container build
airbase container deploy --yes feature-auth

URL: https://feature-auth--myproject.app.tc1.airbase.sg

Developer B (Payments feature):

git checkout -b feature/payments
# ... develop payments ...
airbase container build
airbase container deploy --yes feature-payments

URL: https://feature-payments--myproject.app.tc1.airbase.sg

Developer C (Dashboard feature):

git checkout -b feature/dashboard
# ... develop dashboard ...
airbase container build
airbase container deploy --yes feature-dashboard

URL: https://feature-dashboard--myproject.app.tc1.airbase.sg

Integration:

After individual testing, merge to main and deploy to staging:

git checkout main
git merge feature/auth
git merge feature/payments
git merge feature/dashboard

airbase container build
airbase container deploy --yes staging

Integration testing in staging before production.

Code Review Workflow

# Create PR environment
git checkout feature/new-feature
airbase container build
airbase container deploy --yes pr-123

# Share URL in PR
# URL: https://pr-123--myproject.app.tc1.airbase.sg

# Reviewers can test live
# After approval, deploy to staging
airbase container deploy --yes staging

# After staging tests pass, deploy to production
airbase container deploy --yes

# Clean up PR environment
airbase container destroy --yes pr-123

Rollback Strategy

If Production Deployment Fails

Scenario: Just deployed to production, discovered critical bug.

Option 1: Quick rollback (redeploy last good version)

# Checkout last good commit
git checkout HEAD~1

# Rebuild and deploy
airbase container build
airbase container deploy --yes

# Production now running last good version

Option 2: Fix forward (if fix is simple)

# Make quick fix
vim src/api/users.js

# Test in staging first
airbase container build
airbase container deploy --yes staging

# Verify fix
curl https://staging--myproject.app.tc1.airbase.sg

# Deploy fix to production
airbase container deploy --yes

Option 3: Revert commit and redeploy

# Revert problematic commit
git revert HEAD

# Rebuild and deploy
airbase container build
airbase container deploy --yes

Best Practices

โœ… Do

  • Always test in on-demand environments before promoting to default
  • Test thoroughly - don't rush deployments
  • Use environment-specific .env files
  • Keep environments in sync (same code, different config)
  • Clean up on-demand environments after merging
  • Document testing checklist for your team
  • Automate testing when possible
  • Use consistent environment naming

โŒ Don't

  • Don't skip testing environments for "small changes"
  • Don't deploy directly to default without testing
  • Don't use default environment credentials in on-demand environments
  • Don't leave on-demand environments running indefinitely
  • Don't test with production data in on-demand environments
  • Don't assume - verify everything works

Troubleshooting

Issue: Changes Not Visible in Staging

Possible causes:

  1. Forgot to rebuild
# Solution: Rebuild first
airbase container build
airbase container deploy --yes staging
  1. Browser cache
# Solution: Hard refresh (Cmd+Shift+R or Ctrl+Shift+R)
  1. Deployed wrong image
# Solution: Verify build, then redeploy
airbase container build
airbase container deploy --yes staging

Issue: Staging Works But Production Fails

Possible causes:

  1. Different environment variables
# Solution: Check .env vs .env.staging
diff .env .env.staging
  1. Different database
# Solution: Check DATABASE_URL in each .env file
  1. Permissions issue
# Solution: Verify production credentials

Issue: Can't Remember Which Environments Are Running

Solution: Check Airbase Console web interface for list of deployments.


Next Steps


Summary

Iterative development workflow:

  1. โœ๏ธ Make changes locally
  2. ๐Ÿ”จ Build: airbase container build
  3. ๐Ÿงช Test in on-demand environment: airbase container deploy --yes staging
  4. ๐Ÿ” Verify thoroughly at environment URL
  5. ๐Ÿ” Fix and repeat until perfect
  6. ๐Ÿš€ Promote to default environment: airbase container deploy --yes

Key principle: Always test in on-demand environments before promoting to your default environment.

This approach catches bugs early, reduces stress, and keeps your stable deployment reliable.