Docker Compose SNARK Workers
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/
Quick start
Before running the commands below, review the Configuration section — including SNARK fee, work selection, and proof level.
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 --env-file .env up -d
# Or use make shortcuts
make mainnet
make devnet
Every docker compose command on this page passes --env-file .env. Docker Compose reads .env on its own, but other runtimes, such as Podman, do not.
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 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) |
Images, for mainnet and devnet, are pulled from Docker Hub.
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
make health
docker compose --env-file .env 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
make clean
docker compose --env-file .env up -d
make clean removes ./mina_node/.mina-config, including your SNARK fee account key. Back up ./mina_node/.mina-config/keys/ before running it.