Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
38 changes: 30 additions & 8 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,45 @@ export POSTGRES_PASSWORD="$(cat ./postgres.password)"

export POSTGRES_DB="cexplorer"

# We bring together the above variables into a database connection string:
export DB_SYNC_POSTGRES_CONNECTION_STRING="psql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB"


# To start with debug logs, add "-l debug" to APPEND_ARGS
# To expose safe rpc method to the host port 9944, add "--unsafe-rpc-external" to APPEND_ARGS or --validator
export APPEND_ARGS="--allow-private-ip --pool-limit 10 --trie-cache-size 0 --prometheus-external --rpc-external --rpc-cors all"


# Validator Values:
if [ ! -f node.privatekey ]; then
# generate node key like this:
DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run --rm -it docker.io/parity/subkey:latest generate-node-key | sed -n '2p' > midnight-node.privatekey
# Use the second line of output for NODE_KEY (that's what sed -n '2p' does)
# Node Key:
# Generate a unique node key for P2P networking
if [ ! -f midnight-node.privatekey ]; then
# Generate node key using parity/subkey
DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run --rm docker.io/parity/subkey:latest generate-node-key > midnight-node.privatekey
fi
export NODE_KEY="$(cat ./midnight-node.privatekey)"

# Indexer Values:
if [ ! -f indexer.secret ]; then
# Generate 32-byte hex secret for indexer
openssl rand -hex 32 > indexer.secret
fi
export INDEXER_SECRET="$(cat ./indexer.secret)"

#
# Mock mode vs Cardano stack:
# Set USE_MOCK=true to run midnight-node with mock Cardano (fast, for dev/testing)
# Set USE_MOCK=false (default) to run full Cardano stack (real blockchain data)
#
export USE_MOCK=${USE_MOCK:-false}

if [ "$USE_MOCK" = "true" ]; then
# Mock mode: Skip Cardano services and indexer
export COMPOSE_PROFILES=""
export DB_SYNC_POSTGRES_CONNECTION_STRING=""
echo "📝 Mock mode enabled - midnight-node will use mock Cardano data"
else
# Cardano stack mode: Run all services
export COMPOSE_PROFILES="cardano"
export DB_SYNC_POSTGRES_CONNECTION_STRING="psql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB"
fi

#
# Partner chains config:
#
Expand Down
11 changes: 11 additions & 0 deletions .envrc.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# overrides for preview
export MIDNIGHT_NODE_IMAGE="ghcr.io/midnight-ntwrk/midnight-node:0.17.0-rc.4"
export INDEXER_IMAGE="ghcr.io/midnight-ntwrk/indexer-standalone:3.0.0-alpha.5"
Copy link
Copy Markdown
Collaborator

@gilescope gilescope Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Node needs to publish to dockerhub for all named releases. (these referenced images aren't public)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gilescope Good catch on the ghcr.io images requiring auth. Is this blocking for the PR, or should we track it separately for the node team?

For context:

  • testnet-02 already uses public Docker Hub image (midnightnetwork/midnight-node:0.12.1)
  • preview/qanet use ghcr.io which needs GitHub authentication

export INDEXER_NETWORK_ID="Preview"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the network id lowercase?


# Mock mode configuration
export MOCK_REGISTRATIONS_FILE="res/mock-bridge-data/default-registrations.json"

# Well known addresses of network that allow discovery of all other nodes.
export BOOTNODES="/dns/midnight-node-boot-01/tcp/30333/ws/p2p/12D3KooWK66i7dtGVNSwDh9tTeqov1q6LSdWsRLJvTyzTCaywYgK \
/dns/midnight-node-boot-02/tcp/30333/ws/p2p/12D3KooWHqFfXFwb7WW4jwR8pr4BEf562v5M6c8K3CXAJq4Wx6ym"
5 changes: 5 additions & 0 deletions .envrc.qanet
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# overrides for qanet
export MIDNIGHT_NODE_IMAGE="ghcr.io/midnight-ntwrk/midnight-node:0.12.0-rc.3"
export INDEXER_IMAGE="ghcr.io/midnight-ntwrk/indexer-standalone:2.1.4"
export INDEXER_NETWORK_ID="QANet"

# Mock mode configuration
export MOCK_REGISTRATIONS_FILE="res/mock-bridge-data/qanet-mock.json"

# Well known addresses of network that allow discovery of all other nodes.
export BOOTNODES="/dns/boot-node-01.qanet.dev.midnight.network/tcp/30333/ws/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp \
Expand Down
7 changes: 6 additions & 1 deletion .envrc.testnet-02
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# overrides for testnet-02
export MIDNIGHT_NODE_IMAGE="midnightnetwork/midnight-node:0.12.0"
export MIDNIGHT_NODE_IMAGE="midnightnetwork/midnight-node:0.12.1"
export INDEXER_IMAGE="ghcr.io/midnight-ntwrk/indexer-standalone:2.1.4"
export INDEXER_NETWORK_ID="TestNet"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not TestNet-02 ? Honestly I think we should have lowercase for all these network ids.


# Mock mode configuration
export MOCK_REGISTRATIONS_FILE="res/mock-bridge-data/testnet-02-mock.json"

# These are well known addresses of a network that allow you to discover all the other nodes.
export BOOTNODES="/dns/boot-node-01.testnet-02.midnight.network/tcp/30333/ws/p2p/12D3KooWMjUq13USCvQR9Y6yFzYNYgTQBLNAcmc8psAuPx2UUdnB \
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/data
*.privatekey
*.password
*.secret
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have 1 not 3.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

ogmios_client.log
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ This allows for easy orchestration of the Midnight Node service.

1. Clone repository

2. In `.envrc` set CFG_PRESET to be the environment you wish to point to (E.g. testnet-02).
2. In `.envrc` set CFG_PRESET to be the environment you wish to point to. Available options:
- `qanet` - QA network
- `testnet-02` - TestNet 02
- `preview` - Preview network

3. run `direnv allow` to load the environment variables

4. Run `docker-compose up`

The `.envrc` file will automatically create a random private key and save it as `midnight-node.privatekey`.
The `.envrc` file will automatically create a random private key and save it as `midnight-node.privatekey` and a random secret for the indexer saved as `indexer.secret`.

The default `compose.yml` now includes both the Midnight Node and Indexer Standalone, providing a GraphQL API at `http://localhost:8088`.

Choose which compose files to use:

- `compose.yml` for Midnight Node
- `compose.yml` for Midnight Node + Indexer
- `compose-partner-chains.yml` for Cardano + DB Sync
- `proof-server.yml` for Local Proof Server

Expand Down
89 changes: 89 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,74 @@

volumes:
midnight-data-testnet: {}
indexer-data: {}
postgres-data: {}
cardano-ipc: {}
db-sync-data: {}

services:
postgres:
profiles: ["cardano"]
image: postgres:15.3
platform: linux/amd64
container_name: db-sync-postgres
restart: unless-stopped
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "${POSTGRES_PORT}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 5s
timeout: 5s
retries: 5

cardano-node:
profiles: ["cardano"]
image: ${CARDANO_IMAGE}
platform: linux/amd64
container_name: cardano-node
restart: unless-stopped
environment:
- NETWORK=${CARDANO_NETWORK}
- CARDANO_NODE_SOCKET_PATH=/ipc/node.socket
volumes:
- cardano-ipc:/ipc
- ${CARDANO_DATA_DIR}:/data
ports:
- "3001:3001"
healthcheck:
test: ["CMD-SHELL", "curl -f 127.0.0.1:12788 || exit 1"]
interval: 60s
timeout: 10s
retries: 5

cardano-db-sync:
profiles: ["cardano"]
image: ghcr.io/intersectmbo/cardano-db-sync:13.6.0.4
platform: linux/amd64
container_name: cardano-db-sync
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
cardano-node:
condition: service_healthy
environment:
- NETWORK=${CARDANO_NETWORK}
- POSTGRES_HOST=${POSTGRES_HOST}
- POSTGRES_PORT=${POSTGRES_PORT}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- cardano-ipc:/node-ipc
- db-sync-data:/var/lib/cexplorer

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have these in the other compose file:
cardano-db-sync
cardano-node
postgres

How about we just have one compose file and rely on docker compose profiles to turn sets of sevices on?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Everything is now in single compose.yml with profiles:

  • docker compose up → just midnight-node
  • docker compose --profile cardano up → adds Cardano stack + indexer
  • docker compose --profile ogmios up → adds Ogmios
  • docker compose --profile proof-server up → adds proof server

Deleted the legacy compose files as requested. Much cleaner now!

midnight-node-testnet:
container_name: midnight-node
restart: unless-stopped
Expand All @@ -38,3 +104,26 @@ services:
- ./data:/data
- ./envs/${CFG_PRESET}/pc-chain-config.json:/pc-chain-config.json
- midnight-data-testnet:/node

indexer-standalone:
profiles: ["cardano"]
container_name: indexer
restart: unless-stopped
image: ${INDEXER_IMAGE}
ports:
- "8088:8088" # GraphQL API
environment:
# v2.1.4 config structure (testnet-02, qanet)
- APP__CHAIN_INDEXER_APPLICATION__NETWORK_ID=${INDEXER_NETWORK_ID}
- APP__WALLET_INDEXER_APPLICATION__NETWORK_ID=${INDEXER_NETWORK_ID}
- APP__INFRA__API__NETWORK_ID=${INDEXER_NETWORK_ID}
# v3.x config structure (preview)
- APP__APPLICATION__NETWORK_ID=${INDEXER_NETWORK_ID}
- APP__INFRA__NODE__URL=ws://midnight-node:9944
- APP__INFRA__STORAGE__CNN_URL=/data/indexer.sqlite
- APP__INFRA__SECRET=${INDEXER_SECRET}
depends_on:
midnight-node-testnet:
condition: service_healthy
volumes:
- indexer-data:/data