# How to Start the Local Macro Stack: Complete Docker Compose Guide

> Quickly start the local Macro stack with Docker Compose. This guide details launching essential services like Postgres, Redis, and LocalStack for your Rust backend development.

- Repository: [Macro/macro](https://github.com/macro-inc/macro)
- Tags: how-to-guide
- Published: 2026-08-21

---

**You can start the local Macro stack by running `just run_local --no-doppler` inside the Nix dev shell, which launches Docker containers for Postgres, Redis, LocalStack, and other services alongside the compiled Rust backend.**

The Macro repository provides a fully containerized local development environment that mirrors production micro-service architecture. According to the `macro-inc/macro` source code, you can spin up the entire stack—including databases, search indexes, and authentication services—using deterministic stubbed configuration that requires no external cloud access.

## Prerequisites

Install **Nix**, the only host-level dependency required by Macro:

```bash
curl -L https://nixos.org/nix/install | sh

```

Enter the development shell to load the Rust toolchain, Docker utilities, and `just` task runner:

```bash
nix develop

```

*If this command fails, enable experimental features as documented in [`docs/RUNNING_LOCALLY.md`](https://github.com/macro-inc/macro/blob/main/docs/RUNNING_LOCALLY.md).*

## Basic Startup Without Doppler

The fastest way to start the local Macro stack uses stubbed configuration values that simulate production integrations without requiring real API keys.

### Launch the Stack

Execute the `run_local` recipe from the `justfile`:

```bash
just run_local --no-doppler

```

This command orchestrates multiple steps defined in [`docs/RUNNING_LOCALLY.md`](https://github.com/macro-inc/macro/blob/main/docs/RUNNING_LOCALLY.md): it compiles the Rust services, starts the Docker Compose stack defined in [`docker/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose.yml), and initializes containers for **Postgres**, **Redis**, **LocalStack** (AWS S3 mock), **OpenSearch**, **Kafka**, and **FusionAuth**.

### Access the Application

Once startup completes, the terminal displays:

```

Frontend URL: http://localhost:3000/app/

```

Open this URL in your browser. The stack uses passwordless login: register any email address, then retrieve the one-time code from **Mailpit** at `http://localhost:8025`.

### Control the Running Stack

While the terminal remains attached to the stack, use these hot-keys:

- **r** – Rebuild only the Rust services whose binaries changed
- **q** – Gracefully stop and remove all containers

*Always press **q** to tear down the stack. Closing the terminal directly can leave orphaned containers and volumes.*

## Understanding the Local Architecture

The local stack simulates production through several coordinated components:

- **Nix dev shell** – Provides `just`, Cargo, the Rust toolchain, and Docker tooling as the single host-level prerequisite. All commands must run from inside `nix develop`.

- **Docker Compose services** – The [`docker/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose.yml) defines containers for Postgres, Redis, LocalStack, OpenSearch, Kafka, and FusionAuth, mirroring the production micro-service architecture.

- **Stubbed configuration** – A set of deterministic keys (e.g., dummy AWS credentials) defined in the local infrastructure setup satisfies service config loaders without accessing Doppler.

- **Hot-reload proxy** – Watches for source changes and triggers incremental rebuilds of Rust services during development.

Configuration and state for each stack instance are generated in `infra/local/generated/`, including port mappings and volume definitions.

## Running With Real Integrations

To test third-party flows like Google login, GitHub OAuth, or Stripe billing, supply real secrets via Doppler or a local environment file.

**Using Doppler:**

```bash
just run_local

```

**Using a local.env file:**

Create `local.env` with the specific variables you need, then:

```bash
just run_local --env-file ./local.env

```

Only the variables you list override the built-in stubs; all other services continue using deterministic defaults.

## Working With Named Instances

You can spin up multiple isolated stacks for parallel development or Git work-trees. Each instance receives its own port window, volumes, and network.

Start a named instance with a custom port base:

```bash
just run_local --no-doppler --instance agent-a --port-base 31000

```

Check the health of a specific instance:

```bash
just status_local --instance agent-a --port-base 31000

```

Seed data for a named instance:

```bash
just seed-scenario --instance agent-a --port-base 31000 \
    apply --file seed/scenarios/team-perms.json

```

Instance-specific configuration and snapshots are stored in `infra/local/generated/` under the instance name.

## Seeding Sample Data

Populate the stack with a realistic demo world using the `seed-scenario` recipe:

```bash
just seed-scenario apply --file seed/scenarios/team-perms.json

```

This creates users, teams, channels, documents, and tasks defined in [`seed/scenarios/team-perms.json`](https://github.com/macro-inc/macro/blob/main/seed/scenarios/team-perms.json), and prints login links for each test persona.

## Summary

- Enter the **Nix dev shell** (`nix develop`) before running any commands.
- Use **`just run_local --no-doppler`** to start the stack with stubbed configuration.
- Access the UI at `http://localhost:3000/app/` and Mailpit at `http://localhost:8025`.
- Press **q** while attached to gracefully stop the stack and clean up containers.
- Supply real secrets via **`--env-file ./local.env`** or omit `--no-doppler` to use Doppler.
- Run multiple isolated stacks using **`--instance <name>`** and **`--port-base <number>`**.

## Frequently Asked Questions

### Can I run multiple local stacks simultaneously?

Yes. Use the **`--instance`** flag to create isolated environments with separate port ranges, volumes, and networks. For example, `just run_local --no-doppler --instance feature-x --port-base 32000` starts a completely independent stack that will not conflict with your default instance on port 3000.

### Do I need Doppler access to run Macro locally?

No. The **`--no-doppler`** flag uses deterministic stubbed configuration values that satisfy all service requirements. You only need real secrets when testing specific third-party integrations like OAuth or payment processing.

### How do I update the stack after modifying Rust source code?

While the stack is running and your terminal is attached, press **r** to rebuild only the services whose binaries changed. This hot-reload mechanism compiles incrementally and restarts the affected containers without tearing down the entire stack.

### What services are included in the local Docker Compose stack?

The stack defined in [`docker/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose.yml) includes **Postgres** (primary database), **Redis** (caching), **LocalStack** (AWS S3 mock), **OpenSearch** (full-text search), **Kafka** (event streaming), and **FusionAuth** (identity management), alongside the compiled Macro Rust services and frontend proxy.