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
What is the Monero Daemon?
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.
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.
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.
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.
All commands are being run as root (even if prompt says ‘>’). You can of course use
Replace any values enclosed in
<> with your own.
The exception is
<..> which I used to indicate where unnecessary text has been snipped.
I’m using vim as a text editor, but feel free to substitute
nano or another editor of your choice.
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.
The most resource-intensive time is when initialising a new full node.
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.
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.
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
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.
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 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.
Whatever you need to download 100+ GB in a reasonable time in the initial sync. After that, not a lot.
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
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.
We are also going to create a dedicated user account to run the monero daemon. This is a Linux best practice.
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
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.
The daemon will need to write to the data directory, so change the ownership of this folder to the
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
We should be ready to create our service now.
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
systemd service configuration is called a unit file. Services are just one type of unit in
Create the unit file:
..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
systemdwhen to start the service
systemdhow to start the service.
systemdwho 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.
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
..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
This will provides a few basic options to
monerod when it starts. For a complete list of options to monerod, read:
Here’s a brief explanation of these options:
data-dir overrides the default location for the monero blockchain (normally
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
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
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.
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
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.
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
Once you are logged in as root, type the following:
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
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
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: Started Monero Daemon. Jan 17 19:59:16 crypto.upaya.net.au monerod: 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: 2021-01-17 08:59:16.816 I Initializing cryptonote protocol... Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.816 I Cryptonote protocol initialized OK Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.817 I Initializing core... Jan 17 19:59:16 crypto.upaya.net.au monerod: 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: 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: 2021-01-17 08:59:16.896 I Loading checkpoints Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.897 I Core initialized OK Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.897 I Initializing p2p server... Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.903 I p2p server initialized OK Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.903 I Initializing core RPC server... Jan 17 19:59:16 crypto.upaya.net.au monerod: 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: 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: 2021-01-17 08:59:16.904 I Starting core RPC server... Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.904 I core RPC server started ok Jan 17 19:59:16 crypto.upaya.net.au monerod: 2021-01-17 08:59:16.904 I Starting p2p net loop... Jan 17 19:59:17 crypto.upaya.net.au monerod: 2021-01-17 08:59:17.905 I Jan 17 19:59:17 crypto.upaya.net.au monerod: 2021-01-17 08:59:17.905 I ********************************************************************** Jan 17 19:59:17 crypto.upaya.net.au monerod: 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: 2021-01-17 08:59:17.905 I Jan 17 19:59:17 crypto.upaya.net.au monerod: 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: 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: 2021-01-17 08:59:17.905 I Jan 17 19:59:17 crypto.upaya.net.au monerod: 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: 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: 2021-01-17 08:59:17.905 I <..>
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.
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.