Platform Deployment 2026-04-28 9 min read

Two Ways to Run Clash on Linux: Desktop Client Install and mihomo Command-Line Deployment

The Linux landscape is far more fragmented than Windows or macOS: a workstation with a desktop environment can install a graphical client directly, while servers, containers, or minimal systems can only rely on the core binary paired with a system service to stay running. This article walks through complete, executable steps for both paths.

Why Linux deployment needs two separate paths

On Windows and macOS, the Clash client follows a fixed routine — download the installer, double-click to install, configure through the GUI — with differences mostly limited to permission prompts. Linux is different because the ecosystem itself is split: desktop distributions (Ubuntu, Debian, Fedora Workstation, and the like) have a windowing system and a system tray, so a graphical client can run there. Cloud servers, NAS boxes, routers, and Docker containers, on the other hand, have no display server at all, so any client that depends on GTK or a webview simply won't launch.

This is exactly why the two deployment paths serve completely different use cases. The graphical client Clash Verge Rev targets desktop scenarios — day-to-day office work and development where you frequently switch nodes, check traffic, and tweak rules — with an emphasis on visual clarity. The mihomo core paired with systemd targets long-running server scenarios, where the priority is booting on startup, restarting automatically after a crash, and running unattended — no graphical interaction needed or even desired. Before choosing a path, check whether your system has a graphical environment at all; that's the first thing that decides which route to take.

Path 1: Installing Clash Verge Rev from the deb Package (Desktop Environments)

Clash Verge Rev is currently one of the most actively maintained, feature-complete graphical clients on Linux desktops. It's built on the Tauri framework, which is noticeably lighter on resources than earlier Electron-based options. Using an Ubuntu / Debian-based distribution as an example, the official .deb package is the recommended installation route, as follows.

Step 1: Confirm system dependencies

Tauri apps rely on the system's WebKitGTK component to render the UI. Most desktop distributions ship with it by default, but minimal installs or slimmed-down images may be missing it. It's worth installing these ahead of time:

sudo apt update
sudo apt install -y libwebkit2gtk-4.1-0 libgtk-3-0 libayatana-appindicator3-1

Tip

Some older distro repositories only carry libwebkit2gtk-4.0 rather than the 4.1 version. If the install fails, run apt-cache search webkit2gtk first to see what version your local repo actually provides, then adjust the package name in the install command accordingly.

Step 2: Install the deb package

After downloading the package matching your architecture (amd64 or arm64), install it with apt install rather than dpkg -i — the former resolves dependencies automatically, while the latter fails and leaves you to fix dependencies by hand:

cd ~/Downloads
sudo apt install ./clash-verge-rev_amd64.deb

Once installed, you'll find the Clash Verge Rev icon in your application menu. On first launch it will prompt for permission to write network configuration — just grant it when asked.

Step 3: Import a subscription and verify the proxy

After launching, paste your subscription link into the client's subscription management screen to pull it in, then go to the proxy page to pick a node. Once system proxy or TUN mode is enabled, verify traffic is actually routing through the proxy with:

curl -s https://ipapi.co/json/

If the returned geolocation field matches the region of your selected node, the proxy chain is working. If a command-line tool isn't going through the proxy (command-line tools and browsers often read different system proxy settings), you'll need to set the http_proxy and https_proxy environment variables separately — or simply enable TUN mode in the client, which takes over network traffic at the system level and saves you from configuring each tool individually.

Common dependency issues on the desktop path

SymptomLikely causeFix
App doesn't respond, no window appearsMismatched WebKitGTK versionCheck the actual available version in your repo and reinstall the correct dependency
System tray icon doesn't show upMissing appindicator librariesInstall libayatana-appindicator3-1 or the equivalent package for your distro
TUN mode fails to enableMissing required network permissionsFollow the client's prompt to run setcap or relaunch with elevated permissions

Path 2: Running mihomo Core + systemd (Headless Environments)

Servers, NAS devices, and containers without a display can't run a graphical client. In these environments, the usual approach is to run the mihomo binary (the core implementation continuing the Clash Meta project) directly, and let systemd manage its lifecycle — handling autostart on boot and automatic restarts after a crash.

Step 1: Download and place the core binary

Download the mihomo binary matching your system architecture, extract it, move it into a system executable path, and grant execute permission:

tar -zxvf mihomo-linux-amd64.tar.gz
sudo mv mihomo /usr/local/bin/mihomo
sudo chmod +x /usr/local/bin/mihomo

Step 2: Set up the config directory and config file

It's best to keep the config file under /etc/mihomo/ so the systemd service can consistently find it, and so multiple configs are easier to manage later:

sudo mkdir -p /etc/mihomo
sudo cp config.yaml /etc/mihomo/config.yaml

In the config file, check that the mixed-port (mixed proxy port) and external-controller (external control API address) fields fit a headless setup. Since there's no GUI to view traffic or switch nodes, it's common to enable external-controller and pair it with a third-party web panel (such as metacubexd) accessed from a browser for remote node management.

mixed-port: 7890
external-controller: 0.0.0.0:9090
secret: "set an access password"

Security note

If the server has a public IP, having external-controller listen on 0.0.0.0 exposes the control interface to the internet. You must set a secret password, or restrict source IPs with firewall rules — otherwise the control interface could be scanned and used to tamper with your proxy rules.

Step 3: Write the systemd service unit

Create a new service file at /etc/systemd/system/mihomo.service with the following content:

[Unit]
Description=mihomo Daemon
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=5
LimitNPROC=500
LimitNOFILE=1000000
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW

[Install]
WantedBy=multi-user.target

Here, -d /etc/mihomo sets that directory as the working directory for reading config; Restart=on-failure ensures systemd automatically restarts the core process if it exits abnormally; and CAP_NET_ADMIN / CAP_NET_RAW are the capabilities required to enable TUN mode and take over network-layer traffic — without needing to run the process fully as root, which is comparatively safer.

Step 4: Enable and check service status

sudo systemctl daemon-reload
sudo systemctl enable mihomo
sudo systemctl start mihomo
sudo systemctl status mihomo

The enable command sets autostart on boot, and status confirms whether the process is active (running). If the status shows a failure, check the detailed log first to pinpoint the issue:

journalctl -u mihomo -n 50 --no-pager

Common startup failures come down to malformed config fields, a port already in use by another process, or missing network capabilities for TUN mode. The log usually points to the exact line or field name — fix them one by one following the message.

Managing nodes and rules without a GUI

No window doesn't mean you're stuck flying blind. There are a few common management approaches, and you can mix and match based on what you're comfortable with.

  • Third-party web panels: With external-controller enabled, you can point a browser on the same local network at that address using an open-source web panel to switch nodes, run latency tests, and view rules — an experience close to a graphical client.
  • Calling the control API with curl: mihomo's external control interface is essentially a REST API. You can query the current proxy group state or switch nodes directly with curl, which fits well into automation scripts.
  • Editing the config file directly and restarting the service: For rule or proxy-group changes, edit the YAML file directly, then run systemctl restart mihomo to apply it — a good fit for stable environments where changes are infrequent.

For subscription updates, if the config file includes a subscription link, you can pair it with a cron job that periodically pulls updates and restarts the service, keeping node data from going stale. It's worth having the auto-update script validate the file format first, so a corrupted download doesn't overwrite the working config and break the service on restart.

Which path should you pick

If your day-to-day setup is a personal laptop or desktop workstation with windows and a system tray, go straight for the graphical client path — it's easier to operate and matches how most people are used to working, without needing to memorize systemd commands.

If your setup is a cloud server, home NAS, a flashed router, or a Docker container — environments that have no way to run a graphical interface at all — the mihomo core plus systemd is the only realistic route. Handing config maintenance and crash recovery to a system service, paired with a remote web panel for day-to-day node management, is currently the most reliable approach for headless environments.

The two paths aren't mutually exclusive — the same person can run both in parallel on different devices: a graphical client on a work laptop, and mihomo plus systemd on a home server that stays on around the clock, both sharing the same subscription while running in entirely different forms.

Download Clash