Server setup

The h3xed server runs on macOS, Windows, and Linux. Pick an install path below — a one-line native installer or Docker — finish in the browser-based setup wizard, choose how you want remote access (the h3xed.app relay or your own reverse proxy), and configure hardware transcoding.

Install the server

Two ways to install, on any of the three operating systems:

Whichever you choose, the first run opens the setup wizard at http://localhost:32400.

Quick install — macOS

Run as your normal user (not sudo) in Terminal:

curl -fsSL https://h3xed.app/install-macos.sh | bash

Quick install — Windows

Open an elevated PowerShell (Start → type PowerShell → right-click → Run as administrator), then:

irm https://h3xed.app/install-windows.ps1 | iex

Quick install — Linux

Run as root with sudo:

curl -fsSL https://h3xed.app/install.sh | sudo bash

Re-running any installer upgrades the app in place and preserves your data.

Docker (macOS, Windows, Linux)

One self-contained image runs the server on all three OSes, with ffmpeg bundled so software transcoding works everywhere with no extra setup. Install Docker Desktop (macOS/Windows) or Docker Engine plus the Compose plugin (Linux). Then either pull the published image:

docker pull ghcr.io/roxas712/hexed

or bring it up with Compose from the repo. Point HEXED_MEDIA_DIR at your media library (mounted read-only), then:

# macOS / Linux
export HEXED_MEDIA_DIR=/Users/you/Movies
docker compose up -d

# Windows (PowerShell)
$env:HEXED_MEDIA_DIR="D:\Media"
docker compose up -d

The default docker-compose.yml is cross-platform: it publishes port 32400 (no host networking), persists the database and metadata under ./data, mounts your media read-only at the in-container path /media, and restarts automatically. Prefer not to use an env var? Copy .env.example to .env, set HEXED_MEDIA_DIR there, and run docker compose up -d; if you skip it entirely it defaults to ./media next to the compose file.

Docker hardware transcoding: On macOS and Windows the Docker VM can't reach the GPU, so Docker does CPU (software) transcoding — correct and fully functional, just more CPU-intensive. For hardware transcoding on Mac/Windows, use the native installer above. On Linux, layer the override to enable GPU/VAAPI: docker compose -f docker-compose.yml -f docker-compose.linux.yml up -d.

Full Docker reference — persisted volumes, environment, and the Linux GPU override — lives in DOCKER.md in the repo.

Setup wizard

After any install path, open http://localhost:32400 (or http://YOUR_SERVER:32400 from another device). On first run the server serves a browser-based wizard that records your remote-access preference, signs in or creates an h3xed.app account (which links the server and becomes the admin), names the server, optionally takes a TMDB API key, and adds your first library with a live scan. Skipping the cloud link makes it a LAN-only server with a local admin password instead. The same options live in Settings afterward, so nothing here is one-shot.

h3xed.app relay

The easiest way to enable remote access is through the h3xed.app relay. When you link your server to h3xed.app during setup (or later from Settings), a secure relay is established automatically. This means:

Optionally, you can also forward a port for direct video streaming when remote — the wizard tests reachability and falls back to the relay if it can't get through. Either way the relay carries control traffic, so the server works from anywhere even without a port forward.

Recommended for most users: The relay is the simplest way to get remote access working. Use the nginx reverse proxy approach below only if you need a custom domain or full control over the connection. For a LAN-only server, skip remote access entirely in the wizard.

Nginx Reverse Proxy

If you prefer a custom domain or want direct control, proxy a subdomain to the Hexed server. Example for media.example.com:

server {
    listen 443 ssl http2;
    server_name media.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:32400;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Required for streaming
        proxy_buffering off;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;

        # WebSocket support (if needed later)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Or proxy via a path prefix (e.g. /hexed-api/):

location /hexed-api/ {
    proxy_pass http://127.0.0.1:32400/;
    proxy_buffering off;
    proxy_read_timeout 300s;
}
SSL: Use certbot for free Let's Encrypt certificates, or Cloudflare origin certificates if using their proxy.

Web app

The server serves its own web app at /app/ where people browse and stream. Share your server URL with the /app/ path (e.g. https://media.example.com/app/), or let invited users reach it through h3xed.app after they accept an invite.

Libraries & scanning

Add libraries for movies, TV, music, and photos — in the setup wizard for your first one, and from Settings any time after. Point each library at a folder on the server; the scanner indexes the files, structures shows into seasons and episodes, and pulls metadata from TMDB (poster art, summaries, cast, year, ratings) with auto-tagging.

Use a path the server can see:

Scans run in the background and can be triggered manually per library; a periodic scan also picks up new files automatically. You can refresh metadata for a whole library, fix a mismatch by searching TMDB for the right title, and organize titles into collections. Watch progress, watchlists, trickplay scrub thumbnails, chapters, and subtitles all come from the same indexed media.

Hardware transcoding

The native installers select hardware transcoding automatically when it's available: VideoToolbox on macOS and NVENC / Quick Sync on Windows work out of the box with no extra configuration. On Linux you supply the GPU drivers below. Docker on macOS and Windows is CPU-only; Docker on Linux needs the GPU override (see Docker). The requirements below apply to a Linux host.

NVIDIA (NVENC)

Requirements:

Verify:

nvidia-smi
ffmpeg -encoders 2>/dev/null | grep nvenc

Hexed auto-detects NVIDIA hardware and selects NVENC automatically.

Intel Quick Sync

Requirements:

AMD (VAAPI/AMF)

Requirements:

Check detected hardware via the API:

curl http://localhost:32400/api/hardware \
  -H "Authorization: Bearer YOUR_TOKEN"

Firewall

If your server runs a firewall, open the Hexed port:

# firewalld (Fedora/RHEL)
sudo firewall-cmd --add-port=32400/tcp --permanent
sudo firewall-cmd --reload

# ufw (Ubuntu/Debian)
sudo ufw allow 32400/tcp
Security: If exposing Hexed to the internet directly, always use nginx with SSL in front of it. The h3xed.app relay tunnel handles this for you automatically.

Managing the service

The native installers set up an auto-start service that runs in the background and restarts on crash. Use the commands for your platform:

macOS (launchd LaunchAgent)

# Restart
launchctl kickstart -k gui/$(id -u)/app.h3xed.server

# Stop
launchctl bootout gui/$(id -u)/app.h3xed.server

# Logs
tail -f ~/Library/Logs/Hexed/hexed.err.log

Windows (Scheduled Task)

In an elevated PowerShell:

# Start / stop
Start-ScheduledTask -TaskName HexedMediaServer
Stop-ScheduledTask  -TaskName HexedMediaServer

# Logs
Get-Content "$env:ProgramData\Hexed\logs\hexed.err.log" -Tail 50

Linux (systemd)

# Status / restart
sudo systemctl status hexed
sudo systemctl restart hexed

# Logs
sudo journalctl -u hexed -f

Docker

# View logs / restart
docker compose logs -f
docker compose restart

# Stop
docker compose down

Updating

For a native install, re-run the same one-line installer for your OS — it upgrades the app in place and preserves your data and configuration. For Docker, pull the latest image and bring the stack back up:

docker compose pull
docker compose up -d

SELinux (Fedora/RHEL)

On SELinux-enforcing systems, the Linux installer's systemd service runs the bundled server from /opt/hexed/app as the hexed user. If you see permission denials in journalctl -u hexed, confirm the install directory is owned by the hexed user (the installer sets this) and that any external media mounts are readable by it.