How to Set Up Local Development with Docker Compose for Macro
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:
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:
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. Start these dependencies first:
docker compose -f docker/docker-compose-databases.yml up -d
Key configuration details from this file include:
- PostgreSQL runs on port
5432with 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:
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. 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.
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), andemail_service, each with dedicated health checks (lines 36-70, 84-95, 98-110). - Background workers including the
ai_editing_worker(lines 124-130) andlexical_service(lines 172-180), which build from their respective Dockerfiles.
Verify the Installation
Confirm all services are healthy by querying their HTTP health endpoints:
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:
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:
docker compose -f docker/docker-compose.yml --profile jaeger up -d
This profile is defined in lines 112-118 of docker/docker-compose.yml.
Datadog Agent (OTLP Export)
Export telemetry to Datadog by providing your API key:
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.ymlto start core infrastructure dependencies. - Use
infra/stacks/fusionauth-instance/docker-compose.ymlfor optional local authentication. - The main
docker/docker-compose.ymlbuilds the Rust services image fromdocker/Dockerfile.devand orchestrates all micro-services. - Enable observability with
--profile jaegeror--profile datadogflags.
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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →