Back to WG0A main page

Dire Wolf service management

Use systemd to start and supervise Dire Wolf

This page shows two practical systemd unit examples for running Dire Wolf on Linux. They are usually easier to support over time than relying on screen or tmux because the service state, logs, and restart behavior are visible through standard tools. I highly recommend not trying to use screen or tmux, even when starting direwolf through systemd. Using screen or tmux adds complexity and makes it harder to see the service state and logs.

Start with the single-instance unit if you have one Dire Wolf configuration. Move to the template unit when you want separate services for different radios or config files.

The examples below run the Dire Wolf binary directly, which keeps the service simple to debug. In this case, you are troubleshooting the direwolf process itself rather than a shell wrapper script and screen session and direwolf.

Referenced gists

1) Single-instance service: direwolf.service gist

2) Multi-instance template service: direwolf@.service gist

Advantages to using systemd to manage Dire Wolf

The Linux systemd model is the standard way to start and supervise long-running processes. It has been optimized over many years to handle service dependencies, logging, and process supervision. The biggest day-2 operations win with systemd is that service behavior, health, and logs are all visible through standard tools. This reduces hand-maintained scripts and the amount of "tribal knowledge" needed to support a station over time.

Topic systemd service
Automatic restart Built in (Restart=always, RestartSec=15) options. Easily adjustable.
Boot ordering Explicit dependencies (After=network.target, After=rigctld.service). Ensures Dire Wolf starts after required services are ready, such as sound and network.
Logging journalctl -u ..., built-in history and follow mode. Logs are centralized and automatically rotated.
Operational control start, stop, status, enable, disable
Least privilege Run as non-root user via User= and Group=. Minimizes security risks of running services as root.
Multi-instance support Native with template units like direwolf@.service
Operator handoff Any operator can run the same standard commands to see status, logs, and restart history.

For more information on systemd, see systemd site.

Recommended starting point

Choose the single-instance unit for a one-radio setup. Use the template unit when you need multiple named services with different config files. Before copying either example, replace YOUR_USERNAME, YOUR_GROUP, and the paths under /opt/direwolf with values that match your system. The -a option determines how often direwolf prints audio level statistics (in seconds). This can be adjusted if you are debugging decoding issues. These examples assume your Dire Wolf config file(s) are stored in /opt/direwolf/, so move your existing direwolf.conf (and any direwolf-*.conf files) there before enabling the service. Note: make sure that the specified user has permissions to access the Dire Wolf config.

Option A: Single-instance service

Use this when you have one Dire Wolf config and one running process.

[Unit]
Description=Dire Wolf Sound Card-based AX.25 TNC
After=network.target
After=sound.target

[Service]
Type=simple
User=YOUR_USERNAME
Group=YOUR_GROUP
WorkingDirectory=/opt/direwolf/
ExecStart=/usr/local/bin/direwolf -t 1 -a 600 -c direwolf.conf
Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target

Example: starting direwolf uses /opt/direwolf/direwolf.conf.

Option B: Multi-instance template service

Use this when you want multiple named Dire Wolf instances with different config files.

[Unit]
Description=Dire Wolf %i Service
Documentation=https://github.com/wb2osz/direwolf/blob/dev/doc/README.md
After=network-online.target
After=sound.target
Wants=rigctld.service
After=rigctld.service

[Service]
Type=simple
User=YOUR_USERNAME
Group=YOUR_GROUP
WorkingDirectory=/opt/direwolf/
ExecStart=/usr/local/bin/direwolf -a 200 -qd -c direwolf-%i.conf
Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target

Example: starting direwolf@vhf uses /opt/direwolf/direwolf-vhf.conf.

For a second instance, direwolf@hf uses /opt/direwolf/direwolf-hf.conf.

Using Wants=rigctld.service makes rigctld optional and starts it if available. Dire Wolf will still start if rigctld is not installed.

For more details on Dire Wolf configuration and command-line arguments, see the Dire Wolf User Guide.

Install and enable

For single instance

sudo cp direwolf.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now direwolf
sudo systemctl status direwolf

For template instances

sudo cp "direwolf@.service" /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now direwolf@vhf
sudo systemctl status direwolf@vhf

Logs and troubleshooting

# Single instance logs
journalctl -u direwolf -f

# Template instance logs
journalctl -u direwolf@vhf -f

Keep After=rigctld.service when PTT depends on rigctld. Use Requires=rigctld.service only if you want Dire Wolf startup to fail when rigctld is unavailable.

Seeing terminal-style text with journalctl

If you like the colored terminal view from screen, you can keep most of that experience with systemd and journalctl.

# 1) Keep -t 1 in ExecStart so Dire Wolf emits ANSI color
ExecStart=/usr/local/bin/direwolf -t 1 -a 600 -c direwolf.conf

# 2) Follow logs in a cleaner, terminal-like format
journalctl -u direwolf -f -o cat --all

# 3) For template instances
journalctl -u direwolf@vhf -f -o cat --all

If colors do not appear, try --no-pager and confirm your terminal emulator supports ANSI colors.

Systemd debugging

A key supportability advantage: if Dire Wolf exits, the screen session may disappear with the error text that was on screen. With systemd, stdout/stderr is captured in journald and remains available after the process exits.

Debug task systemd workflow
Did startup fail? systemctl status direwolf immediately shows exit code, last logs, and unit state.
Find recent errors journalctl -u direwolf --since "15 minutes ago" gives a time-bounded log view.
Follow live behavior journalctl -u direwolf -f is the standard live tail.
Post-crash evidence retention journalctl -u direwolf --since "1 hour ago" preserves crash messages even after service exit/restart.
Root-cause restart loops Restart policy and cadence are explicit in one place (Restart=always, RestartSec=15) and easily adjusted.
See which command actually started systemctl show direwolf -p ExecStart,FragmentPath shows exact unit command and source file.
Dependency visibility Unit declares ordering/dependencies with After=/Wants=/Requires=.
# Fast systemd debug checklist
systemctl status direwolf@vhf
journalctl -u direwolf@vhf --since "-30 min"
journalctl -u direwolf@vhf -f
systemctl show direwolf@vhf -p ActiveState,SubState,ExecMainStatus,FragmentPath

Migrating from cron and dw-start.sh

Before trying to start Dire Wolf with systemd, make sure any old crontab entries that launch Dire Wolf through dw-start.sh are removed or commented out. Running both methods together can create duplicate processes and audio/PTT conflicts.