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​