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:
- Generate a new key pair for each node.
- Set a static IPv4 address on your machine.
- Allow incoming TCP traffic on the ports configured in the
node-config-<dapp | system>.properties
file. - Choose a password and username for Postgres.
- Prepare the domain on which you want to host your node.
- 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.
Ensure that Docker is installed on your system.
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.8noteIf you are using Docker on Mac, then use
en_US.UTF-8
instead ofC.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
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
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