[Unit] Description=Onion Monero Blockchain Explorer (xmrblocks) Documentation=https://github.com/moneroexamples/onion-monero-blockchain-explorer After=network-online.target monerod.service Wants=network-online.target # The explorer reads monerod's LMDB directly. If the blockchain disk is not # mounted there is nothing to serve, and without this the unit would start and # fail on every request instead of refusing to start at all. RequiresMountsFor={{ xmrblocks_bc_path }} [Service] Type=simple User={{ xmrblocks_user }} Group={{ xmrblocks_group }} # NOT decoration: the binary hardcodes TMPL_DIR as "./templates", so it resolves # its HTML relative to the working directory. Without this it starts happily and # then 500s on the first page view. WorkingDirectory={{ xmrblocks_dir }} ExecStart={{ xmrblocks_dir }}/xmrblocks \ --bc-path {{ xmrblocks_bc_path }} \ --daemon-url {{ xmrblocks_daemon_url }} \ --daemon-login {{ xmrblocks_rpc_user }}:{{ xmrblocks_rpc_password }} \ --bindaddr {{ xmrblocks_bind }} \ --port {{ xmrblocks_port }} \ --concurrency {{ xmrblocks_concurrency }}{% if xmrblocks_enable_json_api %} \ --enable-json-api{% endif %}{% if xmrblocks_enable_autorefresh %} \ --enable-autorefresh-option{% endif %}{% if xmrblocks_enable_pusher %} \ --enable-pusher{% endif %} Restart=always RestartSec=20 TimeoutStopSec=30 StandardOutput=journal StandardError=journal # Hardening. The explorer serves static templates and reads the chain. NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=read-only # The LMDB directory must be WRITABLE even though the database is opened # read-only. monero sets `mdb_flags = MDB_RDONLY` without MDB_NOLOCK # (db_lmdb.cpp), so LMDB still registers this process in the reader table # inside lock.mdb. With ProtectSystem=strict and no ReadWritePaths the open # fails outright - the obvious "it only reads, so grant nothing" is wrong here. # Writing to monerod's own lock table is normal and is what any second reader # does; data.mdb itself stays read-only to this process. ReadWritePaths={{ xmrblocks_bc_path }} LimitNOFILE=16384 [Install] WantedBy=multi-user.target