# How to Set Up Local Development with Docker Compose for Macro

> Easily set up local development for Macro a multi-service Rust app with Docker Compose. Start the entire stack including PostgreSQL Redis Kafka and more with simple commands.

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

---

**Macro is a multi-service Rust application that orchestrates PostgreSQL, Redis, Kafka, OpenSearch, and authentication services locally using Docker Compose, allowing developers to start the entire stack with a few CLI commands.**

Setting up a local development environment for Macro requires coordinating multiple backend services and Rust micro-services. The macro-inc/macro repository provides Docker Compose configurations that containerize the entire architecture, eliminating the need to install Rust toolchains or databases directly on your host machine. This guide walks you through the exact steps to set up local development with Docker Compose for Macro using the official compose files.

## Prerequisites

Before starting, ensure you have the following tools installed:

- **Docker Desktop** or Docker Engine with Compose v2 support.
- **Git** to clone the repository.
- Optional: **Node.js or Bun** if you plan to modify the lexical or analytics workers (though these build inside containers).

## Clone the Repository

Start by cloning the official Macro repository and navigating into the project root:

```bash
git clone https://github.com/macro-inc/macro.git
cd macro

```

## Configure Environment Variables

The compose files load configuration from `${MACRO_ENV_FILE:-.env}`, defaulting to a `.env` file in the project root. While optional for basic setups, you should create this file if you need to override secrets, ports, or connection strings:

```bash
touch .env

```

You can populate this file with custom values, but the stack runs with sensible defaults if left empty.

## Start the Core Infrastructure

The **databases** stack defines PostgreSQL, Redis, Kafka, and OpenSearch in [`docker/docker-compose-databases.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose-databases.yml). Start these dependencies first:

```bash
docker compose -f docker/docker-compose-databases.yml up -d

```

Key configuration details from this file include:

- **PostgreSQL** runs on port `5432` with max connections set to 500 (lines 9-13).
- **Redis** exposes its management UI on port `8001`.
- **Kafka** operates as a single-node KRaft broker on port `9092`.
- **OpenSearch** runs in single-node mode on port `9200` (lines 80-85).

## Start the Authentication Stack (Optional)

If your development work requires local authentication, start the FusionAuth stack defined in [`infra/stacks/fusionauth-instance/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/infra/stacks/fusionauth-instance/docker-compose.yml):

```bash
docker compose -f infra/stacks/fusionauth-instance/docker-compose.yml up -d

```

This provides an authentication service on port `9011` alongside a dedicated PostgreSQL instance for user data.

## Launch the Macro Services

With infrastructure running, start the main Rust application stack using [`docker/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose.yml). This file defines the `x-common-env` extension (lines 11-18) for shared environment variables and the `x-rust-services-image` extension (lines 19-24) which builds the `macro-local-rust-services:dev` image from `docker/Dockerfile.dev`.

```bash
docker compose -f docker/docker-compose.yml up -d

```

This command launches:

- **Micro-services** such as `authentication-service` (port 8080), `document_storage_service` (port 8086), and `email_service`, each with dedicated health checks (lines 36-70, 84-95, 98-110).
- **Background workers** including the `ai_editing_worker` (lines 124-130) and `lexical_service` (lines 172-180), which build from their respective Dockerfiles.

## Verify the Installation

Confirm all services are healthy by querying their HTTP health endpoints:

```bash
curl http://localhost:8080/health          # authentication-service

curl http://localhost:8086/health          # document_storage_service

curl http://localhost:16686                # Jaeger UI (if using jaeger profile)

```

## Stop the Environment

When finished developing, tear down the containers in reverse order:

```bash
docker compose -f docker/docker-compose.yml down
docker compose -f docker/docker-compose-databases.yml down
docker compose -f infra/stacks/fusionauth-instance/docker-compose.yml down

```

## Optional Observability Profiles

The main compose file includes optional profiles for monitoring and tracing.

**Jaeger (Distributed Tracing)**

Start the Jaeger trace viewer on port `16686`:

```bash
docker compose -f docker/docker-compose.yml --profile jaeger up -d

```

This profile is defined in lines 112-118 of [`docker/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose.yml).

**Datadog Agent (OTLP Export)**

Export telemetry to Datadog by providing your API key:

```bash
DD_API_KEY=<your-key> docker compose -f docker/docker-compose.yml --profile datadog up -d

```

Defined in lines 140-147, this profile runs the Datadog Agent as an OTLP exporter.

## Summary

- **Macro** runs as a multi-service Rust architecture requiring PostgreSQL, Redis, Kafka, and OpenSearch.
- Use [`docker/docker-compose-databases.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose-databases.yml) to start core infrastructure dependencies.
- Use [`infra/stacks/fusionauth-instance/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/infra/stacks/fusionauth-instance/docker-compose.yml) for optional local authentication.
- The main [`docker/docker-compose.yml`](https://github.com/macro-inc/macro/blob/main/docker/docker-compose.yml) builds the Rust services image from `docker/Dockerfile.dev` and orchestrates all micro-services.
- Enable observability with `--profile jaeger` or `--profile datadog` flags.

## Frequently Asked Questions

### Do I need to install Rust locally to develop Macro?

No. The `docker/Dockerfile.dev` builds the `macro-local-rust-services:dev` image containing all compiled Rust binaries inside the container. You only need Docker Compose and Git to run the full stack.

### Why are the databases and services split into separate compose files?

The separation allows you to manage infrastructure lifecycles independently. You can keep PostgreSQL, Redis, Kafka, and OpenSearch running continuously while restarting only the Rust micro-services during active development, reducing startup time.

### How do I override default configuration values?

Create a `.env` file in the project root. The compose files reference `${MACRO_ENV_FILE:-.env}`, loading your overrides for secrets, ports, or connection strings automatically when starting the stack.

### Can I run specific services instead of the entire stack?

Yes. Docker Compose supports service names as arguments. For example, to run only the authentication service and its dependencies: `docker compose -f docker/docker-compose.yml up -d authentication-service`.