Introudction

In this tutorial I will explain how to run a stellar-core node on CentOS 7.2. We will be setting up a full validator, but in most cases you don't need to run a validator. Validation is only necessary if other nodes care about your validation and you want to participate in the SCP. For more information about stellar-core and why you would want to run a node check out this page.

Most steps are the same for setting up a validator or non-validator node, the only difference is in the configuration file. So you can follow this tutorial in both cases.

There are also stellar-core docker images: https://github.com/stellar/docker-stellar-core-horizon

This way you can save a lot of time getting a node up and running by sacrificing some of the flexibility and control.

Requirements

At first I was running a validator on a $5/mo DigitalOcean instance with 512 MB RAM, but I would constantly run into performance issue. Especially, stellar-core would eat up all the RAM and kill the machine when the swap kicked in. I would suggest to have a machine with at least 2 GB of RAM. I didn't run into CPU (average 25%) or bandwidth issue.

General CentOS setup

If you just started a fresh instance of CentOS you should take some steps before the installation of stellar-core to assure the system is secure and up to date.

The first thing I do is to run:

sudo yum upgrade sudo yum install vim

This will get the repository and all system packages up to date. And of course give me vim so I can easier edit configuration files. Feel free to pick emacs 🙂

The second task I do, on a freshly installed machine, is to create a local non-root user and forbid root login. You can follow this excellent guide to accomplish this.

I also like to add this line to /etc/ssh/sshd_config:

PasswordAuthentication no

This disables password authentication and you can only use Public/Private Key login on the machine. It's good practice and makes it more secure. No reason to deal with passwords in 2016.

I also strongly encourage you to follow this guide to enable the firewall, set correct time and add a swap file.

I would only leave 2 ports open in this case sshd and the stellar peer port (11625):

sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --permanent --add-port=11625/tcp

Building stellar-core

We will be compiling stellar-core from source and need the developer tools installed:

sudo yum groupinstall 'Development Tools' sudo yum install postgresql-devel

You can check out all the dependencies required by stellar-core here.

Building gcc

CentOs 7.2 ships with gcc 4.8. Stellar-core requires 4.9 or higher. The best way to solve this is to compile the latest gcc from source following instructions on StackOverflow:

http://stackoverflow.com/questions/36327805/how-to-install-gcc-5-3-with-yum-on-centos-7-2

I would grab the latest version (6.2) instead of 5.3 with:

curl ftp://ftp.gnu.org/pub/gnu/gcc/gcc-6.2.0/gcc-6.2.0.tar.bz2 -O

The compilation process takes some time, go grab a coffee.

You will also need to simlink the freshly compiled libstdc++ library with:

sudo cp /usr/local/lib64/libstdc++.so.6.0.22 /lib64/ sudo rm /lib64/libstdc++.so.6 sudo ln -s /lib64/libstdc++.so.6.0.22 /lib64/libstdc++.so.6

Configuring libpq

At one point during the stellar-core compilation you would run ./configure and it would fail with the following error:

No package 'libpq' found

The problem is that when you install PostgreSQL dev tools on CentOS it doesn't install the required file for pkg-config to find it. To solve this you can create the file by hand.

/usr/lib64/pkgconfig/libpq.pc:

prefix=/usr libdir=${prefix}/lib64 includedir=${prefix}/include/pgsql Name: LibPQ Version: 5.5.0 Description: PostgreSQL client library Requires: Libs: -L${libdir}/libpq.so -lpq Cflags: -I${includedir}

Getting stellar-core

Just grab it from git and check out the latest release tag:

git clone https://github.com/stellar/stellar-core.git git checkout v0.5.0 # Check out the latest stable version git submodule init git submodule update

Compiling & installing stellar-core

The following steps will compile and install stellar-core:

./autogen.sh ./configure make -j 4 make check # Runs the tests sudo make install

Configuring CentOs for stellar-core

We will run stellar-core under the stellar user:

sudo useradd stellar

Note that we don't set a password for this user as we will never need it. If we want to become the user for configuration purposes we can always do 'sudo su - stellar'.

Installing PostgreSQL

For the production database you probably don't want to use SQLite. It's a good idea to install PostgreSQL. Here are instructions how to install it on CentOS:

https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-centos-7

You will need to create a role stellar and a database stellar:

sudo -i -u postgres createuser --interactive # role=stellar, everything else=no createdb stellar

Again, we don't need to set a password for the user, because stellar-core will run under the user stellar and as we have the same roll and database it automatically has privileges to access it.

Stellar folders

Stellar requires a place on disk to save logs and the full ledger:

sudo mkdir /var/log/stellar sudo chown stellar /var/log/stellar sudo mkdir -p /var/stellar/buckets sudo chown stellar /var/stellar sudo chown stellar /var/stellar/buckets

Configuring stellar-core

This is the most important step! You can find more information about all the configuration parameters here.

This is an example validator configuration file:

https://github.com/stellar/docs/blob/master/other/stellar-core-validator-example.cfg

I usually start from the example file and adapt it to my needs:

sudo mkdir /etc/stellar sudo cp stellar-core/docs/stellar-core_example.cfg /etc/stellar/stellar.cfg sudo chown stellar /etc/stellar/stellar.cfg sudo chmod 600 /etc/stellar/stellar.cfg sudo vim /etc/stellar/stellar.cfg

An example of some of my configuration parameters:

LOG_FILE_PATH="/var/log/stellar/stellar-core.log" BUCKET_DIR_PATH="/var/stellar/buckets" DATABASE="postgresql://dbname=stellar user=stellar" NODE_NAMES=[ "GAOO3LWBC4XF6VWRP5ESJ6IBHAISVJMSBTALHOQM2EZG7Q477UWA6L7U eno", "GAXP5DW4CVCW2BJNPFGTWCEGZTJKTNWFQQBE5SCWNJIJ54BOHR3WQC3W moni", "GBFZFQRGOPQC5OEAWO76NOY6LBRLUNH4I5QYPUYAK53QSQWVTQ2D4FT5 dzham", "GDXWQCSKVYAJSUGR2HBYVFVR7NA7YWYSYK3XYKKFO553OQGOHAUP2PX2 jianing", "GCJCSMSPIWKKPR7WEPIQG63PDF7JGGEENRC33OKVBSPUDIRL6ZZ5M7OO tempo.eu.com", "GCCW4H2DKAC7YYW62H3ZBDRRE5KXRLYLI4T5QOSO6EAMUOE37ICSKKRJ sparrow_tw", "GD5DJQDDBKGAYNEAXU562HYGOOSYAEOO6AS53PZXBOZGCP5M2OPGMZV3 fuxi.lab", "GBGGNBZVYNMVLCWNQRO7ASU6XX2MRPITAGLASRWOWLB4ZIIPHMGNMC4I huang.lab", "GDPJ4DPPFEIP2YTSQNOKT7NMLPKU2FFVOEIJMG36RCMBWBUR4GTXLL57 nezha.lab", "GCDLFPQ76D6YUSCUECLKI3AFEVXFWVRY2RZH2YQNYII35FDECWUGV24T SnT.Lux", "GBAR4OY6T6M4P344IF5II5DNWHVUJU7OLQPSMG2FWVJAFF642BX5E3GB telindus", # non validating "GCGB2S2KGYARPVIA37HYZXVRM2YZUEXA6S33ZU5BUDC6THSB62LZSTYH sdf_watcher1", "GCM6QMP3DLRPTAZW2UZPCPX2LF3SXWXKPMP3GKFZBDSF3QZGV2G5QSTK sdf_watcher2", "GABMKJM6I25XI4K7U6XWMULOUQIQ27BCTMLS6BYYSOWKTBUXVRJSXHYQ sdf_watcher3" ] PREFERRED_PEERS=[] PREFERRED_PEER_KEYS=[ "$sdf_watcher1", "$sdf_watcher2", "$sdf_watcher3", "$dzham", "$SnT.Lux", "$tempo.eu.com" ] KNOWN_PEERS=[ "core-live-a.stellar.org:11625", "core-live-b.stellar.org:11625", "core-live-c.stellar.org:11625", "confucius.strllar.org", "stellar1.bitventure.co", "stellar.256kw.com" ] NODE_SEED="SXXXXXX....XXXX galactictalk.org" NODE_IS_VALIDATOR=true # History local commented out # [HISTORY.local] # get="cp /var/stellar/history/vs/{0} {1}" # put="cp {0} /var/stellar/history/vs/{1}" # mkdir="mkdir -p /var/stellar/history/vs/{0}" # Stellar.org history store [HISTORY.sdf1] get="curl -sf http://history.stellar.org/prd/core-live/core_live_001/{0} -o {1}" [HISTORY.sdf2] get="curl -sf http://history.stellar.org/prd/core-live/core_live_002/{0} -o {1}" [HISTORY.sdf3] get="curl -sf http://history.stellar.org/prd/core-live/core_live_003/{0} -o {1}" [QUORUM_SET] VALIDATORS=[ "$moni", "$eno", "$tempo.eu.com", "$dzham", "$sparrow_tw", "$SnT.Lux" ] # This field does not exist # MAINTENANCE_ON_STARTUP=true

Notice how I commented out the MAINTENANCE_ON_STARTUP parameter. I do this because I was getting an error that this parameter does not exist when starting stellar-core:

<startup> [default FATAL] Got an exception: Unknown configuration entry: 'MAINTENANCE_ON_STARTUP' [main.cpp:537]

As a validator, defining the QUORUM_SET is going to be one of the most important things you do. Take your time to read more about it and understand it.

Create the stellar-core tables in PostgreSQL

Switch to the stellar user and create the database tables:

sudo su - stellar stellar-core --conf /etc/stellar/stellar.cfg --newdb

Add stellar-core to systemd

If the previous step went well you want to add stellar-core to systemd as a service, so it automatically restarts on crashes and gets started when the system starts.

To do this create the file /etc/systemd/system/stellar-core.service with the following content:

[Unit] Description=Stellar Core After=postgresql.service [Service] ExecStart=/usr/local/bin/stellar-core --conf /etc/stellar/stellar.cfg User=stellar Group=stellar WorkingDirectory=/home/stellar Restart=on-failure [Install] WantedBy=default.target

Notice how stellar-core is started after PostgreSQL so it has the database available.

Now you can start your stellar-core node and enable automatic startup:

sudo systemctl start stellar-core sudo systemctl enable stellar-core

Inspecting the state of your node

Congratulations! Your node should be up and running. Now you want to keep one eye on the logs and the health of the quorum so your node stays up and happy.

To check what the stellar-core service is writing to stdout and stderr run:

sudo journalctl -u stellar

For the rest of the commands you need to be the stellar user:

sudo su - stellar

To get general information about your node you can run:

stellar-core --conf /etc/stellar/stellar.cfg --c 'info'

Or to check the quorum status:

stellar-core --conf /etc/stellar/stellar.cfg --c 'quorum'

An explanation of all this fields you can find here.

Hope this tutorial was useful. If you get stuck on some steps or require additional clarification feel free to ask here.