Why run Mihomo directly on Linux
Most beginner-friendly guides focus on Clash Verge Rev on Windows and macOS. That is great when you want menus, tray icons, and one-click updates. But on a VPS, homelab router, or stripped-down desktop, a graphical client is often unnecessary noise. Running Mihomo from the command line keeps your setup transparent: one binary, one configuration directory, and predictable behavior under automation.
Mihomo stays highly compatible with mainstream Clash YAML. In many cases you can reuse the same profile you already export from a provider portal or from another client. If you are still learning how subscription URLs become a working config.yaml, read our subscription import walkthrough first, then return here to wire Linux and systemd around that file.
Compared with ad-hoc nohup shells or screen sessions, systemd gives you deterministic restart behavior, dependency ordering against network-online.target, and structured metadata for observability tools. You can still pair Mihomo with Docker or Podman if your organization standardizes on containers, but native systemd units remain the lightest way to integrate with host networking, firewall rules, and certificate stores without an extra abstraction layer.
Distributions, init systems, and CPU architecture
This guide targets systemd-based distributions such as Debian, Ubuntu, Fedora, Arch Linux, and their derivatives. The same mental model applies elsewhere—binary plus config plus a supervisor—only the service manager syntax changes.
Always match the release asset to your CPU architecture. Cloud instances and typical PCs use amd64 (also labeled x86_64). Raspberry Pi boards and many ARM cloud shapes need arm64 (aarch64). Run uname -m before downloading; a wrong architecture produces immediate exec errors or silent failures if you accidentally mixed static builds.
Container-first workflows sometimes hide architecture mismatches until runtime. When you build a custom image, copy the same binary you would run on bare metal and pin versions explicitly. Pinning matters because Mihomo ships frequent releases; automatic upgrades are convenient on desktops but should be staged on servers after you read release notes for breaking YAML changes.
Download, permissions, and install location
Grab the latest Mihomo archive from the official GitHub Releases page. Extract the mihomo binary, mark it executable, and place it somewhere stable:
- System-wide path such as
/usr/local/bin/mihomo(easy for systemd system units) - Per-user path such as
~/.local/bin/mihomo(ensure the directory is on yourPATHfor interactive testing) - Apply
chmod +xafter every manual upgrade - Optionally verify SHA256 sums published on the release page before you trust the binary in production
If you want background on how Mihomo evolved from Clash Meta and which modern protocols it unlocks, skim the core upgrade guide; the compatibility notes there still apply when you run the core bare-metal on Linux.
Configuration directory and import strategies
Mihomo reads settings from a directory you pass with -d. Inside that directory, config.yaml is mandatory. Common choices are ~/.config/mihomo for a personal account or /etc/mihomo for a shared appliance.
Three import patterns cover most users. First, paste a full provider-generated Clash profile straight into config.yaml. Second, keep a slim file and pull nodes through proxy-providers that point at remote subscription URLs. Third, export YAML from another compatible client and copy it over SSH. After any import, double-check listener ports: mixed-port or separate port and socks-port, plus external-controller for the REST API, must not collide with existing daemons.
Transparent TUN routing is powerful but needs extra capabilities and routing discipline. Get the baseline HTTP/SOCKS service stable under systemd first. When you are ready, follow the dedicated TUN mode guide so you do not conflate network-namespace issues with basic startup problems.
Sanity-check in the foreground
Before you touch systemd, launch Mihomo interactively:
mihomo -d ~/.config/mihomo
Watch the log lines. Successful startup shows configuration parsing, listener binding, and optional outbound tests. YAML indentation mistakes, unknown keys for your exact version, or occupied ports surface immediately here. Press Ctrl+C when satisfied; only then promote the same command line into a service unit.
systemd user service (recommended for laptops and single-user servers)
User units live under ~/.config/systemd/user/mihomo.service and do not require root to edit. A minimal unit looks like this—replace the username fragment in ExecStart with your real home path:
[Unit]
Description=Mihomo (Clash) proxy daemon
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /home/yourname/.config/mihomo
Restart=on-failure
RestartSec=3
LimitNOFILE=65536
[Install]
WantedBy=default.target
Reload and start:
systemctl --user daemon-reload
systemctl --user enable --now mihomo.service
systemctl --user status mihomo.service
Headless SSH boxes need lingering so user services survive logout and start at boot: sudo loginctl enable-linger yourname. Without it, your proxy may stop as soon as the interactive session ends, which confuses people who expect true unattended operation.
systemd system service (shared gateways)
When the binary lives in /usr/local/bin and configuration lives in /etc/mihomo, place /etc/systemd/system/mihomo.service with ExecStart=/usr/local/bin/mihomo -d /etc/mihomo, then run sudo systemctl enable --now mihomo. Tighten file permissions on the config directory so unprivileged accounts cannot read private node credentials. This pattern mirrors how other network daemons are managed and plays nicely with central backup jobs.
Verification: API, listeners, and logs
With external-controller set to something like 127.0.0.1:9090, run curl http://127.0.0.1:9090/version. A JSON payload mentioning mihomo confirms the control plane is alive. Check listeners with ss -tlnp or test application traffic through the published HTTP or SOCKS port using a known-good probe destination.
If you expose the controller beyond loopback—which we do not recommend on untrusted networks—put an authenticating reverse proxy or firewall rule in front of it. For local diagnostics, curl against /proxies endpoints helps confirm group names match what your applications expect. Combine that with a quick dig or resolvectl check when you suspect DNS hijacking or split-stack misconfiguration.
Logs unify through journald. User services: journalctl --user -u mihomo.service -f. System services: sudo journalctl -u mihomo.service -f. Temporarily raising log-level to debug helps chase DNS or rule issues, but remember to revert so you do not fill disks or leak sensitive details in shared logging stacks.
When correlating outages, capture a short window with journalctl --since '10 minutes ago' instead of scrolling endlessly. Pair those logs with systemctl status exit codes; frequent Restart= storms usually mean configuration drift or upstream TLS failures rather than a broken systemd unit.
Security habits and upgrades
Avoid running Mihomo as root unless you truly need privileged ports or system-wide TUN. Restrict directory modes on config.yaml so only the service account can read secrets. During upgrades, stop the unit, replace the binary atomically, then start it again; this prevents half-written executables from being launched by automatic restarts.
Store provider secrets in configuration management systems when you manage fleets, and render the final YAML on the host instead of copying files by hand. If you rely on unattended upgrades, schedule a post-update smoke test that hits the controller API and a lightweight outbound check so you detect regressions before users notice.
Finally, keep backups of working config.yaml snapshots before experimenting with experimental rule providers or remote rule sets. Rolling back YAML is faster than reconstructing a profile from memory after a failed edit marathon.
Quick troubleshooting
Address already in use
Change conflicting keys in YAML or stop the competing process. Clash-style stacks are picky about duplicate controller ports.
Permission denied or exec format error
Re-download the proper architecture and reapply chmod +x. Mixed musl/glibc environments are rare for official builds but worth noting on exotic images.
SELinux denials on Fedora or RHEL
Use audit2why to learn which boolean or file context blocks execution, then fix policy intentionally instead of disabling SELinux globally.
Still stuck after checking ports, permissions, and logs? Walk through the broader Clash troubleshooting guide—many DNS and subscription failures look like systemd issues but actually stem from stale airport links or rule typos.
Keeping a small checklist—binary hash, YAML lint, listener list, controller ping—turns most incidents into five-minute fixes instead of late-night guesswork.
Where graphical clients still shine
Command-line Mihomo plus systemd is unbeatable for servers, CI runners, and minimal desktops you administer through SSH. You get explicit logs, reproducible units, and no surprise GUI updates. Yet when you sit at a workstation and want visual policy editors, fast node switching, and bundled diagnostics, a polished client still saves time. Clash Verge Rev ships with an up-to-date Mihomo core, so you can stay on the same feature set without manually chasing nightly binaries.
Pick the workflow that matches the machine: automate the headless path here, and keep the friendly client handy where interaction matters. When you are ready to consolidate tooling, grab the official build and let it handle core updates for you. → Download Clash for free and experience the difference