Running a Testnet Node with Docker

This section walks you through running a Concordium Testnet Node with Docker.

In this guide, you'll learn how to run a node on your computer to participate in the Concordium network. This involves receiving blocks and transactions from other nodes and propagating information about blocks and transactions to nodes in the Concordium network. By following this guide, you'll achieve the following:

  1. Run a Concordium Node: Set up and run a node on your computer.

  2. Observe on Network Dashboard: Monitor your node's activity on the network dashboard.

  3. Query Blockchain State: Query the state of the Concordium blockchain directly from your machine.

Note: Stay informed about updates and changes that may affect you as a node runner by subscribing to the Mainnet or Testnet status page and checking release information on Discourse.

Understanding Running/Upgrading a Node

When running a Concordium node, it's essential to grasp key concepts related to Docker images, database storage, and version upgrades.

Docker Images

Concordium provides Docker images for both mainnet and testnet deployments. These images are meant to be utilized alongside docker-compose or similar tools. This guide offers a sample configuration using docker-compose.

Database Storage

The Concordium node requires a database stored on the host system to ensure data persistence when the Docker container stops. You can choose the database location on your host system, with common options being /var/lib/concordium-mainnet or /var/lib/concordium-testnet.

GRPC V2 Interface

Starting from version 4.5.0, Concordium introduces the GRPC V2 interface, which enhances node functionality. If you have custom configurations, ensure your settings align with the new API, specifically by including CONCORDIUM_NODE_GRPC2_LISTEN_PORT and CONCORDIUM_NODE_GRPC2_LISTEN_ADDRESS as outlined in the provided sample configurations.

Version Upgrades

When upgrading the Concordium node, following specific guidelines is crucial. You can only upgrade one minor version at a time or transition from the last release of major version X to major version X+1. Skipping versions is not supported.

However, for patches, skipping versions is permissible (e.g., upgrading from X.X.0 to X.X.3). If you are currently running version 4.2.3, you can migrate to the latest version directly. For versions older than 4.2.3, it's necessary to delete the existing database and follow the instructions outlined in the provided documentation.

Prerequisites

Before running a Concordium testnet node, ensure you have:

Step 1: Create Configuration

Create a configuration file named "testnet-node.yaml" with the following content:

# This is an example configuration for running the testnet node
version: '3'
services:
  testnet-node:
    container_name: testnet-node
    image: concordium/testnet-node:latest
    pull_policy: always
    environment:
      # Environment specific configuration
      # The url where IPs of the bootstrap nodes can be found.
      - CONCORDIUM_NODE_CONNECTION_BOOTSTRAP_NODES=bootstrap.testnet.concordium.com:8888
      # Where the genesis is located
      - CONCORDIUM_NODE_CONSENSUS_GENESIS_DATA_FILE=/testnet-genesis.dat
      # The url of the catchup file. This speeds up the catchup process.
      - CONCORDIUM_NODE_CONSENSUS_DOWNLOAD_BLOCKS_FROM=https://catchup.testnet.concordium.com/blocks.idx
      # General node configuration Data and config directories (it's OK if they
      # are the same). This should match the volume mount below. If the location
      # of the mount inside the container is changed, then these should be
      # changed accordingly as well.
      - CONCORDIUM_NODE_DATA_DIR=/mnt/data
      - CONCORDIUM_NODE_CONFIG_DIR=/mnt/data
      # The port on which the node will listen for incoming connections. This is a
      # port inside the container. It is mapped to an external port by the port
      # mapping in the `ports` section below. If the internal and external ports
      # are going to be different then you should also set
      # `CONCORDIUM_NODE_EXTERNAL_PORT` variable to what the external port value is.
      - CONCORDIUM_NODE_LISTEN_PORT=8889
      # Desired number of nodes to be connected to.
      - CONCORDIUM_NODE_CONNECTION_DESIRED_NODES=5
      # Maximum number of __nodes__ the node will be connected to.
      - CONCORDIUM_NODE_CONNECTION_MAX_ALLOWED_NODES=10
      # Address of the GRPC server
      - CONCORDIUM_NODE_RPC_SERVER_ADDR=0.0.0.0
      # And its port
      - CONCORDIUM_NODE_RPC_SERVER_PORT=10001
      # Address of the V2 GRPC server
      - CONCORDIUM_NODE_GRPC2_LISTEN_PORT=20001
      # And its port
      - CONCORDIUM_NODE_GRPC2_LISTEN_ADDRESS=0.0.0.0
      # Maximum number of __connections__ the node can have. This can temporarily be more than
      # the number of peers when incoming connections are processed. This limit
      # ensures that there cannot be too many of those.
      - CONCORDIUM_NODE_CONNECTION_HARD_CONNECTION_LIMIT=20
      # Number of threads to use to process network events. This should be
      # adjusted based on the resources the node has (in combination with
      # `CONCORDIUM_NODE_RUNTIME_HASKELL_RTS_FLAGS`) below.
      - CONCORDIUM_NODE_CONNECTION_THREAD_POOL_SIZE=2
      # The bootstrapping interval in seconds. This makes the node contact the
      # specified bootstrappers at a given interval to discover new peers.
      - CONCORDIUM_NODE_CONNECTION_BOOTSTRAPPING_INTERVAL=1800
      # Haskell RTS flags to pass to consensus. `-N2` means to use two threads
      # for consensus operations. `-I0` disables the idle garbage collector
      # which reduces CPU load for non-baking nodes.
      - CONCORDIUM_NODE_RUNTIME_HASKELL_RTS_FLAGS=-N2,-I0
    entrypoint: ["/concordium-node"]
    # Exposed ports. The ports the node listens on inside the container (defined
    # by `CONCORDIUM_NODE_LISTEN_PORT` and `CONCORDIUM_NODE_RPC_SERVER_PORT`)
    # should match what is defined here. When running multiple nodes the
    # external ports should be changed so as not to conflict.
    # In the mapping below, the first port is the `host` port, and the second
    # port is the `container` port. When the `container` port is changed the
    # relevant environment variable listed above must be changed as well. For
    # example, changing `10001:10001` to `10001:13000` would mean that
    # `CONCORDIUM_NODE_RPC_SERVER_PORT` should be set to `13000`. Otherwise
    # the node's gRPC interface will not be available from the host.
    ports:
    - "8889:8889"
    - "10001:10001"
    - "20001:20001"
    volumes:
    # The node's database should be stored in a persistent volume so that it
    # survives container restart. In this case we map the **host** directory
    # /var/lib/concordium-testnet to be used as the node's database directory.
    - /var/lib/concordium-testnet:/mnt/data
  # The collector reports the state of the node to the network dashboard. A node
  # can run without reporting to the network dashboard. Remove this section if
  # that is desired.
  testnet-node-collector:
    container_name: testnet-node-collector
    image: concordium/testnet-node:latest
    pull_policy: always
    environment:
      # Settings that should be customized by the user.
      - CONCORDIUM_NODE_COLLECTOR_NODE_NAME=docker-test
      # Environment specific settings.
      - CONCORDIUM_NODE_COLLECTOR_URL=https://dashboard.testnet.concordium.com/nodes/post
      # Collection settings.
      # How often to collect the statistics from the node.
      - CONCORDIUM_NODE_COLLECTOR_COLLECT_INTERVAL=5000
      # The URL where the node can be reached. Note that this will use the
      # docker created network which maps `testnet-node` to the internal IP of
      # the `testnet-node`. If the name of the node service is changed from
      # `testnet-node` then the name here must also be changed.
      - CONCORDIUM_NODE_COLLECTOR_GRPC_HOST=http://testnet-node:10001
    entrypoint: ["/node-collector"]

Step 2: Customize Configuration (Optional)

Customize the configuration file if necessary. You can do the following:

  • Modify the volume mount to map the database directory to a different location on the host system:

volumes:
   # The node's database should be stored in a persistent volume so that it
   # survives container restart. In this case we map the **host** directory
   # /var/lib/concordium-testnet to be used as the node's database directory.
   - /var/lib/concordium-testnet:/mnt/data
  • Modify the node name that appears on the network dashboard. The environment variable sets this:

- CONCORDIUM_NODE_COLLECTOR_NODE_NAME=docker-test

This name can be set to any non-empty string. If the name has spaces it should be quoted.

Step 3: Start the Node

Run the following command to start the node and collector:

docker-compose -f testnet-node.yaml up

Once you run this command, it starts your testnet-node-collector and testnet-node as follows:

The configurations start two containers, one running the node and another running the node collector that reports the node state to the network dashboard. If you wish to have the node running in the background, then add a -d option to the above command.

Note: The sample configuration always downloads the latest node image. It is good practice to choose the version deliberately. To choose a specific version, find the correct version in Docker Hub and change the image value from:

image: concordium/testnet-node:latest

to, e.g.,

image: concordium/testnet-node:4.2.3-0

Step 4: Enable Inbound Connections

By default, your Concordium node may only be able to connect to other nodes but not accept incoming connections. While this is acceptable for basic network participation, enabling inbound connections can enhance your node's role in the Concordium network.

Follow these steps to enable inbound connections:

  1. Identify Your Network Configuration: Determine whether your node is behind a firewall or home router.

  2. Configure Port Forwarding: Depending on your network and platform configuration, you may need to forward an external port to port 8889 on your router. This allows external nodes to connect to your Concordium node.

  3. Open Firewall Ports: If a firewall is enabled, ensure that port 8889 is open to incoming connections. This allows external nodes to communicate with your node. The exact method for configuring port forwarding and opening firewall ports varies depending on your router and operating system. Refer to your router's manual or consult online resources for specific instructions.

Enabling inbound connections enhances your Concordium node's ability to fully participate in the network. It will be able to send transactions and, if so configured, to bake and finalize.

Step 5: Retrieve Node Logs

The sample configuration presented above logs data using Docker’s default logging infrastructure. To retrieve the logs for the node, run the following command:

docker logs testnet-node

This outputs the logs to stdout.

Step 6: Migration from the Previous Docker Distribution

If you were using the previous Concordium Docker distribution, which utilized the concordium-software package containing a concordium-node binary, follow these steps to migrate:

  1. Stop the Running Node:

    Ensure that the previous node instance is stopped. You can do this by using the appropriate command, such as concordium-node-stop.

  2. Update Configuration File:

    Modify the relevant configuration file (testnet-node.yaml in this case) by adjusting the database directory mapping. Replace:

- /var/lib/concordium-testnet:/mnt/data

with:

- ~/.local/share/concordium:/mnt/data

Alternatively, move the contents of ~/.local/share/concordium to a location such as /var/lib/concordium-testnet, while keeping the configuration files unchanged.

  1. Update Configuration for Baker Node (If Applicable):

    If your node was serving as a baker, update the configuration file to include the path to the baker credentials file:

- CONCORDIUM_NODE_BAKER_CREDENTIALS_FILE=/mnt/data/baker-credentials.json

Add this line to the environment section of the node service section of the configuration file.

  1. Start the Node and Collector:

    Use the following command to start the node and collector:

docker-compose -f testnet-node.yaml up

Last updated