Skip to content

Manage Environments

Learn how to create and manage multiple environments for your Airbase application.

What are Environments?

Environments are isolated instances of your application. Each environment:

  • Has its own deployment
  • Has its own URL
  • Can have different environment variables
  • Shares the same project but runs independently

Common environments:

  • Default (production): Live application for end users
  • Staging: Pre-production testing
  • Development: Development team testing
  • Feature branches: Temporary environments for specific features

Understanding Environments

For conceptual understanding, see Environments Concept.


Quick Reference

# Deploy to default environment (production)
airbase container deploy --yes

# Deploy to named environment
airbase container deploy --yes staging
airbase container deploy --yes development

# Undeploy from environment
airbase container destroy --yes staging

Environment Types

Default Environment (Production)

Also called: Production environment

URL pattern:

https://PROJECT-NAME.app.tc1.airbase.sg

Deploy command:

airbase container deploy --yes

Characteristics:

  • ⚠️ Requires --yes flag (prompt defaults to "N" for safety)
  • Intended for production use
  • Accessible to end users
  • Should be stable and tested

Named Environments

Examples: staging, development, preview, feature-auth

URL pattern:

https://ENVIRONMENT--PROJECT-NAME.app.tc1.airbase.sg

Notice the double dash (--) between environment and project name.

Deploy command:

airbase container deploy --yes staging

Characteristics:

  • Auto-defaults to "Y" in interactive mode (easier iteration)
  • Good for testing and development
  • Each named environment is completely isolated
  • Can have different environment variables

Creating Environments

Create Your First Environment

Environments are created automatically when you deploy to them.

Create a staging environment:

# Build your application
airbase container build

# Deploy to "staging" environment (creates it if it doesn't exist)
airbase container deploy --yes staging

What happens:

  1. Airbase checks if "staging" environment exists
  2. If not, creates it
  3. Deploys your application to it
  4. Provides the URL

Output:

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

Create Multiple Environments

Create as many environments as you need:

# After building once
airbase container build

# Deploy to multiple environments
airbase container deploy --yes development
airbase container deploy --yes staging
airbase container deploy --yes preview

Each gets its own URL:

  • https://development--myproject.app.tc1.airbase.sg
  • https://staging--myproject.app.tc1.airbase.sg
  • https://preview--myproject.app.tc1.airbase.sg

Environment URL Structure

URL Format

Default environment:

https://PROJECT-NAME.app.tc1.airbase.sg

Named environment:

https://ENVIRONMENT--PROJECT-NAME.app.tc1.airbase.sg

Examples

If your project handle is runtime/demo:

Environment URL
Default (production) https://demo.app.tc1.airbase.sg
staging https://staging--demo.app.tc1.airbase.sg
development https://development--demo.app.tc1.airbase.sg
feature-auth https://feature-auth--demo.app.tc1.airbase.sg

Note: Only the project name (after the slash) is used in the URL, not the team name.

See URL Patterns Reference for complete details.


Environment Variables per Environment

Each environment can have its own configuration.

Setup

Create environment-specific .env files:

.env                 # For default/production
.env.staging         # For staging
.env.development     # For development
.env.feature-auth    # For feature-auth environment

Example: Database URLs per Environment

.env (production):

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

.env.staging:

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

.env.development:

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

How It Works

When you deploy:

# Deploys with .env.staging variables
airbase container deploy --yes staging

# Deploys with .env variables (default/production)
airbase container deploy --yes

The CLI automatically:

  1. Reads the appropriate .env file
  2. Sends variables to Airbase
  3. Airbase injects them at runtime

See Set Environment Variables for complete guide.


Updating Environments

Redeploy to Existing Environment

To update an environment:

# Make code changes
# Rebuild
airbase container build

# Redeploy to environment
airbase container deploy --yes staging

The existing deployment is replaced with the new one.

Update Environment Variables Only

If you only changed environment variables (.env files), redeploy without rebuilding:

# No rebuild needed
airbase container deploy --yes staging

Airbase updates the environment variables without changing the container image.


Switching Between Environments

Deploy Same Code to Multiple Environments

Build once, deploy to many:

# Build once
airbase container build

# Deploy to all environments
airbase container deploy --yes development
airbase container deploy --yes staging
airbase container deploy --yes production

Test in Staging, Promote to Production

Standard workflow:

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

# Step 2: Test at https://staging--myproject.app.tc1.airbase.sg
# Verify everything works

# Step 3: If good, deploy to production
airbase container deploy --yes

See Iterative Development for complete workflow.


Removing Environments

Undeploy from an Environment

# Undeploy from named environment
airbase container destroy --yes staging

# Undeploy from default environment
airbase container destroy --yes

What happens:

  1. Application is removed from the environment
  2. URL becomes inaccessible
  3. Resources are freed

Note: Wait 30-60 seconds for the change to propagate.

Verify Undeployment

# Wait for propagation
sleep 60

# Try to access the URL (should fail)
curl -I https://staging--myproject.app.tc1.airbase.sg

Expected: Connection error or 404.

See Undeploy Applications for complete guide.


Environment Naming

Naming Rules

Environment names must:

  • ✅ Be lowercase
  • ✅ Use hyphens (-) for word separation
  • ✅ Be short and descriptive
  • ❌ Not contain underscores
  • ❌ Not contain special characters

Good names:

  • staging
  • development
  • preview
  • feature-auth
  • feature-user-dashboard
  • qa
  • uat

Bad names:

  • Staging (uppercase)
  • feature_auth (underscore)
  • feature/auth (special character)
  • my environment (space)

Naming Conventions

Common patterns:

Pattern Example Use Case
Stage-based development, staging, production Traditional pipeline
Feature-based feature-auth, feature-dashboard Feature branches
Purpose-based demo, qa, uat, preview Specific purposes
Team-based team-frontend, team-backend Team isolation

Choose a consistent naming convention for your team.


Common Environment Setups

Setup 1: Simple (Single Environment)

Environments:

  • Default (production)

Use when: Small projects, solo developer, simple deployments

Workflow:

airbase container build
airbase container deploy --yes

Setup 2: Two-Stage (Staging + Production)

Environments:

  • staging
  • Default (production)

Use when: Want to test before production

Workflow:

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

# Test, then promote to production
airbase container deploy --yes

Setup 3: Three-Stage Pipeline

Environments:

  • development
  • staging
  • Default (production)

Use when: Team development, formal testing process

Workflow:

# Development → Staging → Production
airbase container build
airbase container deploy --yes development

# After testing in development
airbase container deploy --yes staging

# After testing in staging
airbase container deploy --yes

Setup 4: Feature Branch Environments

Environments:

  • feature-auth
  • feature-dashboard
  • feature-payments
  • staging
  • Default (production)

Use when: Parallel feature development, multiple developers

Workflow:

# Each developer works on their feature environment
git checkout feature/auth
airbase container build
airbase container deploy --yes feature-auth

# After feature is complete, deploy to staging for integration testing
git checkout main
git merge feature/auth
airbase container build
airbase container deploy --yes staging

# After testing, deploy to production
airbase container deploy --yes

CI/CD Branch Environment Patterns

Automating environment deployments with CI/CD enables preview environments for every branch and pull request.

Pattern 1: Branch Preview Environments

Use case: Deploy every feature branch to its own preview environment for testing before merge.

GitLab CI example:

review:
  extends: .airbase-deploy
  stage: test
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  variables:
    AIRBASE_ENVIRONMENT: $CI_COMMIT_REF_SLUG
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    url: $DYNAMIC_ENVIRONMENT_URL
    on_stop: stop_review
    auto_stop_in: 1 day

stop_review:
  extends: .airbase-destroy
  stage: test
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  variables:
    AIRBASE_ENVIRONMENT: $CI_COMMIT_REF_SLUG
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    action: stop

What this does: - Creates preview environment when MR is opened - Environment name: review/feature-auth-123 - URL: https://feature-auth-123--myapp.app.tc1.airbase.sg - Auto-cleanup after 1 day - Manual cleanup when MR is closed

Pattern 2: Getting Dynamic Environment URL

Use --output flag to get the deployed URL:

airbase container deploy --yes --output deploy.env $BRANCH_NAME

Output file (deploy.env):

DYNAMIC_ENVIRONMENT_URL=https://feature-123--myapp.app.tc1.airbase.sg

Use in GitLab CI:

review:
  script:
    - airbase container build
    - airbase container deploy --yes --output deploy.env $CI_COMMIT_REF_SLUG
    - source deploy.env
    - echo "Preview URL: $DYNAMIC_ENVIRONMENT_URL"
  environment:
    url: $DYNAMIC_ENVIRONMENT_URL

This enables "View Deployment" button on merge requests!

Pattern 3: Multi-Stage Pipeline

Use case: Deploy to staging on commits, production on tags/releases.

staging:
  extends: .airbase-deploy
  stage: deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"
  variables:
    AIRBASE_ENVIRONMENT: staging
  environment:
    name: staging
    url: https://staging--myapp.app.tc1.airbase.sg

production:
  extends: .airbase-deploy
  stage: deploy
  rules:
    - if: $CI_COMMIT_TAG =~ /^v/  # Only on version tags
  variables:
    AIRBASE_ENVIRONMENT: default
  environment:
    name: production
    url: https://myapp.app.tc1.airbase.sg

Workflow: 1. Commit to develop → Auto-deploy to staging 2. Tag release (v1.0.0) → Auto-deploy to production

Pattern 4: Manual Production Gate

Use case: Require manual approval before production deployment.

staging:
  extends: .airbase-deploy
  stage: deploy
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  variables:
    AIRBASE_ENVIRONMENT: staging
  environment:
    name: staging

production:
  extends: .airbase-deploy
  stage: deploy
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual  # ← Requires manual trigger
  variables:
    AIRBASE_ENVIRONMENT: default
  environment:
    name: production

Workflow: 1. Merge to main → Auto-deploy to staging 2. Test staging manually 3. Click "Deploy to production" button in GitLab 4. Production deployed

Pattern 5: Environment Cleanup

Automatic cleanup with CI/CD:

stop_review:
  extends: .airbase-destroy
  stage: test
  rules:
    - if: $CI_MERGE_REQUEST_EVENT_TYPE == "close"
    - if: $CI_MERGE_REQUEST_EVENT_TYPE == "merge"
  variables:
    AIRBASE_ENVIRONMENT: $CI_COMMIT_REF_SLUG
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    action: stop

What this does: - Automatically destroys environment when MR is closed/merged - Frees up resources - Prevents environment sprawl

Manual cleanup:

# CLI command
airbase container destroy --yes feature-auth-123

Pattern 6: Parallel Environment Testing

Use case: Test multiple versions simultaneously.

# Deploy different branches to different environments
airbase container deploy --yes feat-auth
airbase container deploy --yes feat-payments
airbase container deploy --yes bugfix-login

# Access each for testing
https://feat-auth--myapp.app.tc1.airbase.sg
https://feat-payments--myapp.app.tc1.airbase.sg
https://bugfix-login--myapp.app.tc1.airbase.sg

CI/CD Prerequisites

Before using these patterns:

  1. Generate Airbase credentials:
  2. Go to Airbase Console
  3. Generate new credentials

  4. Add to GitLab CI/CD Variables:

  5. AIRBASE_RC (Type: File)
  6. Contains: AIRBASE_ACCESS_KEY_ID=xxx and AIRBASE_SECRET_ACCESS_KEY=yyy

  7. Configure .gitlab-ci.yml:

    include:
      - project: innersource/sgts/runtime/airbase/airbase-pipeline
        ref: v1
        file: baseline.gitlab-ci.yml
    

See: GitLab CI/CD Integration for full setup instructions.

Branch Environment Benefits

For developers: - ✅ Preview changes before merge - ✅ Test integrations with real data - ✅ Share work-in-progress with team - ✅ QA testing before production

For teams: - ✅ Parallel feature development - ✅ Faster feedback cycles - ✅ Reduced production bugs - ✅ Better collaboration

Branch Environment Best Practices

1. Use consistent naming:

# Good
feature-user-auth
bugfix-payment-validation
hotfix-security-patch

# Avoid special characters
feature/user/auth  # ❌ Slashes become dashes
feature_user_auth  # ⚠️ Underscores work but use hyphens

2. Set auto-cleanup:

environment:
  auto_stop_in: 1 day  # Or 3 days, 1 week

3. Use separate .env files:

.env.production       # Production secrets
.env.staging          # Staging secrets
.env.{branch-name}    # Branch-specific overrides

4. Clean up after merge:

# Automatic via GitLab CI on_stop
# Or manual cleanup
airbase container list  # See all environments
airbase container destroy old-branch-name


Best Practices

✅ Do

  • Use staging for testing changes before production
  • Use consistent naming across your team
  • Clean up feature environments after merging
  • Document environment purposes for your team
  • Use separate .env files for each environment
  • Test in staging before deploying to production

❌ Don't

  • Don't skip testing in staging
  • Don't leave old feature environments running
  • Don't use production credentials in staging
  • Don't deploy untested code to production
  • Don't forget to clean up after yourself

Troubleshooting

Issue: Environment Not Accessible After Deployment

Wait 30-60 seconds for deployment to complete, then refresh.

Issue: Wrong Environment Variables

Check which .env file is being used:

  • Default environment → .env
  • Named environment → .env.ENVIRONMENT-NAME

Issue: Can't Remember Which Environments Exist

Check your deployments in the Airbase Console (web interface).

Issue: Environment Name Has Typo

Solution: Deploy with correct name, then undeploy the typo:

# Deploy with correct name
airbase container deploy --yes staging

# Remove the typo
airbase container destroy --yes stagging

Next Steps


See Also


Summary

Key concepts:

  • Environments are isolated instances of your application
  • Default environment is production (requires --yes)
  • Named environments are created automatically when you deploy
  • Each environment has its own URL with double-dash separator
  • Use .env.ENVIRONMENT files for per-environment configuration

Common workflow:

  1. Deploy to staging: airbase container deploy --yes staging
  2. Test at https://staging--project.app.tc1.airbase.sg
  3. Deploy to production: airbase container deploy --yes

Environments enable safe, iterative development!