Create Startup Service
A Cardano blockchain node written in Go which actively participates in network communications on the Cardano blockchain using the Ouroboros Network Node-to-Node family of mini-protocols.
⚠️ Dingo is a work in progress and is currently under heavy development
In this guide, we will walk you through setting up a systemd service. Using a systemd service to run a Dingo Node maximizes the uptime by automatically restarting the Dingo node when the computer reboots. To get started follow the steps below.
✅ This guide assumes a typical Linux setup. Please adjust commands and paths as needed.
⚠️ For this guide we assume you have already completed the Quick Start guide.
Step 1 - Move the Dingo Binary and Configuration
Section titled “Step 1 - Move the Dingo Binary and Configuration”We will move the Dingo binary to /usr/local/bin/ and the configuration to /etc/dingo/ so they are accessible system-wide.
Copy the binary:
sudo cp ~/dingo/dingo /usr/local/bin/✅ You can verify the binary was copied by running
which dingo
Create the config directory and copy the configuration:
sudo mkdir -p /etc/dingosudo cp ~/dingo/dingo.yaml /etc/dingo/Step 2 - Update Paths in dingo.yaml
Section titled “Step 2 - Update Paths in dingo.yaml”Since the service will run as your user but the config is now in /etc/dingo/, we need to make sure the database and socket paths use absolute paths. Run the following to regenerate the config with your $HOME expanded:
sudo bash -c "cat <<EOF > /etc/dingo/dingo.yaml# Global data directory for both blob and metadata storage plugins.# Can be overridden with CARDANO_DATABASE_PATH or --data-dir.databasePath: \"$HOME/dingo/.dingo\"
# Pluginsplugins: storage: blob: provider: \"badger\" config: # Optional Badger data directory. When unset, databasePath applies. dataDir: \"$HOME/dingo/.dingo/badger\" blockCacheSize: 0 compression: false gc: true indexCacheSize: 0 metadata: provider: \"sqlite\" config: # Optional SQLite data directory. When unset, databasePath applies. dataDir: \"$HOME/dingo/.dingo/metadata.db\" mempool: provider: \"default\" config: # `capacity` is an optional override, not a required setting. # Default: 1 MiB for Praos mode and normal serve mode, and 25 MiB for Musashi mode. # Leave the key commented or omit it to use the mode default. # capacity: 1048576 # `revalidationDeltaCap` is optional. Default: 64. The value must be positive. # revalidationDeltaCap: 64 api: blockfrost: provider: \"builtin\" config: port: 3000 mesh: provider: \"builtin\" config: port: 8080 utxorpc: provider: \"builtin\" config: port: 9090
# Mithrilmithril: aggregatorUrl: \"\" cleanupAfterLoad: true enabled: true verifyCertificates: true
# Network# Health probes. CLI: --health-port; environment: DINGO_HEALTH_PORT.# Set healthPort to 0 to disable the health listener.healthPort: 12799# CLI: --health-ready-gap-slots; environment: DINGO_HEALTH_READY_GAP_SLOTS.healthReadyGapSlots: 1000bindAddr: \"0.0.0.0\"metricsPort: 12798debugPort: 0network: \"preview\"privateBindAddr: \"127.0.0.1\"privatePort: 3002relayPort: 3001socketPath: \"$HOME/dingo/dingo.socket\"
# StoragebarkBaseUrl: \"\"barkPort: 0storageMode: \"core\"# Database lifecycledatabaseLifecycle: # Automatic database snapshots run at epoch boundaries. # Do not enable automatic snapshots when the primary blob provider is "badger", "s3", or "gcs". # Select a local primary blob provider instead. # Default: false. snapshotEnabled: false # Dingo writes automatic snapshots to this local filesystem directory. # Set this when snapshotEnabled is true and when Bark mounts the live service. snapshotDir: \"$HOME/dingo/snapshots\" # Keep only the most recent automatic snapshots. # Default: 0. snapshotRetention: 0 # Optional cloud mirror for snapshots. # snapshotCloudDestination: \"\" # snapshotCloudDestinationPrefix: \"\" # Capture an automatic snapshot every N epoch closes. # CLI: --db-snapshot-every-n-epochs snapshotEveryNEpochs: 1EOF"📝 Leave
debugPortset to0unless profiling is required.debugPortcontrols a separate optional pprof listener and should stay disabled unless profiling is needed.
📝 The
databaseLifecycle.snapshotEnabledsetting controls automatic epoch boundary snapshots. Manualdingo database snapshotand BarkCreateSnapshotremain available withbadger,s3, orgcsas the primary blob provider. When Bark also serves live restore or truncate operations, setbarkPort,databaseLifecycle.snapshotDir,barkClientCaFilePath, andtlsCertFilePath/tlsKeyFilePath.
📝 Set
databaseLifecycle.snapshotRetentionto keep only the most recent automatic snapshots. SetdatabaseLifecycle.snapshotCloudDestinationto mirror each snapshot to S3 or GCS when Dingo runs withdingo_extra_plugins. This mirror destination is separate from the primary blob provider.
📝 Use
dingo database snapshot,dingo database restore <snapshot-dir>, anddingo database truncate --slot <slot>,--hash <hash>, or--block-number <n>on an offline data directory.restorealso accepts the same cloud URI thatsnapshotCloudDestinationuses and downloads it to a temporary directory before restoration.
📝 When
barkPortruns together withdatabaseLifecycle.snapshotDir, Bark also exposes liveRestoreandTruncateaccess.
📝 In core storage mode, Dingo rejects an offline
dingo database truncatetarget or a live BarkTruncatetarget older thanconsumed_utxo_prune_floorbefore any mutation because Dingo already pruned consumed UTxO history below that floor. Dingo allows a target exactly at the floor, and API storage mode remains unchanged. Choose a shallower target or recover from a fully synced peer snapshot when the requested rewind is older than the floor.
storageMode: "api"plugins: api: blockfrost: provider: "builtin" config: port: 3000 mesh: provider: "builtin" config: port: 8080 utxorpc: provider: "builtin" config: port: 9090midnight: # Enable the Midnight gRPC server. Default: false. serverEnabled: false # Expose gRPC reflection. Requires serverEnabled. Default: false. reflectionEnabled: false # Allow plaintext on a wildcard, hostname, or non-loopback listener. Default: false. allowInsecureRemote: false # gRPC listen port. Required and nonzero when serverEnabled is true. port: 50051 # gRPC listen host. An empty host defaults to 127.0.0.1. host: "127.0.0.1" authTokenPolicyId: ""📝 Dingo starts the Blockfrost, Mesh, and UTxO RPC listeners only in API storage mode. Midnight
gRPCserving also requiresAPIstorage mode,midnight.serverEnabled: true, and a nonzeromidnight.port. Set any listener port to0to disable that API.
📝
midnight.serverEnabledexplicitly controls the MidnightgRPCserver and keeps it off when false.midnight.enabledcontrols indexing separately; the server can serve persisted Midnight rows without running the indexer.midnight.reflectionEnabledrequiresmidnight.serverEnabled.
📝 The Midnight listener defaults to
127.0.0.1whenmidnight.hostis empty. For non-loopback plaintext, setmidnight.allowInsecureRemote: true; for remoteTLSexposure, configuretlsCertFilePathandtlsKeyFilePathinstead.
📝
midnight.authTokenPolicyIdonly applies in API storage mode with Midnight indexing. Leaving it empty keeps the broader default auth token matching behavior.
💡 Tip: The network setting supports the following values:
# Musashi (Leios) testnetnetwork: musashi
# Preview testnetnetwork: preview
# Pre-production testnetnetwork: preprod
# Mainnet - NOT CURRENTLY RECOMMENDEDnetwork: mainnetYou can view and verify our dingo.yaml file by running:
cd /etc/dingo/sudo nano dingo.yamlStep 3 - Bootstrap from Mithril (First Run Only)
Section titled “Step 3 - Bootstrap from Mithril (First Run Only)”Before starting the service for the first time, bootstrap the database from a Mithril snapshot:
dingo mithril sync --config /etc/dingo/dingo.yaml📝
mithril.downloadMaxTransientRetriescontrols retries for transient bootstrap download failures such as TLS timeouts, HTTP 429 responses, and HTTP 5xx responses. The example uses the default value of10.
This downloads and loads a snapshot, saving hours of sync time. See Step 4 of the Quick Start guide for details.
📝 You only need to do this once. After the initial bootstrap, the systemd service will keep the node synced.
Step 4 - Create dingo.service Unit File
Section titled “Step 4 - Create dingo.service Unit File”Create the systemd service file. Replace YOUR_USER with your username (echo $USER):
cat <<ENDFILE | sudo tee /etc/systemd/system/dingo.service > /dev/null[Unit]Description=Dingo NodeAfter=network-online.target
[Service]Type=simpleRestart=on-failureRestartSec=10User=YOUR_USERExecStart=/usr/local/bin/dingo serve --config /etc/dingo/dingo.yamlSyslogIdentifier=dingoTimeoutStopSec=5
[Install]WantedBy=multi-user.targetENDFILEWe can view and verify our dingo.service file by running:
sudo nano /etc/systemd/system/dingo.serviceStep 5 - Enable and Start the Service
Section titled “Step 5 - Enable and Start the Service”Enable the service to start on boot and start it now:
sudo systemctl daemon-reloadsudo systemctl enable dingo.servicesudo systemctl start dingo.serviceStep 6 - Check Status
Section titled “Step 6 - Check Status”Verify the service is running:
sudo systemctl status dingo.serviceCheck /health or /healthz for liveness and /readyz for readiness on port 12799:
curl http://127.0.0.1:12799/healthcurl http://127.0.0.1:12799/healthzcurl http://127.0.0.1:12799/readyz/health and /healthz report liveness. /readyz reports readiness and is not ready while the tip gap is unavailable or exceeds healthReadyGapSlots.
To follow the logs in real time:
sudo journalctl -u dingo -fTo see recent logs if there is an error:
sudo journalctl -u dingo -n 50 --no-pagerCongratulations! You have successfully set up a systemd service for Dingo.
Section titled “Congratulations! You have successfully set up a systemd service for Dingo.”Docs authored by Doc Holiday