Skip to main content

Linux Setup

Everything you need to install, configure, and systemd-ify hali on Linux.


Architecture

On Linux, hali uses a split process model:

User CLI (your user) ──IPC (group socket)──> halid daemon (hali user)
/run/hali/
  • The daemon runs as the hali system user
  • The CLI runs as your normal user
  • Communication happens over a group-writable socket at /run/hali/
  • Your user must be in the hali group

Installation

sudo dpkg -i hali_0.1.0_amd64.deb

The post-install script automatically:

  • Creates the hali system user (/usr/sbin/nologin, no home dir)
  • Provisions /var/lib/hali/, /var/log/hali/, /run/hali/ with hali:hali ownership
  • Installs and enables the halid systemd service
  • Starts the service immediately

Verify:

hali --help
hali search mistral
systemctl status halid --no-pager

Option B: Manual tarball

tar xzf hali-linux-amd64.tar.gz
cd hali-linux-amd64

# Copy binaries
sudo cp hali /usr/bin/
sudo cp halid /usr/bin/

# Copy systemd unit
sudo cp halid.service /etc/systemd/system/halid.service

# Create system user
sudo useradd --system --no-create-home --shell /usr/sbin/nologin hali

# Create service directories
sudo install -d -m 2775 -o hali -g hali /var/lib/hali /var/log/hali /run/hali

# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable halid
sudo systemctl start halid

Option C: Build from source

go build -o bin/hali .
go build -o bin/halid ./cmd/service

# Or use the build script (also packages tar.gz and .deb)
installer/linux/build-linux.sh

Group setup (non-sudo CLI access)

The daemon runs as hali:hali. To use the CLI without sudo, add your user to the hali group:

sudo usermod -aG hali "$USER"
newgrp hali
sudo systemctl restart halid

Verify:

id -nG # Should show "hali"
ls -l /run/hali # Socket should be group-writable
hali daemon status # Should work without sudo

If your current shell still doesn't show hali in groups, log out and back in (or reboot).


systemd service

The service is named halid and runs under the hali system user.

Unit file (/etc/systemd/system/halid.service)

[Unit]
Description=Hali Daemon (local model cache + LAN sync)
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/halid
Restart=always
RestartSec=5

User=hali
Group=hali

LimitNOFILE=65536
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

systemctl commands

# Check status
systemctl status halid

# Start / stop / restart
sudo systemctl start halid
sudo systemctl stop halid
sudo systemctl restart halid

# Enable on boot / disable
sudo systemctl enable halid
sudo systemctl disable halid

# View logs
journalctl -u halid -f
journalctl -u halid --since "10 minutes ago"
journalctl -u halid -n 100 --no-pager

Or use the hali CLI (aliases to systemctl)

hali service start # → systemctl start halid
hali service stop # → systemctl stop halid
hali service status # → systemctl status halid
hali service install # → provision and enable halid
hali service uninstall # → disable and stop halid

Service storage (FHS-compliant)

/var/lib/hali/
cache/
torrents/
models/

/var/log/hali/

/run/hali/
.ready (startup sentinel — created when daemon is ready)

User mode (without systemd)

If you prefer not to use a system service, run the daemon as your user:

hali daemon start # Launches halid in background
hali daemon status # Shows what's seeding
hali daemon stop # Stops the daemon

In user mode, data is stored under ~/.hali/:

~/.hali/
config.json
logs/
cache/
torrents/

No sudo needed. No systemd involved. The daemon stops when you log out.


LAN mode

By default, the daemon's HTTP API binds to 127.0.0.1:47433 (localhost only). To allow other machines on the LAN to access the web dashboard:

# Enable LAN API access
hali service enable-lan # Binds to 0.0.0.0:47433
sudo systemctl restart halid

# Dashboard is now reachable at http://<your-linux-ip>:47433

To revert:

hali service disable-lan # Binds back to 127.0.0.1:47433
sudo systemctl restart halid

This writes daemon_listen_addr to /var/lib/hali/config.json.


Configuration

Config file: ~/.hali/config.json (user mode) or /var/lib/hali/config.json (service mode).

hali materializes this file on first run with sensible defaults. Edit it directly or use the CLI:

# See all current settings
hali config show

# Common adjustments
hali config set streaming_hash true
hali config set debug true
hali config set models_dir /mnt/data/llama-models
hali config set max_upload_mbps 50
hali config set max_download_mbps 0
/var/lib/hali/config.json
{
"streaming_hash": true,
"debug": false,
"telemetry_enabled": true,
"models_dir": "/mnt/data/llama-models",
"lmstudio_models_dir": "/home/you/.lmstudio/models",
"ollama_models_dir": "/home/you/.ollama/models",
"daemon_listen_addr": "127.0.0.1",
"max_upload_mbps": 0,
"max_download_mbps": 0,
"lan_hmac_enabled": false,
"lan_hmac_shared_secret": ""
}

Changes take effect after restart:

sudo systemctl restart halid
# or: hali service restart

Environment variables

Precedence: env vars > config.json > defaults

export HALI_MODELS_DIR="/mnt/data/llama-models"
export ENABLE_STREAMING_HASH="true"
export LMSTUDIO_MODELS_DIR="/home/you/.lmstudio/models"
export OLLAMA_HOME="/home/you/.ollama"

Add to ~/.bashrc or ~/.zshrc for persistence.


LAN Setup

LAN discovery works out of the box. hali sends UDP multicast announcements on 239.192.42.1:4269 across all usable IPv4 interfaces.

Verify LAN is working

hali daemon status

Look for the LAN AVAILABLE section — it lists models discovered from peers.

Firewall considerations

If your firewall blocks multicast:

# ufw
sudo ufw allow 4269/udp

# firewalld
sudo firewall-cmd --add-port=4269/udp --permanent
sudo firewall-cmd --reload

Troubleshooting: Sender not visible

If another host is announcing models but this machine doesn't see them:

# Check if packets are arriving
sudo tcpdump -ni any udp port 4269

If no packets arrive, the issue is upstream network multicast policy (router/AP/VLAN), not local hali state. Also verify:

  1. The sender has active seeding entries (hali daemon status)
  2. Both daemons use compatible lan_hmac_enabled and shared secret settings
  3. Both hosts are on the same L2 segment (multicast is blocked across routed subnets)

LAN is always optional — downloads fall back to HuggingFace HTTP if multicast is unavailable.


Telemetry

hali telemetry status # Check current state
hali telemetry enable # Opt in — anonymous pull events help trust scoring
hali telemetry disable # Opt out — queued events stay on disk but are never sent

Read more: Telemetry Reference


Web Dashboard

hali daemon start
hali stats --web

Or visit http://127.0.0.1:47433 directly. Tail the daemon logs in real time:

journalctl -u halid -f

Complete workflow example

# 1. Search
hali search llama

# 2. Pull (interactive)
hali pull llama

# 3. Check cache
hali list

# 4. Check daemon
hali daemon status

# 5. Export to Ollama
hali export ollama llama:8b:instruct:q5_k_m

# 6. Install as service (optional — runs on boot)
hali service install

# 7. Open dashboard
hali stats --web

# 8. Create publisher profile (optional — attribute your seeds)
hali profile create

Upgrading

.deb package

sudo dpkg -i hali_<new_version>_amd64.deb
sudo systemctl restart halid

Manual install

sudo cp hali /usr/bin/
sudo cp halid /usr/bin/
sudo systemctl restart halid

Next steps