How to Deploy Macro Inc. to a Production Environment: Complete 7-Step Guide

Deploy Macro Inc. to production by building Rust services with just build, provisioning AWS infrastructure via Pulumi stacks, deploying Cloudflare Workers with wrangler, and publishing Docker images to ECS/Fargate—all orchestrated through CI/CD pipelines.

This guide walks through the end-to-end deployment process for the macro-inc/macro repository, a multi-service platform combining Rust backends, Cloudflare Edge infrastructure, and AWS-native resources. All commands and file paths reference the actual source code implementation.


Prerequisites and Local Environment Setup

Before touching production infrastructure, establish a properly configured local development environment. Macro Inc. uses Nix as its primary toolchain orchestrator and Docker Compose for local database services.

Install the Development Shell


# Enter the Nix development shell (provides Rust, Bun, just, docker, Pulumi, etc.)

nix develop

# Alternative: launch with specific shell

nix develop --command bash

The Nix flake automatically pins compatible versions of all build tools, eliminating version drift between local and CI environments.

Initialize Local Databases


# Start PostgreSQL containers for all required databases

docker compose -f docker/docker-compose-databases.yml up -d postgres

# Generate environment files for all deployment targets

just setup_test_envs

# Run database migrations across all services

just initialize_dbs

These steps populate .env.dev, .env.test, and .env.prod files with connection strings and create the schema for MacroDB, CommsDB, EmailDB, and ContactsDB as referenced in [docker/docker-compose-databases.yml](https://github.com/macro-inc/macro/blob/main/docker/docker-compose-databases.yml).


Build Production Artifacts

Macro Inc. produces three distinct artifact types: Rust binaries (services and Lambdas), Docker images, and Cloudflare Workers. Build all artifacts before any deployment step.

Build Rust Services and Lambda Functions


# Compile all service binaries

just build

# Generate Lambda deployment packages (zip files)

just build_lambdas

The just build command orchestrates cargo build --release across all workspace crates. Lambda functions receive special treatment via the cargo-lambda toolchain, outputting optimized zip archives to target/lambda/.

Prepare SQLx Query Metadata


# Generate offline query metadata required for release builds

just prepare_db

Critical: Macro Inc. does not use SQLx offline mode for tests. The prepare_db command must execute after any schema migration to regenerate .sqlx/ metadata, ensuring compile-time query verification passes in CI.

Build Docker Images


# Example: build the lexical service image

docker build -f docker/lexical-service.Dockerfile -t macro/lexical:prod .

# Build all service images via just

just build_images

Dockerfiles reside in docker/*.Dockerfile with service-specific configurations for multi-stage Rust builds.


Deploy Infrastructure with Pulumi

Macro Inc. manages all AWS infrastructure through Pulumi TypeScript stacks under infra/stacks/. Each stack represents an independently deployable infrastructure component.

Core Production Stacks

Stack Purpose Key Resources
web-app Static site hosting S3 bucket, CloudFront distribution, Route 53 records
cloud-storage-cache Edge caching layer Docker-based cache services
fusion-auth Authentication service ECS Fargate, RDS PostgreSQL
search Full-text search OpenSearch domain, IAM policies
kafka-cluster Event streaming MSK cluster, topic definitions

Deploy a Stack to Production

cd infra/stacks/web-app

# Select and deploy the production stack

pulumi up --stack prod

First-time deployment: Pulumi prompts for required secrets (e.g., fusionauth-db-password-prod). Store these in Pulumi's encrypted state or export as environment variables beforehand.

Stack Configuration Management

Each stack maintains environment-specific configuration in Pulumi.<stack>.yaml. The production configuration references:

  • Pre-provisioned SSL certificates
  • Registered domain names
  • VPC and subnet IDs
  • Database connection parameters

Consult [infra/README.md](https://github.com/macro-inc/macro/blob/main/infra/README.md) for complete stack documentation and secret management procedures.


Deploy Cloudflare Workers

Real-time services—including document collaboration, WebSocket handling, and sync operations—run as Cloudflare Workers at the network edge.

Deploy via Wrangler CLI


# Navigate to target service

cd services/lexical-service

# Deploy to production environment

bun run deploy-prod

The deploy-prod script wraps wrangler deploy --env prod with additional build steps. Direct wrangler usage:

npx wrangler deploy --env prod --config wrangler.toml

Service-Specific Deployment Patterns

Each worker service in services/ follows identical patterns:

Service Deployment Command Reference
lexical-service bun run deploy-prod [services/lexical-service/README.md](https://github.com/macro-inc/macro/blob/main/services/lexical-service/README.md)
sync-service npx wrangler deploy --env prod [services/sync-service/README.md](https://github.com/macro-inc/macro/blob/main/services/sync-service/README.md)
websocket-service bun run deploy-prod Service README

Worker resources: KV namespaces and Durable Objects provision automatically on first deployment. Verify binding configuration in each service's wrangler.toml.


Deploy Docker-Based Services

Containerized services deploy to ECS Fargate through Pulumi stack updates. The workflow combines image publishing with infrastructure reconciliation.

Publish and Deploy Container Images


# Tag image with version identifier

docker tag macro/lexical:prod registry.example.com/macro/lexical:2024-08-20

# Push to configured registry

docker push registry.example.com/macro/lexical:2024-08-20

# Update stack to reference new image

cd infra/stacks/web-app
pulumi up --stack prod

Pulumi detects the image tag change and performs a rolling deployment of ECS tasks, maintaining service availability throughout the update.

Local Docker Compose vs. Production

The [docker/docker-compose.yml](https://github.com/macro-inc/macro/blob/main/docker/docker-compose.yml) supports local integration testing only. Production containers never use Compose; they execute under AWS ECS with Pulumi-managed task definitions, service discovery, and auto-scaling policies.


Verify Deployment Health

Validate production functionality through comprehensive test execution against live infrastructure.

Run Test Suites


# Execute all Rust unit and integration tests

just test

# Execute end-to-end test suite

just test_e2e

Tests authenticate against production endpoints and verify database connectivity, search indexing, and worker responsiveness. Failure indicates infrastructure misconfiguration or incomplete deployment.

Monitoring and Observability

Deployed stacks automatically emit metrics to CloudWatch. Check the Pulumi stack outputs for:

  • CloudFront distribution URLs
  • ECS service ARNs
  • OpenSearch domain endpoints
  • MSK broker connection strings

CI/CD Pipeline Integration

Production deployments typically trigger automatically via GitHub Actions. Understand the pipeline architecture for manual intervention or troubleshooting.

Key Workflows

Workflow Trigger Actions
deploy_web_app.yml Push to main (path: apps/web/**) Build SPA → Upload to S3 → Invalidate CloudFront
deploy_service_generic.yml Push to main (service directories) Build Docker image → pulumi up → wrangler deploy
release-production.yml Tag v* Multi-arch image publish → Lambda artifact release

Source: .github/workflows/

Manual Pipeline Execution

Force a deployment without code changes:


# Trigger via GitHub CLI

gh workflow run deploy_service_generic.yml --ref main

# Or dispatch with specific inputs

gh workflow run deploy_web_app.yml -f environment=prod

Rollback Procedures

When production releases require reversal, execute these steps in sequence:

  1. Revert infrastructure state

    cd infra/stacks/web-app
    pulumi destroy --stack prod  # removes resources
    
    # Or roll back to previous state
    
    pulumi stack export --stack prod > backup.json
    pulumi stack import --stack prod < previous-state.json
  2. Revert worker deployment

    cd services/lexical-service
    npx wrangler rollback --env prod
  3. Database recovery (if schema migration caused issues)

    just restore_db <snapshot-identifier>
  4. Emergency hot-fix Push corrective commit to main; CI automatically redeploys corrected artifacts.


Summary

Deploying Macro Inc. to production requires coordinating multiple build systems and infrastructure providers:

  • Local setup with Nix development shell and Docker database services
  • Artifact building via just build, just build_lambdas, and just prepare_db
  • Infrastructure provisioning through Pulumi stacks (pulumi up --stack prod)
  • Edge deployment with wrangler for Cloudflare Workers
  • Container publishing and ECS updates for Docker-based services
  • Verification through just test and end-to-end suites
  • Automation via GitHub Actions with manual rollback capabilities

Each phase references specific files in the repository—consult the linked documentation for environment-specific configurations.


Frequently Asked Questions

What permissions are required to deploy Macro Inc. to production?

You need AWS credentials with permissions for S3, CloudFront, Route 53, ECS, RDS, MSK, and OpenSearch; Pulumi access to the organization stack; Cloudflare API tokens for worker deployment; and Docker registry push access. The [infra/README.md](https://github.com/macro-inc/macro/blob/main/infra/README.md) specifies exact IAM policies and token scopes.

Can I deploy Macro Inc. without using Pulumi?

No. Pulumi is the sole infrastructure-as-code tool in the repository. All AWS resources—VPCs, databases, caches, and compute—are defined in TypeScript stacks under infra/stacks/. Manual resource creation will cause drift and break subsequent deployments.

How do I deploy a single service without rebuilding everything?

Use targeted just commands and stack selection:


# Build only lexical-service

cargo build --release -p lexical-service

# Deploy only its worker

cd services/lexical-service && bun run deploy-prod

# Update only the ECS service (if containerized)

cd infra/stacks/cloud-storage-cache && pulumi up --stack prod

Pulumi performs differential updates, modifying only changed resources.

What happens if just prepare_db fails during deployment?

SQLx compile-time verification requires accurate query metadata. If prepare_db fails:

  1. Verify local PostgreSQL is running: docker ps | grep postgres
  2. Check database connectivity in .env.dev
  3. Run just initialize_dbs to ensure migrations are applied
  4. Retry just prepare_db with explicit logging: RUST_LOG=sqlx=debug just prepare_db

Without successful preparation, release builds will fail in CI.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →