Introduction
Table of Contents
In this post I will explain how to turn your monero daemon into a service, a monerod
instance that will be stopped and started automatically by the system.
Then in Part 2 we will cover troubleshooting a service that won’t start.
Finally in Part 3 we will consider security issues, such as using selinux
and firewalld
.
What is the Monero Daemon?
Simply put monerod
, is software that sits in between wallets (clients) and the rest of the monero network (other servers). An instance of monerod
is itself part of the monero network. That is, it receives and validates blocks and, in the case of a ‘full node’ daemon, maintains a copy of the blockchain. If a wallet is connected, it will also validate and forward any transactions for that wallet to and from the network.
Why Run Monerod?
When you run your own daemon you’re contributing to the distributed nature of the blockchain by maintaining your own copy. You also provide a trusted place for your own wallets to connect to. Unlike in many other crypto-currencies, in Monero the wallet software is completely decoupled from the blockchain software.
Why Run Monerod as a service?
Services are generally things you want to be persistent. There is blockchain activity around the clock, and if you’re running a daemon, you probably want it to be up to date. When you create a service you are handing over some of the management of that service to the system. For example, your system will automatically start the service and grant it the appropriate resources.
Wallets are different, you really only need to sync them when you need to check balances or transact. Transactions are not stored in a wallet, only cached. Your transactions are always preserved on the blockchain.
Assumptions
We will run a full node, hosting a copy of the entire blockchain, and we will not be mining.
If you want to mine you can still benefit from running your own daemon, but it is recommended to use a dedicated miner such as XMRig.
Operating System
While this guide uses Centos 8, the configuration should be almost identical on any recent Fedora or Red Hat system. And the basic steps should be similar on any recent Linux system which uses systemd
as the init manager.
Command-Line Only
A graphical interface is unnecessary for this guide, so we will use the command-line version of monero. Also I just like doing everything by command-line.
Root Access
All commands are being run as root (even if prompt says ‘>’). You can of course use sudo
instead.
Angle Brackets
Replace any values enclosed in <>
with your own.
Snipped Text
The exception is <..>
which I used to indicate where unnecessary text has been snipped.
Text Editor
I’m using vim as a text editor, but feel free to substitute vi
for nano
or another editor of your choice.
Planning
System Resources
Normal Conditions
monerod
is not particularly CPU and memory hungry, once it is synced, and as long as you’re not mining, The main activity that consumes resources is validating new blocks when they come in. For this task it uses moderate amounts of CPU, and relatively smalls amounts of memory, disk IO and network bandwidth.
Initial Conditions
The most resource-intensive time is when initialising a new full node.
By default monerod
will download a fresh copy of the entire blockchain from the server, validating each block as it goes. This can take days and consume a fair bit of CPU and network bandwidth. Even if you use an existing or partial copy of the blockchain in a new daemon, there are still resources consumed.
Even so, the average system today will have plenty of CPU and memory for this task, and the main bottleneck is most likely to be disk.
Disk Space
At time of writing the monero blockchain is just under 100 GB and growing at a rate of ~1GB a month. The bulk of this is in one single file.
As such, the first step is to have a filesystem with enough free space for now, and to have some kind of strategy for future growth. Your strategy may be just having plenty of free space. Or you may have a logical volume that you can expand later with extra disks or by expanding the filesystem.
For this guide I am going to assume you have an additional filesystem, mounted at /opt
and with at least 110 GB free space. But in principle there is no issue with using your home directory instead.
Disk Speed
Fast disk will help a lot. monerod
will even warn you about it at startup:
The blockchain is on a rotating drive: this will be very slow, use an SSD if possible
The big requirement here is for fast reads. Monero will mostly only write one block at a time, being the last block – by definition past blocks are supposed to be immutable, at least after a few are confirmed. But there may be situations where monerod
will need to walk through the entire blockchain.
Ideally you would install the data-dir
on an SSD. Failing that, spinning disks in a RAID 1 or 5 will help. My system uses SAS disks in a RAID5 configuration which is perfectly ok for me. But note I haven’t actually tested with SSDs to see how much faster it actually is. It might cut down the initial sync by hours or more. Overall, use the best disk you have
CPU
The monero daemon is threaded and will use more cores when available. However, it’s possible to run on only 1 core without issue. If using a VM, I would recommend starting with between 2 and 4 cores and then experiment to find the optimal number.
Memory
Answering the question “how much memory does monerod
need under Linux?” is a difficult one because of how Linux manages memory. As a rough guide, and on a system doing no heavy loads, 2GB will be ok but 4GB is better.
I suspect that giving a dedicated monero server more than 4GB will provide diminishing returns. For example, on my system with 36GB, Linux reports that monerod
is virtual memory mapping just under 3GB, not including the blockchain itself. This figure includes shared libraries so the amount of additional memory required is going to be less than 3GB.
Large Pages
Large pages allow the operating system to allocate memory to processes in larger ‘chunks’ than normal. This can be more efficient for processes that churn through a lot of RAM. The downside is that any RAM allocated to huge pages is completely unavailable to regular pages, and not every process can use or even benefit from huge pages. So you can only allocate some fraction of your total RAM.
I have seen that monerod
will use 100-200 2MB pages (200-400MB) when available, but it does not seem capable of using 1GB pages. This is not a lot of RAM, so I doubt it makes much difference at all performance-wise. Having said that large pages is very handy for mining and perhaps that’s why monerod
supports it.
Overall large pages are probably going to make no practical difference to a full node, but won’t hurt either.
Network Bandwidth
Whatever you need to download 100+ GB in a reasonable time in the initial sync. After that, not a lot.
Installing
Monero Package
Login to your CLI and download the latest Linux CLI package from the Monero Project.
mkdir /opt/crypto cd /opt/crypto wget https://downloads.getmonero.org/cli/linux64
For later clarity we will rename the download package to a more useful name. For example:
mv linux64 monero-x86_64-linux-gnu-v0.17.1.9.tar.bz2
Extract the package and then create a soft link from the created folder to a new folder simply called monero
.
tar -xjvf monero-x86_64-linux-gnu-v0.17.1.9.tar.bz2 # extracts folder monero-x86_64-linux-gnu-v0.17.1.9 ln -s monero-x86_64-linux-gnu-v0.17.1.9 monero # creates a softlink
The purpose of the soft link is so that we can upgrade our monero package as new ones are released without changing any external references to the path /opt/crypto/monero
. We just need to remove and create a new soft link.
Monero User
We are also going to create a dedicated user account to run the monero daemon. This is a Linux best practice.
The monero
user will have no login or shell privileges, it will be used by the system directly.
useradd --no-create-home --home-dir /opt/crypto/monero-data -s /sbin/nologion --system monero
Data Folder
We do not want a separate copy of the blockchain for each version of Monero, so we will keep that in a separate folder.
Here we have called it monero-data
. The Monero Project refers to this as the ‘data directory’. Create the directory. Note this is one level up from the monero package directory we extracted.
mkdir /opt/crypto/monero-data
Update Permissions
The daemon will need to write to the data directory, so change the ownership of this folder to the monero
user.
chown -R monero /opt/crypto/monero-data
Your directory listing should now look something like this:
> ls -1 /opt/crypto monero monero-data monero-x86_64-linux-gnu-v0.17.1.9 monero-x86_64-linux-gnu-v0.17.1.9.tar.bz2
Configuring
We should be ready to create our service now.
Systemd
What is systemd?
Systemd is the system init manager in Centos 8, and most other Linux systems today. That means it is the first process started by the kernel, ‘process id 1’, and is responsible for starting and stopping every other process on the system.
Another init system you might encounter on some distributions is Sys V. Note other types of init systems work completely differently to systemd and are not covered by this guide.
Create the Unit File
A systemd
service configuration is called a unit file. Services are just one type of unit in systemd
.
Create the unit file:
vi /etc/systemd/system/monerod.service
..and add the text below.
[Unit] Description=Monero Daemon Documentation=https://getmonero.org After=network.target [Service] User=monero Group=monero Type=idle ExecStart=/opt/crytpo/monero/monerod --config-file /etc/monerod.conf --non-interactive StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target
After
tellssystemd
when to start the serviceExecStart
which tellssystemd
how to start the service.User
andGroup
tellssystemd
who should run the service
Save the file and issue the following command to let systemd
know there’s been a change to a unit file.
systemctl daemon-reload
Monerod Configuration File
We also going to maintain a separate configuration file for monerod
. This is a more manageable alternative than passing command-line arguments to monerod
in the unit file.
Create the following file. Note that this file does not need to be owned by the monero
user.
vi /etc/monerod.conf
..and add the following text
data-dir=/opt/crytpo/monero-data rpc-bind-ip=0.0.0.0 rpc-bind-port=18081 confirm-external-bind=1 restricted-rpc=1 log-level=0
Monerod Options
This will provides a few basic options to monerod
when it starts. For a complete list of options to monerod, read:
/opt/crypto/monero/monerod --help
Here’s a brief explanation of these options:
data-dir
overrides the default location for the monero blockchain (normally /root/.bitmonero
).
rpc-bind-ip
tells the daemon which interfaces to listen on. 0.0.0.0
means listen on all interfaces, which will be suitable for most people. This will allow connections from wallets on other systems. If you only want the service to listen on the loopback interface, simply comment the rpc-bind-ip
option with a ‘#’.
rpc-bind-port
is the TCP
port that wallets will connect over. RPC stands for remote procedural call. Basically it’s an API to the daemon. Note that it is not actually using the old but still common RPC protocol, but a monero-specific version inspired by it.
confirm-external-bind
confirms you want to allow connections from wallets that aren’t on this system, such as when binding to 0.0.0.0
.
restricted-rpc
furthers restricts what information can be requested from the daemon by any client. It’s best to enable this unless you need otherwise.
log-level
increases log verbosity when > 0
Note
If you want allow some other systems to connect to your daemon but not others, we will cover firewalling your service in Part 3, but for now the daemon is not running so the port is still closed.
Use an existing copy of the monero blockchain
If you already have a copy of the blockchain, even one that may be out of date, you can potentially save a lot of time by reusing it. But it doesn’t necessarily make the whole process fast. If you don’t have an existing copy feel free to skip to the next section.
Your existing copy should be in a folder somewhere called lmdb
and contain two files:
> ls -l lmdb/ total 101013504 -rw-r--r--. 1 monero root 103437815808 Jan 17 19:54 data.mdb -rw-r--r--. 1 monero root 8192 Jan 17 19:54 lock.mdb
Move or copy this folder to the new data directory.
cp -r <source_dir>/lmdb /opt/crypto/monero-data
If all goes well, the blockchain will be revalidated by the service when we start it and then updated to the latest block. It does not always save much time however, so don’t be too concerned if you don’t have an existing copy.
Tip
Later when we start our service, monerod
may report that your existing copy is corrupted. If so you can try adding the following option to your monerod.conf
:
db-salvage
=1
Enabling
Viewing Logs
We are almost ready to try and start the service. But before we do let’s up open another terminal, one that we will use for monitoring our logs (I’ll show activity on that terminal if different colours from here).
In our unit file, we told systemd
to use journald
for logging.
StandardOutput=journal StandardError=journal
journald
is the default logging collector for any system running systemd
. Even though it still inspires plenty of hate among the Linux user community, it has many advantages over traditional syslog which writes to text files. We’ll cover the basic commands to monitor your service via journald
below.
Once you are logged in as root, type the following:
journalctl -ef
This will display the last 100 or so logs captured by the system, and also start following new logs (similar to the tail -f
you might run on a text log file).
If there are too many logs being displayed we can filter down to the relevant ones like so.
journalctl -ef -t systemd -t setroubleshoot -t monerod
This instructs journald to only show logs from the units named systemd
, and monerod
.
Another useful option to journalctl
is the -g
option, which allows you to filter on any message text. For example:
journalctl -ef -g "monero"
First attempt: Enabling the service
Let’s start and enable the service in one shot. Enabling means that the service will be started automatically at boot from now on.
Go back to the other terminal and enter the following.
systemctl enable --now
Basic Management of Systemd Services
For future reference, the basic commands for starting and stopping the service are as follows.
systemctl start monerod systemctl stop monerod systemctl restart monerod # shorthand for stopping then starting the service
You can check the current status of the service as follows. This command will also show the last few journal lines which may be useful when troubleshooting or to confirm normal activity at any point:
systemctl status monerod
Checking the Service Status
So let’s try this ourselves. I usually wait a few seconds after starting a service to give the journals time to catch up:
> systemctl status monerod â monerod.service - Monero Daemon Loaded: loaded (/etc/systemd/system/monerod.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2021-02-15 12:49:44 AEDT; 5 days ago Docs: https://getmonero.org Main PID: 1493 (monerod) Tasks: 30 (limit: 230032) Memory: 1.1G CGroup: /system.slice/monerod.service 1493 /kvm/cc/monero/monerod --config-file /etc/monerod.conf --non-interactive <..logs..>
You are looking for active
and enabled
. If you see anything else, we are going to cover troubleshooting in Part 2.
Checking Startup Logs
Now switch back to your logging terminal and you should see something like below:
Jan 17 19:59:15 crypto.upaya.net.au systemd[1]: Started Monero Daemon. Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.816 I Monero 'Oxygen Orion' (v0.17.1.9-release) Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.816 I Initializing cryptonote protocol... Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.816 I Cryptonote protocol initialized OK Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.817 I Initializing core... Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.817 I Loading blockchain from folder /kvm/cc/monero-data/lmdb ... Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.817 W The blockchain is on a rotating drive: this will be very slow, use an SSD if possible Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.896 I Loading checkpoints Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.897 I Core initialized OK Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.897 I Initializing p2p server... Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.903 I p2p server initialized OK Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.903 I Initializing core RPC server... Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.903 I Binding on 0.0.0.0 (IPv4):18081 Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.903 I core RPC server initialized OK on port: 18081 Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.904 I Starting core RPC server... Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.904 I core RPC server started ok Jan 17 19:59:16 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:16.904 I Starting p2p net loop... Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I ********************************************************************** Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I The daemon will start synchronizing with the network. This may take a long time to complete. Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I You can set the level of process detailization through "set_log <level|categories>" command, Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I where <level> is between 0 (no details) and 4 (very verbose), or custom category based levels (eg, *:WARNING). Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I Use the "help" command to see the list of available commands. Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I Use "help <command>" to see a command's documentation. Jan 17 19:59:17 crypto.upaya.net.au monerod[167062]: 2021-01-17 08:59:17.905 I <..>
Note
Some of these startup messages seem to suggest your daemon while accept interactive commands. This is not the case. You will not be able to type anything into the service and have it respond. That’s part of the point of having it as a service – monerod
will not be tied to particular user being logged or a particular shell & terminal process.
Summary
With luck your service is now downloading and validating 100GB of blockchain! Expect this to take several days the first time.
Now, if your service is not active and you don’t seem to see the right logs, then it’s time to troubleshoot! Head over to Part 2 – Troubleshooting.
Connecting a CLI Wallet
This is not a full guide to using the CLI wallet. Just a quick note on which options you’ll need to work with your new service and connect a wallet located on another system:
/opt/crypto/monero/monero-wallet-cli --daemon-address <system-ip>:<rpc-bind-port> --wallet-file <path-to-wallet>
Once you enter your wallet password, you should see the wallet connecting to the daemon and starting to refresh. If your wallet is reporting any connection issues it may be a firewall problem. We’ll cover that in Part 3 – Security.