Skip to main content

Set up and start a node

Before you start a node, you must install the PostgreSQL database. For more information, see Set up PostgreSQL database.

To start a node correctly for the testnet, you need two files:

  • bc-config.xml: This file contains configuration settings for the node.
  • node-config-<dapp | system>.properties: The filename depends on whether you are hosting a dapp or system node. It contains node configuration information.

Hardware requirements

Ensure that the node has the following minimum hardware specifications, either as physical hardware or virtual:

  • 32 GB RAM
  • Eight vCPU, high frequency, burstable
  • 250 GB SSD
  • 100 Mbit/s network connection

You can start a Chromia node as a:

But first, you need a configure the node.

Prepare your node

Perform the following configurations to prepare your node:

  1. Generate a new key pair for each node.
  2. Set a static IPv4 address on your machine.
  3. Allow incoming TCP traffic on the ports configured in the node-config-<dapp | system>.properties file.
  4. Choose a password and username for Postgres.
  5. Prepare the domain on which you want to host your node.
  6. Enable disk quota.

The node configuration file is as follows:

# Node configuration
messaging.privkey=<node private key>
messaging.pubkey=<node public key>
messaging.port=9870
api.port=7740

# Postchain configuration
configuration.provider.node=managed
# Infrastructure to use. It can be net.postchain.managed.Chromia0InfrastructureFactory if all blockchains should be in the same process
infrastructure=net.postchain.managed.Chromia0MasterInfrastructureFactory

# Storage
database.username=<postgres-user>
database.password=<postgres-pw>
database.schema=<postgres-schema>
# Url to database. The host must point to the node's network.
# If the node is run as a Docker container, and the DB is also on Docker, then this would be the internal Docker host.
database.url=jdbc:postgresql://localhost:5432/<db-name>

# Node information to connect to an existing network
genesis.pubkey=<node public key>
genesis.host=<genesis address>
genesis.port=9870

# Container
# Path to image used by subnode containers
container.docker-image=registry.gitlab.com/chromaway/postchain-chromia/chromaway/chromia-subnode:<version>
# Mount path to a directory on the host that can be used to store configurations. Note that we don't want to use /tmp since this folder will be cleaned when a container is stopped
container.host-mount-dir=/var/lib/chromaway/postchain/subnode
# The host device on which the `container.host-mount-dir` is located. This is used to enforce disk I/O limits.
# Note that this should only be the device's name, not the partition.
# For Macm you might use `/dev/vda` to enforce limits
container.host-mount-device=/dev/sda
# Hostname of the master host as seen by a subnode. If the master is on Docker, then the subnode will perceive the host as the internal Docker host.
# 172.17.0.1 on linux/Windows. It can be localhost if master node is a native Java process.
container.master-host=host.docker.internal
# Port used by the master node to establish connections with subnodes
container.master-port=9880
# Hostname of subnodes as seen by the master host. See above
container.subnode-host=host.docker.internal
# Subnodes will spawn and host their own database, use this if you want all subnodes to use another external database
container.subnode-database-url=jdbc:postgresql://localhost:5432/postchain

Start a node using Docker

If you prefer to host the node outside Docker, skip this section and proceed to the next step.

  1. Ensure that Docker is installed on your system.

  2. Start Postgres using the provided Docker command.

    docker run \
    -d \
    --name postchain \
    --mount type=bind,source=<path to local data point. For example, /data/chromaway/postgres>,target=/var/lib/postgresql/data \
    -e POSTGRES_INITDB_ARGS="--lc-collate=C.UTF-8 --lc-ctype=C.UTF-8 --encoding=UTF-8" \
    -e POSTGRES_USER=postchain \
    -e POSTGRES_PASSWORD=<insert password here> \
    -p 127.0.0.1:5432:5432 \
    postgres:14.8
    note

    If you are using Docker on Mac, then use en_US.UTF-8 instead of C.UTF-8

Now, you can start the postchain node as a Docker container.

When starting a node using Docker, you must expose a few ports and add mount points. Folders containing node configuration, blockchain configuration, and the subnode mount path must be mounted, and the Docker socket must be a volume. The subnode mount path must have write access, and the others can be read-only. Furthermore, the messaging, API and subnode ports must be exposed. The container runs as the current user/group, and subnode containers run as the same user/group. It needs the docker group to talk to the Docker daemon.

You should also ensure that your machine doesn't run out of memory. Consider how much-dedicated memory you have left after subtracting the memory that's dedicated to dapp-containers. Also, consider the memory consumption of PostgreSQL (and any other applications you may have running on your machine). You can limit memory usage by setting JVM flags via JAVA_TOOL_OPTIONS environment variables.

System node:

docker run \
-d \
--name postchain \
--restart unless-stopped \
--mount type=bind,source="<path to local mounted files. For example, /data/chromaway/node-mounted-files>",target=/node-mounted-files,readonly \
-e JAVA_TOOL_OPTIONS="-Xmx16g" \
-e POSTCHAIN_DEBUG=true \
-e POSTCHAIN_CONFIG=/node-mounted-files/node-config-system.properties \
-e POSTCHAIN_BLOCKCHAIN_CONFIG=/node-mounted-files/bc-config.xml \
-p <internal node communications port (9870)>:<external node communications port>/tcp \
-p 127.0.0.1:<internal api port (7740)>:<external api port>/tcp \
-p <9880>:<9880>/tcp \
registry.gitlab.com/chromaway/postchain-chromia/chromaway/chromia-server:<version> \
run-node

Dapp node:

docker run \
-d \
--name postchain \
--restart unless-stopped \
--volume /var/run/docker.sock:/var/run/docker.sock \
--mount type=bind,source="<path to local user info. For example, /etc/passwd>",target=/etc/passwd,readonly \
--mount type=bind,source="<path to local subnodes. For example, /data/chromaway/subnodes>",target=/data/chromaway/subnodes \
--mount type=bind,source="<path to local node mounted files. For example, /data/chromaway/node-mounted-files>",target=/node-mounted-files,readonly \
-e JAVA_TOOL_OPTIONS="-Xmx8g" \
-e POSTCHAIN_DEBUG=true \
-e POSTCHAIN_CONFIG=/node-mounted-files/node-config-dapp.properties \
-e POSTCHAIN_BLOCKCHAIN_CONFIG=/node-mounted-files/bc-config.xml \
-p <internal node communications port (9870)>:<external node communications port>/tcp \
-p 127.0.0.1:<internal api port (7740)>:<external api port>/tcp \
-p <9880>:<9880>/tcp \
--privileged \
registry.gitlab.com/chromaway/postchain-chromia/chromaway/chromia-server:<version> \
run-node
note

The recommended port is specified in the parenthesis unless it's different in the node-configuration.properties file.

After completing these steps, your node should be up and running!

To verify that the node has been successfully turned on, use the following command to curl the debug endpoint:

curl http://<local address>:<port>/_debug

If you call this command after a few minutes, you should see that the block height has increased.

Start a node as a native background process

You can start the node as a background process, like a screen. You can add JVM flags by setting the environment variable JAVA_TOOL_OPTIONS. Make sure that the process gets restarted on a crash.

$ screen -S n0
# Ctrl+a, d (means detach)
# screen -r n0 (means reattach)

$ export JAVA_TOOL_OPTIONS="-Xmx2g"
$ postchain.sh run-node -nc config/node-config.properties --blockchain-config build/bc-config.xml --debug

Enforce subnode disk quotas

You can enforce subnode disk quotas can by using ext4. ext4 is a widely used file system for Linux operating systems that supports disk quotas. The quota provides a useful tool for managing disk space usage on Linux systems.

Ext4 disk quotas can be used with a native master node or a master node running in a Docker container with a chromaway/chromia-server image started with --privileged and run as root. To enable this:

Create an ext4 file system with project quotas enabled and mount it with project quotas enabled:

mkfs.ext4 -v -L postchain -O quota -E quotatype=prjquota /dev/...
mount -o prjquota /dev/... /mnt/chromaway/postchain

Add the following properties to the node configuration file:

container.filesystem=ext4
container.host-mount-dir=/mnt/chromaway/postchain

Start the master node container:

docker run -d --name postchain \
--privileged \
--restart unless-stopped \
--volume /var/run/docker.sock:/var/run/docker.sock \
--mount type=bind,source=/mnt/chromaway/postchain,target=/mnt/chromaway/postchain \
--mount type=bind,source="<path to local config. For example, $(pwd)/config>",target=/config,readonly \
--mount type=bind,source="<path to local build. For example, $(pwd)/build>",target=/build,readonly \
-e JAVA_TOOL_OPTIONS="-Xmx2g" \
-e POSTCHAIN_DEBUG=true \
-e POSTCHAIN_CONFIG=/config/node-config.properties \
-e POSTCHAIN_BLOCKCHAIN_CONFIG=/build/bc-config.xml \
-e POSTCHAIN_SUBNODE_USER=$(id -u):$(id -g) \
-p <internal node communications port (9870)>:<external node communications port>/tcp \
-p 127.0.0.1:<internal api port (7740)>:<external api port>/tcp \
-p <9880>:<9880>/tcp \
registry.gitlab.com/chromaway/postchain-chromia/chromaway/chromia-server:<version> \
run-node
note

The recommended port is specified in the parenthesis unless it's different in the node-configuration.properties file.

If running the master node natively, it needs to run as root and the quota tool setquota needs to be installed. You can find it in the package quota in Debian and Ubuntu.

Subnode containers must run as a non-root user, configured with node configuration property container.subnode-user or environment variable POSTCHAIN_SUBNODE_USER. The value should be <user-id>:<group-id>. Numerical user and group ids must be used.

Transport Layer Security (TLS)

TLS must be enabled on all nodes. You can add TLS with a reverse proxy. For more information, see Set up a TLS certificate.

Logging

Prometheus

To enable Prometheus, add metrics.prometheus.port=<port> to the node-config.properties file. For more information, see Set up Prometheus monitoring.

Generic logs

Docker supports different log drivers that can be used when collecting logs from a running container. For more information about available log drivers, see the official logging drivers documentation.

To start a node with a specific log driver, add log-driver and, optionally, log-opt to the docker run command when starting the node.

For example:

docker run -d --name postchain \
...
--log-driver=fluentd
--log-opt fluentd-address=fluentdhost:24224
--log-opt fluentd-async=true
...

Subnodes

Since subnodes are started automatically, the log driver and log options need to be added to the node configuration file as follows:

container.docker-log-driver=fluentd
container.docker-log-opts=fluentd-address=fluentdhost:24224;fluentd-async=true