From ba61862bbe30df18a367565a4cc676d8fbb9e2e5 Mon Sep 17 00:00:00 2001 From: dkijania Date: Wed, 1 Apr 2026 13:01:20 +0200 Subject: [PATCH 1/2] Rewrite block producer and archive docker-compose pages Follow the pattern established by the Rosetta docker-compose page: - Use .env file for all configuration (images, network, ports, passwords) - Add health checks to daemon services - Add libp2p key generation to block producer - Add data persistence and services overview tables - Add verification and clean start sections - Remove hardcoded image versions from docker-compose.yml Co-Authored-By: Claude Opus 4.6 (1M context) --- .../archive-node/docker-compose.mdx | 208 +++++++++++++++--- .../block-producer-node/docker-compose.mdx | 154 +++++++++++-- 2 files changed, 318 insertions(+), 44 deletions(-) diff --git a/docs/node-operators/archive-node/docker-compose.mdx b/docs/node-operators/archive-node/docker-compose.mdx index 37c792d70..0c21b3cea 100644 --- a/docs/node-operators/archive-node/docker-compose.mdx +++ b/docs/node-operators/archive-node/docker-compose.mdx @@ -10,9 +10,101 @@ 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 +Run a Mina archive node using Docker Compose. The setup includes a PostgreSQL database, a bootstrap service that imports the latest daily archive dump, the archive process, a Mina daemon, and a missing blocks guardian that monitors and recovers 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. +## 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. +::: + +1. Create a project directory and save the files below: + +```bash +mkdir -p mina-archive && cd mina-archive +``` + +2. Create the `.env` file (see [Configuration](#configuration) for all variables): + +```bash +# .env +MINA_DAEMON_IMAGE=minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet +MINA_ARCHIVE_IMAGE=minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet +MINA_NETWORK=mainnet +MINA_PEERLIST_URL=https://bootnodes.minaprotocol.com/networks/mainnet.txt +MINA_LIBP2P_PASS= +POSTGRES_PASSWORD=postgres +POSTGRES_PORT=5432 +MINA_REST_PORT=3085 +MINA_P2P_PORT=8302 +MINA_ARCHIVE_PORT=3086 +ARCHIVE_DUMP_BASE_URL=https://storage.googleapis.com/mina-archive-dumps +ARCHIVE_DUMP_PREFIX=mainnet-archive-dump +GUARDIAN_PRECOMPUTED_BLOCKS_URL=https://673156464838-mina-precomputed-blocks.s3.us-west-2.amazonaws.com/mainnet +``` + +3. Create the `docker-compose.yml` (see [Docker Compose file](#docker-compose-file)). + +4. Start the services: + +```bash +docker compose up -d + +# Follow logs +docker compose logs -f +``` + +:::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. +::: + +## Configuration + +All configuration is done through a single `.env` file. + +### Docker images + +| Variable | Description | Example | +|----------|-------------|---------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | `minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet` | +| `MINA_ARCHIVE_IMAGE` | Mina archive Docker image | `minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet` | + +For devnet, use the o1Labs GCR images: +- Daemon: `gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet` +- Archive: `gcr.io/o1labs-192920/mina-archive:3.3.0-alpha1-6929a7e-bullseye-devnet` + +### Network + +| Variable | Description | Example | +|----------|-------------|---------| +| `MINA_NETWORK` | Network name | `mainnet` or `devnet` | +| `MINA_PEERLIST_URL` | Bootstrap peers URL | `https://bootnodes.minaprotocol.com/networks/mainnet.txt` | +| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | — | + +### Ports + +| Variable | Default | Description | +|----------|---------|-------------| +| `POSTGRES_PORT` | `5432` | 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 | + +### Database + +| Variable | Default | Description | +|----------|---------|-------------| +| `POSTGRES_PASSWORD` | `postgres` | PostgreSQL password | + +### 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 | + +## Docker Compose file ```yaml services: @@ -20,7 +112,7 @@ services: image: postgres:17 restart: always environment: - POSTGRES_PASSWORD: postgres + POSTGRES_PASSWORD: ${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$'"] @@ -30,77 +122,133 @@ services: volumes: - './archive/postgresql/data:/var/lib/postgresql/data' ports: - - '5432:5432' + - '${POSTGRES_PORT:-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 + image: '${MINA_ARCHIVE_IMAGE}' 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 " + curl -O ${ARCHIVE_DUMP_BASE_URL}/${ARCHIVE_DUMP_PREFIX}-$$(date +%F_0000).sql.tar.gz; + tar -zxvf ${ARCHIVE_DUMP_PREFIX}-$$(date +%F_0000).sql.tar.gz; + psql postgres://postgres:${POSTGRES_PASSWORD:-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; + psql postgres://postgres:${POSTGRES_PASSWORD:-postgres}@postgres:5432/archive -f ${ARCHIVE_DUMP_PREFIX}-$$(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 + image: '${MINA_ARCHIVE_IMAGE}' 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; + export GUARDIAN_PRECOMPUTED_BLOCKS_URL=${GUARDIAN_PRECOMPUTED_BLOCKS_URL}; + export MINA_NETWORK=${MINA_NETWORK}; + export PG_CONN=postgres://postgres:${POSTGRES_PASSWORD:-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' + image: '${MINA_ARCHIVE_IMAGE}' restart: always command: - mina-archive - run - --postgres-uri - - postgres://postgres:postgres@postgres:5432/archive + - postgres://postgres:${POSTGRES_PASSWORD:-postgres}@postgres:5432/archive - --server-port - - "3086" + - "${MINA_ARCHIVE_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 + image: '${MINA_DAEMON_IMAGE}' restart: always + environment: + MINA_LIBP2P_PASS: ${MINA_LIBP2P_PASS} + healthcheck: + test: ["CMD-SHELL", "mina client status"] + interval: 60s + timeout: 10s + retries: 100 entrypoint: [] command: > bash -c ' - mina daemon --archive-address mina_archive:3086 \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ + mina daemon \ + --archive-address mina_archive:${MINA_ARCHIVE_PORT:-3086} \ + --peer-list-url ${MINA_PEERLIST_URL} \ --insecure-rest-server \ - --rest-port 3085 + --rest-port ${MINA_REST_PORT:-3085} \ + --config-directory /root/.mina-config \ + --file-log-rotations 500 \ + --generate-genesis-proof true \ + --log-json ' - # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet ports: - - '3085:3085' - - '8302:8302' + - '${MINA_REST_PORT:-3085}:${MINA_REST_PORT:-3085}' + - '${MINA_P2P_PORT:-8302}:8302' + volumes: + - './mina_node/.mina-config:/root/.mina-config' depends_on: bootstrap_db: condition: service_completed_successfully ``` -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`. +## Services overview + +| Service | Description | Default Port | +|---------|-------------|--------------| +| **postgres** | PostgreSQL 17 with health checks | 5432 | +| **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 with GraphQL API | 3085 (GraphQL), 8302 (P2P) | +| **missing_blocks_guardian** | Monitors and recovers missing blocks between nightly dumps and chain tip | — | + +## 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 | + +## Verifying the deployment + +```bash +# Check container status +docker compose ps + +# Check sync status +docker compose exec mina_node mina client status + +# Query GraphQL API +curl -s http://localhost:${MINA_REST_PORT:-3085}/graphql \ + -H 'Content-Type: application/json' \ + -d '{"query": "{ syncStatus }"}' | jq . + +# Connect to archive database +psql postgres://postgres:${POSTGRES_PASSWORD:-postgres}@localhost:${POSTGRES_PORT:-5432}/archive + +# Check archive block height +psql postgres://postgres:${POSTGRES_PASSWORD:-postgres}@localhost:${POSTGRES_PORT:-5432}/archive \ + -c "SELECT MAX(height) FROM blocks;" +``` + +## Clean start -To retrieve the status of the Mina Node, run `docker compose exec mina_node mina client status` +To wipe all data and start fresh: + +```bash +docker compose down +rm -rf archive/ mina_node/ +docker compose up -d +``` diff --git a/docs/node-operators/block-producer-node/docker-compose.mdx b/docs/node-operators/block-producer-node/docker-compose.mdx index 87f55c7af..432105c90 100644 --- a/docs/node-operators/block-producer-node/docker-compose.mdx +++ b/docs/node-operators/block-producer-node/docker-compose.mdx @@ -10,45 +10,171 @@ keywords: # Docker Compose Block Producer -This example demonstrates how to run a Mina Block Producer node using Docker Compose for the Mainnet network. The Docker Compose setup includes a Mina Block Producer node, and another script to generate a wallet key. +Run a Mina Block Producer node using Docker Compose. The setup includes a one-shot key generation service and the block producer daemon. -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. +## Quick start + +:::tip +Before running the commands below, review the [Configuration](#configuration) section to see all available options — including image tags, network selection, and ports. +::: + +1. Create a project directory and save the files below: + +```bash +mkdir -p mina-block-producer && cd mina-block-producer +``` + +2. Create the `.env` file (see [Configuration](#configuration) for all variables): + +```bash +# .env +MINA_DAEMON_IMAGE=minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet +MINA_NETWORK=mainnet +MINA_PEERLIST_URL=https://bootnodes.minaprotocol.com/networks/mainnet.txt +MINA_PRIVKEY_PASS= +MINA_LIBP2P_PASS= +MINA_P2P_PORT=8302 +``` + +3. Create the `docker-compose.yml` (see [Docker Compose file](#docker-compose-file)). + +4. Start the services: + +```bash +# Generate keys and start the block producer +docker compose up -d + +# Follow logs +docker compose logs -f mina_block_producer +``` + +## Configuration + +All configuration is done through a single `.env` file. + +### Docker image + +| Variable | Description | Example | +|----------|-------------|---------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | `minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet` | + +For devnet, use the o1Labs GCR image: `gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet` + +### Network + +| Variable | Description | Example | +|----------|-------------|---------| +| `MINA_NETWORK` | Network name | `mainnet` or `devnet` | +| `MINA_PEERLIST_URL` | Bootstrap peers URL | `https://bootnodes.minaprotocol.com/networks/mainnet.txt` | +| `MINA_PRIVKEY_PASS` | Passphrase for the wallet key (required) | — | +| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | — | + +### Ports + +| Variable | Default | Description | +|----------|---------|-------------| +| `MINA_P2P_PORT` | `8302` | P2P networking port (must be reachable from the internet) | + +## Docker Compose file ```yaml services: generate_wallet_key: - 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 + image: '${MINA_DAEMON_IMAGE}' environment: - MINA_PRIVKEY_PASS: PssW0rD + MINA_PRIVKEY_PASS: ${MINA_PRIVKEY_PASS} entrypoint: [] command: > bash -c ' + if [ -f /root/.mina-config/keys/wallet-key ]; then + echo "Wallet key already exists, skipping generation" + exit 0 + fi mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/wallet-key + chmod 0700 /root/.mina-config/keys + chmod 0600 /root/.mina-config/keys/wallet-key + ' + volumes: + - './node/mina-config:/root/.mina-config' + generate_libp2p_key: + image: '${MINA_DAEMON_IMAGE}' + environment: + MINA_LIBP2P_PASS: ${MINA_LIBP2P_PASS} + entrypoint: [] + command: > + bash -c ' + if [ -f /root/.mina-config/keys/libp2p-key ]; then + echo "Libp2p key already exists, skipping generation" + exit 0 + fi + mina libp2p generate-keypair -privkey-path /root/.mina-config/keys/libp2p-key + chmod 0700 /root/.mina-config/keys + chmod 0600 /root/.mina-config/keys/libp2p-key ' volumes: - './node/mina-config:/root/.mina-config' mina_block_producer: - 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 + image: '${MINA_DAEMON_IMAGE}' restart: always environment: - MINA_PRIVKEY_PASS: PssW0rD + MINA_PRIVKEY_PASS: ${MINA_PRIVKEY_PASS} + MINA_LIBP2P_PASS: ${MINA_LIBP2P_PASS} + RAYON_NUM_THREADS: 6 + healthcheck: + test: ["CMD-SHELL", "mina client status"] + interval: 60s + timeout: 10s + retries: 100 entrypoint: [] command: > bash -c ' mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ - --block-producer-key /root/.mina-config/keys/wallet-key + --peer-list-url ${MINA_PEERLIST_URL} \ + --block-producer-key /root/.mina-config/keys/wallet-key \ + --libp2p-keypair /root/.mina-config/keys/libp2p-key \ + --config-directory /root/.mina-config \ + --file-log-rotations 500 \ + --generate-genesis-proof true \ + --log-json ' - # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet volumes: - './node/mina-config:/root/.mina-config' ports: - - '8302:8302' + - '${MINA_P2P_PORT:-8302}:8302' depends_on: generate_wallet_key: condition: service_completed_successfully + generate_libp2p_key: + condition: service_completed_successfully +``` + +## Data persistence + +Bind mounts preserve data across `docker compose down` / `up`: + +| Host path | Container path | Contents | +|-----------|---------------|----------| +| `./node/mina-config` | `/root/.mina-config` | Daemon config, wallet key, libp2p key, peers | + +## Verifying the deployment + +```bash +# Check container status +docker compose ps + +# Check sync status +docker compose exec mina_block_producer mina client status + +# Follow logs +docker compose logs -f mina_block_producer +``` + +## Clean start + +To wipe all data and start fresh: + +```bash +docker compose down +rm -rf node/ +docker compose up -d ``` From 7ff712a6ee575a886524713dfc33741cec6b7e7c Mon Sep 17 00:00:00 2001 From: dkijania Date: Wed, 6 May 2026 17:41:18 +0200 Subject: [PATCH 2/2] Rewrite all four docker-compose pages as reference wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces inline docker-compose YAML in the four node-operator pages (block-producer-node, archive-node, snark-workers, seed-peers) with narrative wrappers that link to canonical recipes maintained in MinaProtocol/mina, mirroring the existing pattern in docs/exchange-operators/rosetta/docker-compose.mdx. The canonical recipes live in MinaProtocol/mina#18827: - src/app/cli/docker-compose/block-producer/ - src/app/cli/docker-compose/snark-worker/ - src/app/cli/docker-compose/seed-peer/ - src/app/archive/docker-compose/ Each page now follows the Rosetta section order: Quick start / Services overview / Configuration tables / Data persistence / Make targets / Verifying the deployment / Clean start. Eliminates the inline-YAML drift problem — image tags, image names, and daemon flags now live in one place (the mina repo) instead of being maintained in parallel across docs2 mdx files. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../archive-node/docker-compose.mdx | 242 ++--- .../block-producer-node/docker-compose.mdx | 182 ++-- .../seed-peers/docker-compose.mdx | 173 ++-- .../snark-workers/docker-compose.mdx | 252 +++--- static/llms-full.txt | 832 +++++++++++------- 5 files changed, 872 insertions(+), 809 deletions(-) diff --git a/docs/node-operators/archive-node/docker-compose.mdx b/docs/node-operators/archive-node/docker-compose.mdx index 0c21b3cea..f3b05837a 100644 --- a/docs/node-operators/archive-node/docker-compose.mdx +++ b/docs/node-operators/archive-node/docker-compose.mdx @@ -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 @@ -10,7 +10,11 @@ keywords: # Docker Compose Archive -Run a Mina archive node using Docker Compose. The setup includes a PostgreSQL database, a bootstrap service that imports the latest daily archive dump, the archive process, a Mina daemon, and a missing blocks guardian that monitors and recovers gaps in the archive database. +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 @@ -18,84 +22,72 @@ Run a Mina archive node using Docker Compose. The setup includes a PostgreSQL da Before running the commands below, review the [Configuration](#configuration) section to see all available options — including image tags, network selection, ports, and database settings. ::: -1. Create a project directory and save the files below: - ```bash -mkdir -p mina-archive && cd mina-archive -``` +git clone https://github.com/MinaProtocol/mina.git +cd mina/src/app/archive/docker-compose -2. Create the `.env` file (see [Configuration](#configuration) for all variables): +# For mainnet +cp example.mainnet.env .env -```bash -# .env -MINA_DAEMON_IMAGE=minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet -MINA_ARCHIVE_IMAGE=minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet -MINA_NETWORK=mainnet -MINA_PEERLIST_URL=https://bootnodes.minaprotocol.com/networks/mainnet.txt -MINA_LIBP2P_PASS= -POSTGRES_PASSWORD=postgres -POSTGRES_PORT=5432 -MINA_REST_PORT=3085 -MINA_P2P_PORT=8302 -MINA_ARCHIVE_PORT=3086 -ARCHIVE_DUMP_BASE_URL=https://storage.googleapis.com/mina-archive-dumps -ARCHIVE_DUMP_PREFIX=mainnet-archive-dump -GUARDIAN_PRECOMPUTED_BLOCKS_URL=https://673156464838-mina-precomputed-blocks.s3.us-west-2.amazonaws.com/mainnet -``` +# For devnet +cp example.devnet.env .env -3. Create the `docker-compose.yml` (see [Docker Compose file](#docker-compose-file)). +# Edit .env — set MINA_LIBP2P_PASS and review POSTGRES_PASSWORD +vi .env -4. Start the services: - -```bash +# Start services docker compose up -d -# Follow logs -docker compose logs -f +# 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. +All configuration is done through a single `.env` file. Key variables: ### Docker images -| Variable | Description | Example | -|----------|-------------|---------| -| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | `minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet` | -| `MINA_ARCHIVE_IMAGE` | Mina archive Docker image | `minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet` | +| Variable | Description | +|----------|-------------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | +| `MINA_ARCHIVE_IMAGE` | Mina archive Docker image | -For devnet, use the o1Labs GCR images: -- Daemon: `gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet` -- Archive: `gcr.io/o1labs-192920/mina-archive:3.3.0-alpha1-6929a7e-bullseye-devnet` +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 | Example | -|----------|-------------|---------| -| `MINA_NETWORK` | Network name | `mainnet` or `devnet` | -| `MINA_PEERLIST_URL` | Bootstrap peers URL | `https://bootnodes.minaprotocol.com/networks/mainnet.txt` | -| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | — | +| 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` | `5432` | Host port mapped to PostgreSQL | +| `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 | -### Database - -| Variable | Default | Description | -|----------|---------|-------------| -| `POSTGRES_PASSWORD` | `postgres` | PostgreSQL password | - ### Archive bootstrap | Variable | Description | @@ -104,113 +96,6 @@ For devnet, use the o1Labs GCR images: | `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 | -## Docker Compose file - -```yaml -services: - postgres: - image: postgres:17 - restart: always - environment: - POSTGRES_PASSWORD: ${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: - - '${POSTGRES_PORT:-5432}:5432' - bootstrap_db: - image: '${MINA_ARCHIVE_IMAGE}' - command: > - bash -c ' - curl -O ${ARCHIVE_DUMP_BASE_URL}/${ARCHIVE_DUMP_PREFIX}-$$(date +%F_0000).sql.tar.gz; - tar -zxvf ${ARCHIVE_DUMP_PREFIX}-$$(date +%F_0000).sql.tar.gz; - psql postgres://postgres:${POSTGRES_PASSWORD:-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_PASSWORD:-postgres}@postgres:5432/archive -f ${ARCHIVE_DUMP_PREFIX}-$$(date +%F_0000).sql; - ' - depends_on: - postgres: - condition: service_healthy - missing_blocks_guardian: - image: '${MINA_ARCHIVE_IMAGE}' - 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=${GUARDIAN_PRECOMPUTED_BLOCKS_URL}; - export MINA_NETWORK=${MINA_NETWORK}; - export PG_CONN=postgres://postgres:${POSTGRES_PASSWORD:-postgres}@postgres:5432/archive; - while true; do bash missing-blocks-guardian-command.sh; sleep 600; done - ' - depends_on: - bootstrap_db: - condition: service_completed_successfully - mina_archive: - image: '${MINA_ARCHIVE_IMAGE}' - restart: always - command: - - mina-archive - - run - - --postgres-uri - - postgres://postgres:${POSTGRES_PASSWORD:-postgres}@postgres:5432/archive - - --server-port - - "${MINA_ARCHIVE_PORT:-3086}" - volumes: - - './archive/data:/data' - depends_on: - bootstrap_db: - condition: service_completed_successfully - mina_node: - image: '${MINA_DAEMON_IMAGE}' - restart: always - environment: - MINA_LIBP2P_PASS: ${MINA_LIBP2P_PASS} - healthcheck: - test: ["CMD-SHELL", "mina client status"] - interval: 60s - timeout: 10s - retries: 100 - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --archive-address mina_archive:${MINA_ARCHIVE_PORT:-3086} \ - --peer-list-url ${MINA_PEERLIST_URL} \ - --insecure-rest-server \ - --rest-port ${MINA_REST_PORT:-3085} \ - --config-directory /root/.mina-config \ - --file-log-rotations 500 \ - --generate-genesis-proof true \ - --log-json - ' - ports: - - '${MINA_REST_PORT:-3085}:${MINA_REST_PORT:-3085}' - - '${MINA_P2P_PORT:-8302}:8302' - volumes: - - './mina_node/.mina-config:/root/.mina-config' - depends_on: - bootstrap_db: - condition: service_completed_successfully -``` - -## Services overview - -| Service | Description | Default Port | -|---------|-------------|--------------| -| **postgres** | PostgreSQL 17 with health checks | 5432 | -| **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 with GraphQL API | 3085 (GraphQL), 8302 (P2P) | -| **missing_blocks_guardian** | Monitors and recovers missing blocks between nightly dumps and chain tip | — | - ## Data persistence Bind mounts preserve data across `docker compose down` / `up`: @@ -221,34 +106,49 @@ Bind mounts preserve data across `docker compose down` / `up`: | `./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 -# Check container status -docker compose ps +make health -# Check sync status docker compose exec mina_node mina client status -# Query GraphQL API -curl -s http://localhost:${MINA_REST_PORT:-3085}/graphql \ - -H 'Content-Type: application/json' \ - -d '{"query": "{ syncStatus }"}' | jq . +# 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_PASSWORD:-postgres}@localhost:${POSTGRES_PORT:-5432}/archive +psql postgres://postgres:postgres@localhost:5433/archive + +# Latest block in archive +psql postgres://postgres:postgres@localhost:5433/archive \ + -tAc "SELECT max(height) FROM blocks" -# Check archive block height -psql postgres://postgres:${POSTGRES_PASSWORD:-postgres}@localhost:${POSTGRES_PORT:-5432}/archive \ - -c "SELECT MAX(height) FROM blocks;" +# Missing-blocks guardian progress +docker compose logs --tail=50 missing_blocks_guardian ``` ## Clean start -To wipe all data and start fresh: - ```bash -docker compose down -rm -rf archive/ mina_node/ +make clean docker compose up -d ``` + +:::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). +::: diff --git a/docs/node-operators/block-producer-node/docker-compose.mdx b/docs/node-operators/block-producer-node/docker-compose.mdx index 432105c90..665885ca6 100644 --- a/docs/node-operators/block-producer-node/docker-compose.mdx +++ b/docs/node-operators/block-producer-node/docker-compose.mdx @@ -1,7 +1,7 @@ --- title: Docker Compose Block Producer Node sidebar_label: Docker Compose example -description: Example of how to run a Mina Block Producer node using Docker Compose. +description: Run a Mina Block Producer node using Docker Compose. keywords: - mina node - docker compose @@ -10,7 +10,11 @@ keywords: # Docker Compose Block Producer -Run a Mina Block Producer node using Docker Compose. The setup includes a one-shot key generation service and the block producer daemon. +Run a Mina block producer node as a separate container, with control over resource allocation, logging, and restarts. + +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/cli/docker-compose/block-producer/`](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/block-producer)** ## Quick start @@ -18,134 +22,69 @@ Run a Mina Block Producer node using Docker Compose. The setup includes a one-sh Before running the commands below, review the [Configuration](#configuration) section to see all available options — including image tags, network selection, and ports. ::: -1. Create a project directory and save the files below: - ```bash -mkdir -p mina-block-producer && cd mina-block-producer -``` - -2. Create the `.env` file (see [Configuration](#configuration) for all variables): +git clone https://github.com/MinaProtocol/mina.git +cd mina/src/app/cli/docker-compose/block-producer -```bash -# .env -MINA_DAEMON_IMAGE=minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet -MINA_NETWORK=mainnet -MINA_PEERLIST_URL=https://bootnodes.minaprotocol.com/networks/mainnet.txt -MINA_PRIVKEY_PASS= -MINA_LIBP2P_PASS= -MINA_P2P_PORT=8302 -``` +# For mainnet +cp example.mainnet.env .env -3. Create the `docker-compose.yml` (see [Docker Compose file](#docker-compose-file)). +# For devnet +cp example.devnet.env .env -4. Start the services: +# Edit .env — set MINA_PRIVKEY_PASS and MINA_LIBP2P_PASS (both required) +vi .env -```bash -# Generate keys and start the block producer +# Start services docker compose up -d -# Follow logs -docker compose logs -f mina_block_producer +# Or use make shortcuts +make mainnet # copies mainnet env and starts services +make devnet # copies devnet env and starts services ``` +## Services overview + +| Service | Description | Default Port | +|---------|-------------|--------------| +| **generate_wallet_key** | One-shot: generates the block producer keypair (skipped if one already exists) | — | +| **mina_block_producer** | Mina daemon running with `--block-producer-key` | 3085 (GraphQL), 8302 (P2P) | + ## Configuration -All configuration is done through a single `.env` file. +All configuration is done through a single `.env` file. Key variables: ### Docker image -| Variable | Description | Example | -|----------|-------------|---------| -| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | `minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet` | +| Variable | Description | +|----------|-------------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | -For devnet, use the o1Labs GCR image: `gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet` +For mainnet, the image is pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol) (`minaprotocol/mina-daemon`). +For devnet, the image is pulled from the o1Labs GCR registry. ### Network -| Variable | Description | Example | -|----------|-------------|---------| -| `MINA_NETWORK` | Network name | `mainnet` or `devnet` | -| `MINA_PEERLIST_URL` | Bootstrap peers URL | `https://bootnodes.minaprotocol.com/networks/mainnet.txt` | -| `MINA_PRIVKEY_PASS` | Passphrase for the wallet key (required) | — | -| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | — | +| Variable | Description | +|----------|-------------| +| `MINA_NETWORK` | `mainnet` or `devnet` | +| `MINA_PEERLIST_URL` | Bootstrap peers URL | +| `MINA_PRIVKEY_PASS` | Passphrase for the block producer key (required) | +| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | ### Ports | Variable | Default | Description | |----------|---------|-------------| +| `MINA_REST_PORT` | `3085` | GraphQL API port | | `MINA_P2P_PORT` | `8302` | P2P networking port (must be reachable from the internet) | -## Docker Compose file - -```yaml -services: - generate_wallet_key: - image: '${MINA_DAEMON_IMAGE}' - environment: - MINA_PRIVKEY_PASS: ${MINA_PRIVKEY_PASS} - entrypoint: [] - command: > - bash -c ' - if [ -f /root/.mina-config/keys/wallet-key ]; then - echo "Wallet key already exists, skipping generation" - exit 0 - fi - mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key - chmod 0700 /root/.mina-config/keys - chmod 0600 /root/.mina-config/keys/wallet-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - generate_libp2p_key: - image: '${MINA_DAEMON_IMAGE}' - environment: - MINA_LIBP2P_PASS: ${MINA_LIBP2P_PASS} - entrypoint: [] - command: > - bash -c ' - if [ -f /root/.mina-config/keys/libp2p-key ]; then - echo "Libp2p key already exists, skipping generation" - exit 0 - fi - mina libp2p generate-keypair -privkey-path /root/.mina-config/keys/libp2p-key - chmod 0700 /root/.mina-config/keys - chmod 0600 /root/.mina-config/keys/libp2p-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - mina_block_producer: - image: '${MINA_DAEMON_IMAGE}' - restart: always - environment: - MINA_PRIVKEY_PASS: ${MINA_PRIVKEY_PASS} - MINA_LIBP2P_PASS: ${MINA_LIBP2P_PASS} - RAYON_NUM_THREADS: 6 - healthcheck: - test: ["CMD-SHELL", "mina client status"] - interval: 60s - timeout: 10s - retries: 100 - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url ${MINA_PEERLIST_URL} \ - --block-producer-key /root/.mina-config/keys/wallet-key \ - --libp2p-keypair /root/.mina-config/keys/libp2p-key \ - --config-directory /root/.mina-config \ - --file-log-rotations 500 \ - --generate-genesis-proof true \ - --log-json - ' - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '${MINA_P2P_PORT:-8302}:8302' - depends_on: - generate_wallet_key: - condition: service_completed_successfully - generate_libp2p_key: - condition: service_completed_successfully +## Funding the block producer + +After the wallet key is generated, your block producer's public key is stored at `./mina_node/.mina-config/keys/wallet-key.pub` on the host. Block production only kicks in once that account holds (or is delegated) staking funds. + +```bash +cat ./mina_node/.mina-config/keys/wallet-key.pub ``` ## Data persistence @@ -154,27 +93,40 @@ Bind mounts preserve data across `docker compose down` / `up`: | Host path | Container path | Contents | |-----------|---------------|----------| -| `./node/mina-config` | `/root/.mina-config` | Daemon config, wallet key, libp2p key, peers | +| `./mina_node/.mina-config` | `/root/.mina-config` | Daemon config, block producer key, libp2p key, 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 `.mina-config` | +| `make logs` | Follow logs | +| `make status` | Show container status | +| `make health` | Check GraphQL endpoint, sync status, and container summary | ## Verifying the deployment +Once services are running and the daemon is connected to peers: + ```bash -# Check container status -docker compose ps +make health -# Check sync status docker compose exec mina_block_producer mina client status -# Follow logs -docker compose logs -f mina_block_producer +curl -s http://localhost:3085/graphql -H 'Content-Type: application/json' \ + -d '{"query":"{ daemonStatus { syncStatus blockchainLength } }"}' | jq . ``` ## Clean start -To wipe all data and start fresh: - ```bash -docker compose down -rm -rf node/ +make clean docker compose up -d ``` + +:::warning +`make clean` removes `./mina_node/.mina-config`, which contains your **block producer key**. Back up `./mina_node/.mina-config/keys/` before running it if you want to keep the key. +::: diff --git a/docs/node-operators/seed-peers/docker-compose.mdx b/docs/node-operators/seed-peers/docker-compose.mdx index 077b8a1a8..22ace0c18 100644 --- a/docs/node-operators/seed-peers/docker-compose.mdx +++ b/docs/node-operators/seed-peers/docker-compose.mdx @@ -1,7 +1,7 @@ --- title: Docker Compose Seed Peers sidebar_label: Docker Compose example -description: Example of how to run a Mina Seed node using Docker Compose. +description: Run a Mina Seed node using Docker Compose. keywords: - mina seed node - docker compose @@ -9,72 +9,129 @@ keywords: # Docker Compose Seed Peer -This example demonstrates how to run a Mina Seed node using Docker Compose for the Mainnet network. This Docker Compose setup includes a Mina seed node, and a script to generate a libp2p key. - -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: - generate_libp2p_key: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - environment: - MINA_LIBP2P_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina libp2p generate-keypair -privkey-path /root/.mina-config/keys/libp2p-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/libp2p-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - 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 - environment: - MINA_LIBP2P_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ - --libp2p-keypair /root/.mina-config/keys/libp2p-key \ - --seed - ' - # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '8302:8302' - depends_on: - generate_libp2p_key: - condition: service_completed_successfully +Run a Mina seed node — a publicly reachable peer that bootstraps newcomers into the network. + +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/cli/docker-compose/seed-peer/`](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/seed-peer)** + +## Quick start + +:::tip +Before running the commands below, review the [Configuration](#configuration) section. +::: + +```bash +git clone https://github.com/MinaProtocol/mina.git +cd mina/src/app/cli/docker-compose/seed-peer + +# For mainnet +cp example.mainnet.env .env + +# For devnet +cp example.devnet.env .env + +# Edit .env — set MINA_LIBP2P_PASS (required) +vi .env + +# Start services +docker compose up -d + +# Or use make shortcuts +make mainnet +make devnet +``` + +## Services overview + +| Service | Description | Default Port | +|---------|-------------|--------------| +| **generate_libp2p_key** | One-shot: generates the libp2p keypair | — | +| **mina_seed** | Mina daemon running with `--seed` and `--libp2p-keypair` | 3085 (GraphQL), 8302 (P2P) | + +## Configuration + +### Docker image + +| Variable | Description | +|----------|-------------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | + +For mainnet, the image is pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol). +For devnet, the image is 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 | +|----------|---------|-------------| +| `MINA_REST_PORT` | `3085` | GraphQL API port | +| `MINA_P2P_PORT` | `8302` | P2P networking port (must be reachable from the internet) | + +## Building the relay-circuit address + +Once the seed has its libp2p peer ID, build a multiaddr that other nodes can use as a `--peer`: + +```bash +make peer-id ``` -To retrieve the status of the Mina Node, run `docker compose exec mina_node mina client status` +``` +/ip4//tcp//p2p/ +``` -In the client status, you should also see the _Adresses and ports_ section. +or with DNS: -```shell -Addresses and ports: - External IP: 35.197.32.58 - Bind IP: 0.0.0.0 - Libp2p PeerID: 12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 - Libp2p port: 8302 - Client port: 8301 ``` +/dns4/seed.example.com/tcp/8302/p2p/12D3Koo... +``` + +You can submit a PR to [`MinaFoundation/seeds`](https://github.com/MinaFoundation/seeds) to be listed in the official seed peer list. + +## Data persistence + +| Host path | Container path | Contents | +|-----------|---------------|----------| +| `./mina_node/.mina-config` | `/root/.mina-config` | Daemon config, libp2p key, 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 `.mina-config` | +| `make logs` | Follow logs | +| `make status` | Show container status | +| `make peer-id` | Print this seed's libp2p peer ID | +| `make health` | Check GraphQL endpoint, peer ID, addresses, and container summary | + +## Verifying the deployment + +```bash +make health -Base on the above output, you can build you "relay circuit" address as follows: +docker compose exec mina_seed mina client status -```shell -/ip4/35.197.32.58/tcp/8302/p2p/12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 +curl -s http://localhost:3085/graphql -H 'Content-Type: application/json' \ + -d '{"query":"{ daemonStatus { peers { peerId } } }"}' | jq . ``` -If you prefer using a DNS instead of an IP address, you can use the following format: +## Clean start -```shell -/dns4/seed.example.com/tcp/8302/p2p/12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 +```bash +make clean +docker compose up -d ``` -Finally, you can add the relay circuit address the official Mina Seed Peers list by submitting a pull request to the [MinaFoundation/seeds](https://github.com/MinaFoundation/seeds) repository +:::warning +`make clean` removes `./mina_node/.mina-config`, including your **libp2p key**. Your seed's multiaddr will change after a clean restart. Back up `./mina_node/.mina-config/keys/libp2p-key*` if you've published the multiaddr anywhere. +::: diff --git a/docs/node-operators/snark-workers/docker-compose.mdx b/docs/node-operators/snark-workers/docker-compose.mdx index 467123ca3..80b38076b 100644 --- a/docs/node-operators/snark-workers/docker-compose.mdx +++ b/docs/node-operators/snark-workers/docker-compose.mdx @@ -8,144 +8,128 @@ keywords: - docker compose --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - # Docker Compose SNARK Workers -This example runs a SNARK coordinator and a SNARK worker together using Docker Compose. It includes a one-time init container that generates a wallet key. - -Save the following as `docker-compose.yml`, then start with `docker compose up -d`. Monitor logs with `docker compose logs -f`. - - - - -```yaml -services: - generate_wallet_key: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - environment: - MINA_PRIVKEY_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/wallet-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - mina_snark_coordinator: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - restart: always - environment: - MINA_PRIVKEY_PASS: PssW0rD - MINA_CLIENT_TRUSTLIST: "0.0.0.0/0" - healthcheck: - test: ["CMD-SHELL", "mina client status"] - interval: 60s - timeout: 10s - retries: 100 - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ - --snark-worker-fee 0.001 \ - --run-snark-coordinator $(cat /root/.mina-config/keys/wallet-key.pub) \ - --work-selection rand - ' - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '8302:8302' - depends_on: - generate_wallet_key: - condition: service_completed_successfully - mina_snark_worker: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - restart: always - entrypoint: [] - command: > - bash -c ' - mina internal \ - snark-worker \ - --daemon-address \ - mina_snark_coordinator:8301 \ - --proof-level full - ' - volumes: - - './node/mina-config:/root/.mina-config' - depends_on: - mina_snark_coordinator: - condition: service_healthy +Run a Mina SNARK coordinator and SNARK worker as separate containers. The coordinator is a Mina daemon configured to advertise SNARK work and collect fees; the worker is an internal process that produces proofs and submits them to the coordinator. + +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/cli/docker-compose/snark-worker/`](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/snark-worker)** + +## Quick start + +:::tip +Before running the commands below, review the [Configuration](#configuration) section — including SNARK fee, work selection, and proof level. +::: + +```bash +git clone https://github.com/MinaProtocol/mina.git +cd mina/src/app/cli/docker-compose/snark-worker + +# For mainnet +cp example.mainnet.env .env + +# For devnet +cp example.devnet.env .env + +# Edit .env — set MINA_PRIVKEY_PASS, MINA_LIBP2P_PASS, review MINA_SNARK_FEE +vi .env + +# Start services +docker compose up -d + +# Or use make shortcuts +make mainnet +make devnet ``` - - - -```yaml -services: - generate_wallet_key: - image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' - environment: - MINA_PRIVKEY_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/wallet-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - mina_snark_coordinator: - image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' - restart: always - environment: - MINA_PRIVKEY_PASS: PssW0rD - MINA_CLIENT_TRUSTLIST: "0.0.0.0/0" - healthcheck: - test: ["CMD-SHELL", "mina client status"] - interval: 60s - timeout: 10s - retries: 100 - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt \ - --snark-worker-fee 0.001 \ - --run-snark-coordinator $(cat /root/.mina-config/keys/wallet-key.pub) \ - --work-selection rand - ' - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '8302:8302' - depends_on: - generate_wallet_key: - condition: service_completed_successfully - mina_snark_worker: - image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' - restart: always - entrypoint: [] - command: > - bash -c ' - mina internal \ - snark-worker \ - --daemon-address \ - mina_snark_coordinator:8301 \ - --proof-level full - ' - volumes: - - './node/mina-config:/root/.mina-config' - depends_on: - mina_snark_coordinator: - condition: service_healthy +## Services overview + +| Service | Description | Default Port | +|---------|-------------|--------------| +| **generate_wallet_key** | One-shot: generates the SNARK fee account keypair | — | +| **mina_snark_coordinator** | Mina daemon with `--run-snark-coordinator` and `--snark-worker-fee` | 3085 (GraphQL), 8302 (P2P) | +| **mina_snark_worker** | `mina internal snark-worker` connected to the coordinator on port 8301 | — | + +## Scaling workers + +To run multiple workers against the same coordinator, duplicate the `mina_snark_worker` service in `docker-compose.yml` with a different name (e.g. `mina_snark_worker_2`). See the [README](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/snark-worker) for the full snippet. + +## Configuration + +All configuration is done through a single `.env` file. Key variables: + +### Docker image + +| Variable | Description | +|----------|-------------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image (used by both coordinator and worker) | + +For mainnet, images are pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol). +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_PRIVKEY_PASS` | Passphrase for the SNARK fee account key (required) | +| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | + +### Ports + +| Variable | Default | Description | +|----------|---------|-------------| +| `MINA_REST_PORT` | `3085` | GraphQL API port (coordinator) | +| `MINA_P2P_PORT` | `8302` | P2P networking port (coordinator) | +| `MINA_DAEMON_CLIENT_PORT` | `8301` | Daemon client port that the worker connects to (internal Docker network only) | + +### SNARK tunables + +| Variable | Default | Description | +|----------|---------|-------------| +| `MINA_SNARK_FEE` | `0.001` | Per-proof fee in MINA. Lower = more competitive but smaller revenue. | +| `MINA_WORK_SELECTION` | `rand` | `rand` (default) or `seq`. `rand` randomizes work selection across coordinators. | +| `MINA_PROOF_LEVEL` | `full` | `full` for production. `check` / `none` are for testing only. | + +## Data persistence + +| Host path | Container path | Contents | +|-----------|---------------|----------| +| `./mina_node/.mina-config` | `/root/.mina-config` | Coordinator daemon config, fee account key, 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 `.mina-config` | +| `make logs` | Follow logs | +| `make status` | Show container status | +| `make health` | Check GraphQL endpoint, coordinator client status, and container summary | + +## Verifying the deployment + +```bash +make health + +docker compose exec mina_snark_coordinator mina client status + +# Pending SNARK work in the pool +curl -s http://localhost:3085/graphql -H 'Content-Type: application/json' \ + -d '{"query":"{ snarkPool { workIds fee } }"}' | jq . ``` - - +## Clean start + +```bash +make clean +docker compose up -d +``` -To scale additional workers, duplicate the `mina_snark_worker` service with a different name (e.g. `mina_snark_worker_2`). +:::warning +`make clean` removes `./mina_node/.mina-config`, including your **SNARK fee account key**. Back up `./mina_node/.mina-config/keys/` before running it. +::: diff --git a/static/llms-full.txt b/static/llms-full.txt index a97144a6d..b4c603451 100644 --- a/static/llms-full.txt +++ b/static/llms-full.txt @@ -6811,100 +6811,148 @@ url: /node-operators/archive-node/docker-compose # 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 -``` - -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`. - -To retrieve the status of the Mina Node, run `docker compose exec mina_node mina client status` +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 +``` + +## Clean start + +```bash +make clean +docker compose up -d +``` + +:::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). +::: --- url: /node-operators/archive-node/getting-started @@ -7370,49 +7418,127 @@ url: /node-operators/block-producer-node/docker-compose # Docker Compose Block Producer -This example demonstrates how to run a Mina Block Producer node using Docker Compose for the Mainnet network. The Docker Compose setup includes a Mina Block Producer node, and another script to generate a wallet key. - -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: - generate_wallet_key: - 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 - environment: - MINA_PRIVKEY_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/wallet-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - mina_block_producer: - 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 - environment: - MINA_PRIVKEY_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ - --block-producer-key /root/.mina-config/keys/wallet-key - ' - # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '8302:8302' - depends_on: - generate_wallet_key: - condition: service_completed_successfully +Run a Mina block producer node as a separate container, with control over resource allocation, logging, and restarts. + +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/cli/docker-compose/block-producer/`](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/block-producer)** + +## Quick start + +:::tip +Before running the commands below, review the [Configuration](#configuration) section to see all available options — including image tags, network selection, and ports. +::: + +```bash +git clone https://github.com/MinaProtocol/mina.git +cd mina/src/app/cli/docker-compose/block-producer + +# For mainnet +cp example.mainnet.env .env + +# For devnet +cp example.devnet.env .env + +# Edit .env — set MINA_PRIVKEY_PASS and MINA_LIBP2P_PASS (both required) +vi .env + +# Start services +docker compose up -d + +# Or use make shortcuts +make mainnet # copies mainnet env and starts services +make devnet # copies devnet env and starts services +``` + +## Services overview + +| Service | Description | Default Port | +|---------|-------------|--------------| +| **generate_wallet_key** | One-shot: generates the block producer keypair (skipped if one already exists) | — | +| **mina_block_producer** | Mina daemon running with `--block-producer-key` | 3085 (GraphQL), 8302 (P2P) | + +## Configuration + +All configuration is done through a single `.env` file. Key variables: + +### Docker image + +| Variable | Description | +|----------|-------------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | + +For mainnet, the image is pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol) (`minaprotocol/mina-daemon`). +For devnet, the image is pulled from the o1Labs GCR registry. + +### Network + +| Variable | Description | +|----------|-------------| +| `MINA_NETWORK` | `mainnet` or `devnet` | +| `MINA_PEERLIST_URL` | Bootstrap peers URL | +| `MINA_PRIVKEY_PASS` | Passphrase for the block producer key (required) | +| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | + +### Ports + +| Variable | Default | Description | +|----------|---------|-------------| +| `MINA_REST_PORT` | `3085` | GraphQL API port | +| `MINA_P2P_PORT` | `8302` | P2P networking port (must be reachable from the internet) | + +## Funding the block producer + +After the wallet key is generated, your block producer's public key is stored at `./mina_node/.mina-config/keys/wallet-key.pub` on the host. Block production only kicks in once that account holds (or is delegated) staking funds. + +```bash +cat ./mina_node/.mina-config/keys/wallet-key.pub +``` + +## Data persistence + +Bind mounts preserve data across `docker compose down` / `up`: + +| Host path | Container path | Contents | +|-----------|---------------|----------| +| `./mina_node/.mina-config` | `/root/.mina-config` | Daemon config, block producer key, libp2p key, 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 `.mina-config` | +| `make logs` | Follow logs | +| `make status` | Show container status | +| `make health` | Check GraphQL endpoint, sync status, and container summary | + +## Verifying the deployment + +Once services are running and the daemon is connected to peers: + +```bash +make health + +docker compose exec mina_block_producer mina client status + +curl -s http://localhost:3085/graphql -H 'Content-Type: application/json' \ + -d '{"query":"{ daemonStatus { syncStatus blockchainLength } }"}' | jq . ``` +## Clean start + +```bash +make clean +docker compose up -d +``` + +:::warning +`make clean` removes `./mina_node/.mina-config`, which contains your **block producer key**. Back up `./mina_node/.mina-config/keys/` before running it if you want to keep the key. +::: + --- url: /node-operators/block-producer-node/getting-started --- @@ -10619,75 +10745,132 @@ url: /node-operators/seed-peers/docker-compose # Docker Compose Seed Peer -This example demonstrates how to run a Mina Seed node using Docker Compose for the Mainnet network. This Docker Compose setup includes a Mina seed node, and a script to generate a libp2p key. - -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: - generate_libp2p_key: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - environment: - MINA_LIBP2P_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina libp2p generate-keypair -privkey-path /root/.mina-config/keys/libp2p-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/libp2p-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - 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 - environment: - MINA_LIBP2P_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ - --libp2p-keypair /root/.mina-config/keys/libp2p-key \ - --seed - ' - # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '8302:8302' - depends_on: - generate_libp2p_key: - condition: service_completed_successfully -``` - -To retrieve the status of the Mina Node, run `docker compose exec mina_node mina client status` - -In the client status, you should also see the _Adresses and ports_ section. - -```shell -Addresses and ports: - External IP: 35.197.32.58 - Bind IP: 0.0.0.0 - Libp2p PeerID: 12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 - Libp2p port: 8302 - Client port: 8301 -``` - -Base on the above output, you can build you "relay circuit" address as follows: - -```shell -/ip4/35.197.32.58/tcp/8302/p2p/12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 -``` - -If you prefer using a DNS instead of an IP address, you can use the following format: - -```shell -/dns4/seed.example.com/tcp/8302/p2p/12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 -``` - -Finally, you can add the relay circuit address the official Mina Seed Peers list by submitting a pull request to the [MinaFoundation/seeds](https://github.com/MinaFoundation/seeds) repository +Run a Mina seed node — a publicly reachable peer that bootstraps newcomers into the network. + +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/cli/docker-compose/seed-peer/`](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/seed-peer)** + +## Quick start + +:::tip +Before running the commands below, review the [Configuration](#configuration) section. +::: + +```bash +git clone https://github.com/MinaProtocol/mina.git +cd mina/src/app/cli/docker-compose/seed-peer + +# For mainnet +cp example.mainnet.env .env + +# For devnet +cp example.devnet.env .env + +# Edit .env — set MINA_LIBP2P_PASS (required) +vi .env + +# Start services +docker compose up -d + +# Or use make shortcuts +make mainnet +make devnet +``` + +## Services overview + +| Service | Description | Default Port | +|---------|-------------|--------------| +| **generate_libp2p_key** | One-shot: generates the libp2p keypair | — | +| **mina_seed** | Mina daemon running with `--seed` and `--libp2p-keypair` | 3085 (GraphQL), 8302 (P2P) | + +## Configuration + +### Docker image + +| Variable | Description | +|----------|-------------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image | + +For mainnet, the image is pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol). +For devnet, the image is 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 | +|----------|---------|-------------| +| `MINA_REST_PORT` | `3085` | GraphQL API port | +| `MINA_P2P_PORT` | `8302` | P2P networking port (must be reachable from the internet) | + +## Building the relay-circuit address + +Once the seed has its libp2p peer ID, build a multiaddr that other nodes can use as a `--peer`: + +```bash +make peer-id +``` + +``` +/ip4//tcp//p2p/ +``` + +or with DNS: + +``` +/dns4/seed.example.com/tcp/8302/p2p/12D3Koo... +``` + +You can submit a PR to [`MinaFoundation/seeds`](https://github.com/MinaFoundation/seeds) to be listed in the official seed peer list. + +## Data persistence + +| Host path | Container path | Contents | +|-----------|---------------|----------| +| `./mina_node/.mina-config` | `/root/.mina-config` | Daemon config, libp2p key, 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 `.mina-config` | +| `make logs` | Follow logs | +| `make status` | Show container status | +| `make peer-id` | Print this seed's libp2p peer ID | +| `make health` | Check GraphQL endpoint, peer ID, addresses, and container summary | + +## Verifying the deployment + +```bash +make health + +docker compose exec mina_seed mina client status + +curl -s http://localhost:3085/graphql -H 'Content-Type: application/json' \ + -d '{"query":"{ daemonStatus { peers { peerId } } }"}' | jq . +``` + +## Clean start + +```bash +make clean +docker compose up -d +``` + +:::warning +`make clean` removes `./mina_node/.mina-config`, including your **libp2p key**. Your seed's multiaddr will change after a clean restart. Back up `./mina_node/.mina-config/keys/libp2p-key*` if you've published the multiaddr anywhere. +::: --- url: /node-operators/seed-peers/generating-a-libp2p-keypair @@ -10853,142 +11036,129 @@ url: /node-operators/snark-workers/docker-compose # Docker Compose SNARK Workers -This example runs a SNARK coordinator and a SNARK worker together using Docker Compose. It includes a one-time init container that generates a wallet key. +Run a Mina SNARK coordinator and SNARK worker as separate containers. The coordinator is a Mina daemon configured to advertise SNARK work and collect fees; the worker is an internal process that produces proofs and submits them to the coordinator. -Save the following as `docker-compose.yml`, then start with `docker compose up -d`. Monitor logs with `docker compose logs -f`. +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/cli/docker-compose/snark-worker/`](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/snark-worker)** + +## Quick start + +:::tip +Before running the commands below, review the [Configuration](#configuration) section — including SNARK fee, work selection, and proof level. +::: + +```bash +git clone https://github.com/MinaProtocol/mina.git +cd mina/src/app/cli/docker-compose/snark-worker -```yaml -services: - generate_wallet_key: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - environment: - MINA_PRIVKEY_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/wallet-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - mina_snark_coordinator: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - restart: always - environment: - MINA_PRIVKEY_PASS: PssW0rD - MINA_CLIENT_TRUSTLIST: "0.0.0.0/0" - healthcheck: - test: ["CMD-SHELL", "mina client status"] - interval: 60s - timeout: 10s - retries: 100 - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ - --snark-worker-fee 0.001 \ - --run-snark-coordinator $(cat /root/.mina-config/keys/wallet-key.pub) \ - --work-selection rand - ' - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '8302:8302' - depends_on: - generate_wallet_key: - condition: service_completed_successfully - mina_snark_worker: - image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' - restart: always - entrypoint: [] - command: > - bash -c ' - mina internal \ - snark-worker \ - --daemon-address \ - mina_snark_coordinator:8301 \ - --proof-level full - ' - volumes: - - './node/mina-config:/root/.mina-config' - depends_on: - mina_snark_coordinator: - condition: service_healthy +# For mainnet +cp example.mainnet.env .env + +# For devnet +cp example.devnet.env .env + +# Edit .env — set MINA_PRIVKEY_PASS, MINA_LIBP2P_PASS, review MINA_SNARK_FEE +vi .env + +# Start services +docker compose up -d + +# Or use make shortcuts +make mainnet +make devnet ``` - - +## Services overview + +| Service | Description | Default Port | +|---------|-------------|--------------| +| **generate_wallet_key** | One-shot: generates the SNARK fee account keypair | — | +| **mina_snark_coordinator** | Mina daemon with `--run-snark-coordinator` and `--snark-worker-fee` | 3085 (GraphQL), 8302 (P2P) | +| **mina_snark_worker** | `mina internal snark-worker` connected to the coordinator on port 8301 | — | + +## Scaling workers + +To run multiple workers against the same coordinator, duplicate the `mina_snark_worker` service in `docker-compose.yml` with a different name (e.g. `mina_snark_worker_2`). See the [README](https://github.com/MinaProtocol/mina/tree/develop/src/app/cli/docker-compose/snark-worker) for the full snippet. + +## Configuration + +All configuration is done through a single `.env` file. Key variables: + +### Docker image + +| Variable | Description | +|----------|-------------| +| `MINA_DAEMON_IMAGE` | Mina daemon Docker image (used by both coordinator and worker) | + +For mainnet, images are pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol). +For devnet, images are pulled from the o1Labs GCR registry. -```yaml -services: - generate_wallet_key: - image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' - environment: - MINA_PRIVKEY_PASS: PssW0rD - entrypoint: [] - command: > - bash -c ' - mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key - chmod -R 0700 /root/.mina-config/keys - chmod -R 0600 /root/.mina-config/keys/wallet-key - ' - volumes: - - './node/mina-config:/root/.mina-config' - mina_snark_coordinator: - image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' - restart: always - environment: - MINA_PRIVKEY_PASS: PssW0rD - MINA_CLIENT_TRUSTLIST: "0.0.0.0/0" - healthcheck: - test: ["CMD-SHELL", "mina client status"] - interval: 60s - timeout: 10s - retries: 100 - entrypoint: [] - command: > - bash -c ' - mina daemon \ - --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt \ - --snark-worker-fee 0.001 \ - --run-snark-coordinator $(cat /root/.mina-config/keys/wallet-key.pub) \ - --work-selection rand - ' - volumes: - - './node/mina-config:/root/.mina-config' - ports: - - '8302:8302' - depends_on: - generate_wallet_key: - condition: service_completed_successfully - mina_snark_worker: - image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' - restart: always - entrypoint: [] - command: > - bash -c ' - mina internal \ - snark-worker \ - --daemon-address \ - mina_snark_coordinator:8301 \ - --proof-level full - ' - volumes: - - './node/mina-config:/root/.mina-config' - depends_on: - mina_snark_coordinator: - condition: service_healthy +### Network + +| Variable | Description | +|----------|-------------| +| `MINA_NETWORK` | `mainnet` or `devnet` | +| `MINA_PEERLIST_URL` | Bootstrap peers URL | +| `MINA_PRIVKEY_PASS` | Passphrase for the SNARK fee account key (required) | +| `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | + +### Ports + +| Variable | Default | Description | +|----------|---------|-------------| +| `MINA_REST_PORT` | `3085` | GraphQL API port (coordinator) | +| `MINA_P2P_PORT` | `8302` | P2P networking port (coordinator) | +| `MINA_DAEMON_CLIENT_PORT` | `8301` | Daemon client port that the worker connects to (internal Docker network only) | + +### SNARK tunables + +| Variable | Default | Description | +|----------|---------|-------------| +| `MINA_SNARK_FEE` | `0.001` | Per-proof fee in MINA. Lower = more competitive but smaller revenue. | +| `MINA_WORK_SELECTION` | `rand` | `rand` (default) or `seq`. `rand` randomizes work selection across coordinators. | +| `MINA_PROOF_LEVEL` | `full` | `full` for production. `check` / `none` are for testing only. | + +## Data persistence + +| Host path | Container path | Contents | +|-----------|---------------|----------| +| `./mina_node/.mina-config` | `/root/.mina-config` | Coordinator daemon config, fee account key, 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 `.mina-config` | +| `make logs` | Follow logs | +| `make status` | Show container status | +| `make health` | Check GraphQL endpoint, coordinator client status, and container summary | + +## Verifying the deployment + +```bash +make health + +docker compose exec mina_snark_coordinator mina client status + +# Pending SNARK work in the pool +curl -s http://localhost:3085/graphql -H 'Content-Type: application/json' \ + -d '{"query":"{ snarkPool { workIds fee } }"}' | jq . ``` - - +## Clean start -To scale additional workers, duplicate the `mina_snark_worker` service with a different name (e.g. `mina_snark_worker_2`). +```bash +make clean +docker compose up -d +``` + +:::warning +`make clean` removes `./mina_node/.mina-config`, including your **SNARK fee account key**. Back up `./mina_node/.mina-config/keys/` before running it. +::: --- url: /node-operators/snark-workers/getting-started