Running a Symbol node manually

This guide walks you through the process of setting up a node to join Symbol’s network without using Symbol Bootstrap.

Symbol Bootstrap is a very handy tool that allows the quick deployment of Symbol nodes. However, it relies on Docker and node.js technology which might not be available (or allowed) in all scenarios. This guide takes the longer route and explains how to setup a Symbol node manually. If you would like to use Symbol Bootstrap use this guide instead.

The following section explains how to build a Peer node and the next one expands the node to convert it into an API node.


The following instructions have only been verified to work on Linux.

Build a Peer node

Build the server

Follow the Catapult server instructions to build its binaries, either manually or using Conan.

Generate keys

A Symbol node requires a number of keys to function properly. These keys are generally randomly generated so you need to create a few ones to be used in the following steps.

This step can be performed on an offline machine for added security.

Main, Remote and VRF

From within the _build directory you created in the previous section, run:

./bin/ --count 3 --network public

This will output 3 key pairs similar to this one:

   address decoded: 68DEF09E4C5D494FF46DA30B7F1ACF9983E7BFC02C29FB4B
      public key: 1E886BA00B4F85DBC0B31DBB78DADFAA29945DF7290DB7A4243D94864483C627
      private key: 3DDDC333029BC8ACDB460435BBC71041D460B911725B03D6F93805521AAD60CB

Each block is a key pair (there is one block shown above) composed of a private key, a public key and an address.

Copy all of them to a temporary text file for later use and label the key pairs Main, Remote and VRF.


If you already have any of these keys, you can use them instead of the randomly-generated ones.

The most relevant scenario is when using a main account opted-in from a NIS1 account. In this case you can directly use the key obtained in the opt-in process as your Main key instead of the randomly-generated one.


If your node is to be a voting node it must have linked a voting key for the period in which you intend to vote. This is interesting as voting nodes receive voting rewards.

The generation of the voting key, though, is a bit more complex than the previous ones:

  1. Still from within the _build directory create another directory called votingkeys.
  1. Create the voting key:

    Voting keys are different from the other keys in that they have a period of validity, for example. They are only valid from a Start Epoch to an End Epoch (see side box).

    Nodes are only eligible as voters if they are linked to a valid voting key for the current blockchain epoch, so remember to renew your voting key periodically.

    To help you with that task, you can have up to 3 linked voting keys, with different periods, so you can easily renew one key while there’s still another one active (you will need to unlink an older key to be able to link more than 3 keys).

    A voting key is created using and providing its period of validity (note you do not use as before):

    bin/ --output votingkeys/private_key_tree1.dat \
                                 --startEpoch 100 --endEpoch 460

    This creates a file named votingkeys/private_key_tree1.dat and prints the voting key on the terminal. As your voting keys expire and you create new ones, increase the number on the file name.

    generating 361 keys, this might take a while
    votingkeys\private_key_tree1.dat generated
    verifying generated file
     saved voting public key: ****************
    loaded voting public key: ****************

    Copy the voting key public key into the temporary text file where you keep the rest of the keys, label it Voting and save it for later.


Symbol is highly customizable and this means there are a lot of parameters that can be adjusted to suit your node’s needs. Some of these parameters are network-related and must match the rest of nodes in the network (for example currencyMosaicId) whereas some others are node-related and you can set freely (for example friendlyName).

You can edit these files manually (Take a look at these templates to know how they look) but it is more convenient to use the Symbol Node Configurator tool as shown next.

This step can be performed on an offline machine for added security.

  1. Prerequisites.

    • Install Python 3.
    • Install OpenSSL (for example running sudo apt install openssl on Linux).
  2. Install symbol-node-configurator.

    • Download and extract Alternatively, clone the GitHub repository if you know how to use Git.

    • Move into the symbol-node-configurator directory and install the tool’s requirements by running:

      python3 -m pip install -r requirements.txt
  3. Create certificates.

    • Create a folder named certificates and move into it.
    • Create a text file named private.main.txt and put the Main account private key inside.
    • Download and run this certificate generation script.
    • Delete private.main.txt.
    • Get back to the parent folder.

    You should now have at least the following files in the certificates folder: ca.pubkey.pem, ca.crt.pem, node.full.crt.pem, node.crt.pem and node.key.pem.

  4. Create harvester and VRF key files.

    • Create a file named private.harvesting.txt and put the Remote private key inside.
    • Create a file named private.vrf.txt and put the VRF private key inside.
  5. Run the configurator tool.

    The node configurator tool is called and it accepts a number of parameters depending on the kind of node you want:

    Parameter Description
    --mode (Mandatory) Type of node. Accepted values are api, peer and dual.
    --harvesting (Optional) To create a harvesting node. The Remote key will automatically be used so that Remote harvesting is enabled by default.
    --voting (Optional) To create a voting node. If you enable this copy the private_key_tree1.dat file you created above into this directory.
    --output (Optional) Folder where resulting configuration will be stored.

    For example:

    python3 --mode dual --harvesting --voting --output settings
      i     | extracting nemesis seed
      i     | preparing base settings
      i     | turning on harvesting
      i     | turning on voting
      i     | extracting mongo scripts
      i     | copying certificates
      i     | moving private_key_tree1.dat

    This command will produce all the required node configuration files in the settings directory and you need to copy them to _build, in the machine where your node will run:

    • Copy settings/resources to _build/resources.
    • Copy settings/certificates to _build/certificates.
    • Copy settings/nemesis/seed to _build/seed (Omit the nemesis part).
  6. Edit

    • Go back to the _build directory.

    • Edit resources/ so that it points to the right places:

      seedDirectory = ../seed
      certificateDirectory = ../certificates
      dataDirectory = ../data
      pluginsDirectory = ../lib
      votingKeysDirectory = ../votingkeys
  7. Edit

    Edit resources/ to customize the node. Learn more about the available properties in the Configuring node properties guide.

    The most common ones are in the [localnode] section:

    Property Description
    host IP address or domain name of your node.
    friendlyName Name of your node for display purposes.
    version Version of catapult-server used by your node. Leave empty to use the current one.
    roles A comma-separated list of the following values: Peer, Api, Voting, IPv4, IPv6.

    For example:

    host = <YOUR_NODE_IP>
    friendlyName = myPeerNode
    version =
    roles = IPv4,Peer

Run the server

Create one last folder:

mkdir data

And finally fire up the server!

cd bin

You should see a lot of debug output while the node starts synchronizing with the rest of the network:

... peer returned 42 blocks (heights 2 - 43)

The node can be stopped by pressing Ctrl-C and restarted simply by running catapult.server again.

If you see no error messages, your server is up and running and you can continue with this guide.

Build an API node

Once you have the Catapult Server running, you can add extra services to turn it into an API node:


As shown in the diagram above, besides the Catapult Server you will also need:

  • A Database holding the REST data.
  • A Catapult Broker serializing accesses to the database.
  • A REST gateway accepting client requests and turning them into server commands or database queries.

The following sections explain how to install each service. You will need all of them.

Move to the _build folder created while building the server and create any additional folders requested in the next steps inside _build.

Run the database

  1. Install MongoDB (at least version 4.4).

    It is recommended to follow the program’s own installation instructions, and NOT install from your distro’s packages.

  2. Create a directory to store the data files and run the database:

    mkdir dbfiles
    mongod --dbpath=dbfiles --wiredTigerCacheSizeGB 2 --bind_ip

    Keep mongod running for as long as your node runs.

  3. Build indices to optimize database accesses.

    The catapult-server repository you cloned to build the server in the first step contains a folder with mongo scripts. Run this one:

    mongo < ../scripts/mongo/mongoDbPrepare.js

    Without this step database performance will be unacceptably slow.

Run the broker

  1. Edit resources/ and point databaseUri to

    databaseUri = mongodb://
    databaseName = catapult
  2. Run the broker:

    Move into the bin directory and run:

    ./ ..

    Keep the broker running for as long as your node runs.

Build and run the REST gateway

  1. Clone the catapult-rest repository and install its dependencies:

    (Going back to the _build directory first)

    cd ..
    git clone
    cd catapult-rest
    npm install -g yarn
  2. Build the REST gateway:

    cd rest
    yarn build
  3. Configure the REST gateway:

    All configuration is stored in the resources/rest.json file.

    Edit this file to make sure that the following properties point to the right files:

    Property File Default location
    tlsClientCertificatePath node.crt.pem _build/certificate/
    tlsClientKeyPath node.key.pem _build/certificate/
    tlsCaCertificatePath ca.crt.pem _build/certificate/
    networkPropertyFilePath _build/resources/
    nodePropertyFilePath _build/resources/

    Use absolute paths. For example:

       "host": "",
       "port": 7900,
       "timeout": 1000,
  4. Run the REST gateway:

    node _build/index.js resources/rest.json

    Keep the REST gateway running for as long as your node runs.


If the REST gateway is working correctly, you can now make queries at port 3000. If the Catapult Server, Broker and MongoDB are working correctly, the values returned by REST will be correctly synchronized with the rest of the blockchain.

Point a browser to the following URLs and check that the returned values are similar to the expected ones:

  • http://localhost:3000/node/info: Services status.

  • http://localhost:3000/chain/info: Node’s connection to the network.

       "scoreHigh": "0",
       "scoreLow": "11485261672816562840",
       "height": "161138",
       "latestFinalizedBlock": {
          "finalizationEpoch": 224,
          "finalizationPoint": 44,
          "height": "160560",
          "hash": "52D3B01920C695B9194FABD869804E4D2A18D9B5509E47B2C70B0E6C3E275E33"

    The height field should match the actual height of the blockchain, but, upon first starting the node, it might take a while to synchronize.

Finally, go to the Symbol Explorer page and check that your node appears in the list (It refreshes every 30 seconds).