Why a Terminal Session Is the Wrong “Service Model”

Installing Mihomo on a Linux laptop or VPS is only half the job. If you start the binary inside an SSH session or a desktop terminal, the process dies when the session ends, when the shell receives SIGHUP, or when you close the laptop lid and the session manager cleans up stray children. Even a dedicated tmux pane is better than nothing, but it still treats your proxy core like a hobby script instead of infrastructure. systemd is the standard answer on modern distributions: it starts the daemon after the network is usable, restarts it when the process exits unexpectedly, and funnels logs into journalctl where you can filter by unit, time range, and priority.

This article complements platform-specific GUI tutorials. On Linux you often run the upstream core directly; once you do, wiring Linux Mihomo systemd integration is what turns “it works when I remember to launch it” into Clash Linux autostart behavior that survives reboots and recovers from transient faults without human babysitting.

Pick a Layout: Binary, Config Directory, and Working Directory

Most Mihomo builds expect a home directory that contains config.yaml plus any downloaded rule providers or GeoIP databases your profile references. A common convention is /etc/mihomo for system-wide installs or ~/.config/mihomo for per-user setups. The binary itself might live at /usr/local/bin/mihomo after you rename the release artifact—keep the path absolute in the unit file so upgrades do not depend on whichever directory you were in when you last typed the command.

Before you touch systemd, prove the same invocation works manually: mihomo -d /etc/mihomo (flags vary slightly by build; check --help on your binary). If manual start fails, fix permissions and YAML first; systemd will only repeat the same failure with better timestamps. When you are tuning profiles and remote rules, our rule providers guide stays focused on what lands inside that directory without duplicating this service wiring.

A Minimal system Unit That Survives Crashes

Create /etc/systemd/system/mihomo.service (name is arbitrary but keep it memorable). A pragmatic starting point looks like this:

[Unit]
Description=Mihomo Clash-compatible proxy core
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=3
# Hardening examples — uncomment after you confirm a clean start
# NoNewPrivileges=yes
# ProtectSystem=strict
# ProtectHome=yes
# ReadWritePaths=/etc/mihomo

[Install]
WantedBy=multi-user.target

After=network-online.target reduces the classic race where the core boots, tries to fetch subscriptions on a still-dead default route, and exits or enters a half-broken state. It does not magically fix captive portals or VPN layers that appear later; it simply aligns start order with what most admins expect from a proxy daemon Linux footprint. Restart=on-failure is the sweet spot for many deployments: it respawns after non-zero exits but will not fight you forever if you intentionally stop the service with systemctl stop (that path uses a successful stop, not a failure). If you prefer aggressive recovery even when the process crashes with a zero exit code—rare but not impossible with some wrappers—you can experiment with Restart=always paired with sensible rate limits.

Reload the supervisor and enable persistence:

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo.service

Check status with systemctl status mihomo and confirm the main PID stays stable while you open a few flows through your configured mixed-port or TUN setup.

User Services: Great for Desktops, Different Permission Story

On a single-user workstation you may prefer a user unit under ~/.config/systemd/user/mihomo.service so the daemon runs in your login session context and writes to your home directory without sprinkling root-owned files everywhere. Enable it with systemctl --user enable --now mihomo.service and consider loginctl enable-linger <user> if you want the user slice to survive logouts—essential if you need Clash Linux autostart at boot without an interactive login.

User units inherit the same Restart= semantics but interact differently with privilege boundaries. Creating TUN interfaces, binding privileged ports below 1024, or applying certain firewall redirect models may still require capabilities or a system-level service. Treat “user service” as the default for simple HTTP/SOCKS listeners on high ports; escalate to a system unit when the kernel says permission denied and you have confirmed the YAML is not the culprit.

TUN, Capabilities, and Why “It Worked in sudo”

When you enable TUN mode, Mihomo typically needs access to /dev/net/tun and enough network capability to install routes. Running manually under sudo masks missing capability settings in the unit. On systemd 240+ you often see combinations of AmbientCapabilities=CAP_NET_ADMIN plus device ACL allowances, or administrators run the service as root for simplicity on a dedicated appliance—pick your threat model consciously.

If you tighten the unit with ProtectSystem=strict, remember to whitelist writable paths via ReadWritePaths= for directories that store downloaded databases and cached providers. Overly strict hardening that blocks writes will surface as silent rule failures or subscription downloads that never land on disk, which then show up as policy gaps rather than explicit permission errors. Iterate: start permissive, confirm stability, then add one hardening knob at a time.

Logs: journalctl Pairs With Mihomo Like a Checklist

Once stdout and stderr are owned by systemd, journalctl -u mihomo -e becomes your tail -f replacement. Follow live output during a subscription refresh, watch restart bursts after OOM kills, or correlate restarts with kernel messages about route changes. Rotate verbosity inside config.yaml when debugging, but return to a quieter level afterward—debug logs grow quickly on busy machines.

When traffic fails despite a running unit, the next skill is interpreting core messages without guessing. Our dedicated walkthrough on Clash logs, port conflicts, and dial tcp timeouts applies directly to Mihomo-class cores: bind errors are local listener problems, while stalled dial tcp lines usually point outward to resolvers or nodes. systemd tells you when the process restarted; the article tells you why the restart might have been a red herring versus a real crash.

Subscription Updates: Let the Core Schedule, Add Timers Only When Needed

Mihomo can refresh remote subscriptions and rule providers on its own timers defined in YAML. For many users that is enough: the daemon is already long-lived, so periodic fetches happen inside the same process without cron. If you additionally need to rotate local files, trigger Git pulls for split rule repos, or run health checks that are not native to the core, a systemd timer unit can call a small script and then systemctl reload mihomo or use the core’s external controller—whichever matches your operational standard.

Avoid stacking three different refresh mechanisms that all fire at once; stagger them so a transient provider outage does not look like a systemic failure. When profiles grow complex, revisiting the speed and subscription checklist helps keep health checks and URL-test groups aligned with reality instead of amplifying noise.

Failure Modes You Will Actually See

Restart loops after a bad YAML edit are loud in the journal: the process exits immediately, systemd applies RestartSec, and you get a sawtooth pattern. Fix the config, run mihomo -t or your build’s test flag if available, then systemctl restart mihomo. Silent stalls without exits often mean upstream network issues or DNS deadlocks; systemd will not restart because the process is still alive—this is where log literacy matters more than restart policies.

Port already in use behaves like any other bind failure: the service may fail to enter the active state until you free mixed-port or legacy port values. Another automation stack, Docker publish, or a second Mihomo instance is the usual suspect. Disk full under ProtectSystem misconfiguration shows up as weird partial writes to provider caches; watch df and journal warnings together.

Documentation, API Control, and When to Reload

Field semantics for listeners, DNS, and TUN change slowly but do change. Keep the documentation hub open while editing YAML so you are not relying on year-old forum snippets. If you integrate automation against the external controller, treat authentication and bind addresses as part of your unit security review—localhost-only listeners are easier to reason about than wide-open LAN interfaces on a laptop that travels.

For configuration-only tweaks that the core can apply without a full process restart, prefer the documented reload path your build supports over kill -HUP folklore. Full restarts are fine during development; production boxes benefit from minimizing connection churn when only a rule provider URL changed.

Legal and ethical use: Run proxy software only on networks and for traffic you are permitted to handle. Respect employer policies, provider terms, and local law. This guide is for operating your own systems, not for bypassing contractual or legal restrictions.

systemd Makes “Always On” Boring—in a Good Way

Wrapping Mihomo in systemd is the bridge between a working config and a Linux proxy persistent service you can trust on a server or a daily-driver desktop. You get deterministic boot order relative to networking, structured logs in journald, and restart semantics that recover from one-off crashes without opening a terminal. Pair that foundation with disciplined subscription refresh, sane hardening, and log interpretation, and the Linux story finally feels as complete as the polished GUI tutorials on other platforms.

If you still prefer an integrated app experience on Linux, many Mihomo-based clients ship their own packaging—but when you run the core directly, the unit file is your productized runbook. Grab a current build from our download page, drop it beside a clean config directory, and let systemd own the lifecycle. When you are ready to standardize on transparent, verifiable tooling, visit our download page for curated releases. → Download Clash for free and experience the difference.