Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 140 additions & 92 deletions docs/node-operators/archive-node/docker-compose.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Docker Compose Archive
sidebar_label: Docker Compose example
description: Example of how to run a Mina archive node using Docker Compose.
description: Run a Mina archive node using Docker Compose.
keywords:
- mina archive node
- docker compose
Expand All @@ -10,97 +10,145 @@ keywords:

# Docker Compose Archive

This example demonstrates how to run a Mina archive node using Docker Compose for the Mainnet network. This Docker Compose setup includes a Postgres database, a bootstrap database with the latest SQL Dump available, an archive node, a Mina node and a Missing Blocks Guardian script to monitor and populate the gaps in the archive database

Copy and paste the provided configuration into a `docker-compose.yml` file. Then run `docker compose up -d` to start the services, and use `docker compose logs -f` to monitor the logs.

```yaml
services:
postgres:
image: postgres:17
restart: always
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: archive
healthcheck:
test: ["CMD-SHELL", "psql -U postgres -d archive -tAc \"SELECT COUNT(*) FROM pg_database WHERE datname='archive';\" | grep -q '^1$'"]
interval: 5s
timeout: 10s
retries: 10
volumes:
- './archive/postgresql/data:/var/lib/postgresql/data'
ports:
- '5432:5432'
bootstrap_db:
image: 'minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet'
# image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet
command: >
bash -c '
curl -O https://storage.googleapis.com/mina-archive-dumps/mainnet-archive-dump-$(date +%F_0000).sql.tar.gz;
tar -zxvf mainnet-archive-dump-$(date +%F_0000).sql.tar.gz;
psql postgres://postgres:postgres@postgres:5432/archive -c "
ALTER SYSTEM SET max_connections = 500;
ALTER SYSTEM SET max_locks_per_transaction = 100;
ALTER SYSTEM SET max_pred_locks_per_relation = 100;
ALTER SYSTEM SET max_pred_locks_per_transaction = 5000;
"
psql postgres://postgres:postgres@postgres:5432/archive -f mainnet-archive-dump-$(date +%F_0000).sql;
'
# For Devnet Network, replace "mainnet" references with "devnet" in the block above
depends_on:
postgres:
condition: service_healthy
missing_blocks_guardian:
image: 'minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet'
# image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet
command: >
bash -c '
curl -O https://raw.githubusercontent.com/MinaFoundation/helm-charts/main/mina-archive/scripts/missing-blocks-guardian-command.sh;
export GUARDIAN_PRECOMPUTED_BLOCKS_URL=https://673156464838-mina-precomputed-blocks.s3.us-west-2.amazonaws.com/mainnet;
export MINA_NETWORK=mainnet;
export PG_CONN=postgres://postgres:postgres@postgres:5432/archive;
while true; do bash missing-blocks-guardian-command.sh; sleep 600; done
'
# For Devnet Network, replace "mainnet" references with "devnet" in the block above
depends_on:
bootstrap_db:
condition: service_completed_successfully
mina_archive:
image: 'minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet'
restart: always
command:
- mina-archive
- run
- --postgres-uri
- postgres://postgres:postgres@postgres:5432/archive
- --server-port
- "3086"
volumes:
- './archive/data:/data'
depends_on:
bootstrap_db:
condition: service_completed_successfully
mina_node:
image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet'
# image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet
restart: always
entrypoint: []
command: >
bash -c '
mina daemon --archive-address mina_archive:3086 \
--peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \
--insecure-rest-server \
--rest-port 3085
'
# use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet
ports:
- '3085:3085'
- '8302:8302'
depends_on:
bootstrap_db:
condition: service_completed_successfully
Run a Mina archive node — a PostgreSQL database that ingests blocks from a connected daemon, plus a missing-blocks guardian that backfills gaps from the daily archive dumps. Use this if you need historical chain state beyond the daemon's transition frontier (the last `k` blocks).

The full Docker Compose configuration — including `docker-compose.yml`, example environment files for mainnet and devnet, a `Makefile`, and a `README` — is maintained in the Mina repository:

**[`mina/src/app/archive/docker-compose/`](https://github.com/MinaProtocol/mina/tree/develop/src/app/archive/docker-compose)**

## Quick start

:::tip
Before running the commands below, review the [Configuration](#configuration) section to see all available options — including image tags, network selection, ports, and database settings.
:::

```bash
git clone https://github.com/MinaProtocol/mina.git
cd mina/src/app/archive/docker-compose

# For mainnet
cp example.mainnet.env .env

# For devnet
cp example.devnet.env .env

# Edit .env — set MINA_LIBP2P_PASS and review POSTGRES_PASSWORD
vi .env

# Start services
docker compose up -d

# Or use make shortcuts
make mainnet
make devnet
```

:::info
The `bootstrap_db` service downloads and imports the latest daily archive dump. This may take a while depending on your connection speed. The archive node and Mina daemon will start after the import completes.
:::

## Services overview

| Service | Description | Default Port |
|---------|-------------|--------------|
| **postgres** | PostgreSQL 17 with health checks | 5432 (container), configurable host port |
| **bootstrap_db** | One-shot: downloads and imports the latest daily archive dump | — |
| **mina_archive** | Archive process, stores block data in PostgreSQL | 3086 |
| **mina_node** | Mina daemon connected to the archive process via `--archive-address` | 3085 (GraphQL), 8302 (P2P) |
| **missing_blocks_guardian** | Monitors and recovers missing blocks between nightly dumps and chain tip | — |

## Configuration

All configuration is done through a single `.env` file. Key variables:

### Docker images

| Variable | Description |
|----------|-------------|
| `MINA_DAEMON_IMAGE` | Mina daemon Docker image |
| `MINA_ARCHIVE_IMAGE` | Mina archive Docker image |

For mainnet, images are pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol) (`minaprotocol/mina-*`).
For devnet, images are pulled from the o1Labs GCR registry.

### Network

| Variable | Description |
|----------|-------------|
| `MINA_NETWORK` | `mainnet` or `devnet` |
| `MINA_PEERLIST_URL` | Bootstrap peers URL |
| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) |

### Ports

| Variable | Default | Description |
|----------|---------|-------------|
| `POSTGRES_PORT` | `5433` | Host port mapped to PostgreSQL |
| `MINA_REST_PORT` | `3085` | GraphQL API port |
| `MINA_P2P_PORT` | `8302` | P2P networking port |
| `MINA_ARCHIVE_PORT` | `3086` | Archive server port |

### Archive bootstrap

| Variable | Description |
|----------|-------------|
| `ARCHIVE_DUMP_BASE_URL` | Base URL for daily archive dumps |
| `ARCHIVE_DUMP_PREFIX` | Dump filename prefix (`mainnet-archive-dump` or `devnet-archive-dump`) |
| `GUARDIAN_PRECOMPUTED_BLOCKS_URL` | S3 bucket URL for precomputed blocks used by the missing blocks guardian |

## Data persistence

Bind mounts preserve data across `docker compose down` / `up`:

| Host path | Container path | Contents |
|-----------|---------------|----------|
| `./archive/postgresql/data` | `/var/lib/postgresql/data` | PostgreSQL data |
| `./archive/data` | `/data` | Archive node data |
| `./mina_node/.mina-config` | `/root/.mina-config` | Daemon config, keys, peers |

## Make targets

| Command | Description |
|---------|-------------|
| `make devnet` | Copy devnet env and start services |
| `make mainnet` | Copy mainnet env and start services |
| `make stop` | Stop services |
| `make clean` | Stop services, remove volumes and all archive data |
| `make logs` | Follow logs |
| `make status` | Show container status |
| `make health` | Check Postgres, GraphQL endpoint, and container summary |

## Verifying the deployment

Once services are running and the node is synced:

```bash
make health

docker compose exec mina_node mina client status

# Mina node sync status
curl -s http://localhost:3085/graphql -H 'Content-Type: application/json' \
-d '{"query":"{ syncStatus }"}' | jq .

# Connect to archive database
psql postgres://postgres:postgres@localhost:5433/archive

# Latest block in archive
psql postgres://postgres:postgres@localhost:5433/archive \
-tAc "SELECT max(height) FROM blocks"

# Missing-blocks guardian progress
docker compose logs --tail=50 missing_blocks_guardian
```

Once the services are running, you can access the Mina node graphql endpoint at `http://localhost:3085/graphql` and the postgres database using `psql postgres://postgres:postgres@localhost:5432/archive`.
## Clean start

```bash
make clean
docker compose up -d
```

To retrieve the status of the Mina Node, run `docker compose exec mina_node mina client status`
:::warning
`make clean` deletes the entire archive database and the daemon's `.mina-config` (including any keys). The next start will re-download the latest archive dump (~30+ GB on mainnet).
:::
Loading
Loading