Installation¶
Haul ships as one container image: tristanteu/haul for
linux/amd64 and linux/arm64. It contains the server, the web UI, the built-in hoster plugins and the
extractors (7z, unrar).
- Docker Compose
- Podman Quadlet
- docker run
- First start
- Volumes
- Environment variables
- Updating
- Behind a reverse proxy
Docker Compose¶
mkdir haul && cd haul
curl -O https://raw.githubusercontent.com/firsttris/haul/main/docker/docker-compose.yml
# set APP_SECRET and your download folders, then
docker compose up -d
The file in docker/docker-compose.yml:
services:
haul:
image: tristanteu/haul:latest
container_name: haul
restart: unless-stopped
ports:
- "8080:8080"
- "127.0.0.1:9666:9666" # Click'n'Load, only on the host's loopback
volumes:
- ./config:/config
- ./downloads/tmp:/downloads/tmp
- ./downloads/done:/downloads/done
environment:
- APP_SECRET=change-me # openssl rand -hex 32
Point the two download volumes wherever your disks are, for example /mnt/cache/downloads:/downloads/tmp
and /mnt/disk1/downloads:/downloads/done.
Podman Quadlet¶
For Podman with systemd, docker/ has a Quadlet unit and network:
mkdir -p ~/.config/containers/systemd ~/haul/config ~/haul/downloads/{tmp,done}
cp docker/haul.container docker/haul.network ~/.config/containers/systemd/
# set APP_SECRET, adjust the Volume= lines
systemctl --user daemon-reload
systemctl --user start haul
For a start at boot without a login, install the files into /etc/containers/systemd/ and use
systemctl without --user (or run loginctl enable-linger $USER for the user unit).
The unit sets AutoUpdate=registry, so podman auto-update pulls new releases.
Logs: journalctl --user -u haul or podman logs haul.
docker run¶
docker run -d --name haul --restart unless-stopped \
-p 8080:8080 -p 127.0.0.1:9666:9666 \
-v ./config:/config \
-v ./downloads/tmp:/downloads/tmp \
-v ./downloads/done:/downloads/done \
-e APP_SECRET="$(openssl rand -hex 32)" \
tristanteu/haul:latest
Keep the APP_SECRET you used: without it, stored account passwords cannot be read.
First start¶
Open http://<server>:8080. On the first visit Haul asks you to create the login. To create it without
the UI, set HAUL_USER and HAUL_PASSWORD for the first start.
Then:
- Accounts & Plugins: add your hoster accounts, see Hosters.
- Settings → Captchas: install the userscript if you use hosters with reCaptcha, hCaptcha or Turnstile, see Captchas.
- Settings → Click'n'Load from the desktop: create an API token if you want to send Click'n'Load links from your desktop.
Volumes¶
| Path | Content |
|---|---|
/config |
SQLite database haul.db and your own plugins in plugins/ |
/downloads/tmp |
Downloads in progress (<id>.part). Fast disk or cache drive recommended. |
/downloads/done |
Finished files, one folder per package. Archives are extracted here. |
tmp and done may be on different disks; Haul moves finished files across.
Environment variables¶
| Variable | Default | Purpose |
|---|---|---|
APP_SECRET |
– (required) | Key that encrypts stored account passwords. Do not change it later. |
HAUL_USER, HAUL_PASSWORD |
– | Create the web login on the first start |
HAUL_CONFIG_DIR |
/config |
Database and own plugins |
HAUL_TMP_DIR |
/downloads/tmp |
Downloads in progress |
HAUL_DONE_DIR |
/downloads/done |
Finished downloads |
HAUL_LISTEN |
0.0.0.0:8080 |
Web UI and API |
HAUL_CNL_LISTEN |
0.0.0.0:9666 in the image, else 127.0.0.1:9666 |
Click'n'Load; off turns it off. Publish it only on 127.0.0.1. |
HAUL_BUILTIN_PLUGINS |
/app/plugins in the image, else unset |
Plugins that come with Haul; unset means only your own plugins load |
HAUL_USER_AGENT |
a desktop browser | User-Agent sent to hosters |
HAUL_7Z, HAUL_UNRAR |
found on PATH |
Extractors: 7zz, 7z or 7za, and unrar |
RUST_LOG |
info,sqlx=warn |
Log level. haul=debug also saves the hoster pages of failed downloads, see Debugging a hoster. |
Settings in the UI¶
Everything else is under Settings in the web UI and stored in the database.
| Setting | Default | Range |
|---|---|---|
| Parallel downloads | 3 | 1–20 |
| Connections per file | 4 | 1–16, hosters may allow fewer |
| Bandwidth limit (KiB/s) | 0, no limit | over all downloads |
| Retries | 5 | 0–50 |
| Extract finished packages automatically | on | |
| Delete archives after successful extraction | off | |
| Remove the downloads from the list after successful extraction | off | |
| Ask for the archive password when none fits | on | |
| Verify the checksum after the download | on |
The same page holds the archive password list, the captcha userscript, the API token for Click'n'Load, the folders and extractors Haul found, and:
- Language: German or English for this browser, including messages from the server and the hosters. It is also switchable at the bottom of the sidebar.
- Login: change your password, or log out.
Health check¶
GET /api/health answers {"status":"ok"} without a login. The image uses it as its Docker
HEALTHCHECK, and you can point an uptime monitor at it.
Updating¶
With Podman: podman auto-update, or systemctl --user restart haul after podman pull.
Downloads in progress resume after the restart.
Tags: latest is the latest release, 1.2.3 and 1.2 pin a version.
Behind a reverse proxy¶
Haul is a single HTTP service on port 8080. The live progress uses Server-Sent Events on
/api/events, so the proxy must not buffer that path. With nginx:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_buffering off; # live progress (SSE)
proxy_read_timeout 1h;
}
Caddy and Traefik need no extra settings for SSE.