Skip to content

Kosztyk/jlmkr-webui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ChatGPT Image Jan 24, 2026, 04_15_16 PM

Jlmkr-webui (TrueNAS SCALE) — Jailmaker Web UI

A Docker-based Web UI for managing Jailmaker “jail-like containers” powered by systemd-nspawn on TrueNAS SCALE.

This project is a convenience layer around the upstream Jailmaker workflow and concepts documented here (usage section):

https://github.com/Jip-Hop/jailmaker?tab=readme-ov-file#usage

What are “jail-like containers with systemd-nspawn” on TrueNAS SCALE?

TrueNAS SCALE is Linux-based, and systemd-nspawn can run lightweight, OS-level environments (often called “jails” in TrueNAS/FreeBSD parlance). These environments behave like containers but feel closer to small VMs:

  • Each jail has its own root filesystem and userspace.
  • You can start/stop them like services.
  • You can bind-mount datasets into them.
  • They are ideal for running services in a clean, isolated userspace while still integrating well with the host storage layout.

Jailmaker (upstream) provides a CLI (jlmkr.py) that creates and manages these nspawn-based “jails” using an on-disk layout such as:

  • <baseDir>/jails/<name>/...

Intent of this application

jlmkr-webui aims to make Jailmaker usable from a browser on TrueNAS SCALE:

  • Provides a web dashboard to list, create, start/stop/restart/remove jails.
  • Supports multi-root setups (multiple datasets / base directories).
  • Provides streamed logs for long-running operations (create/backup/restore).
  • Adds quality-of-life behaviors (e.g., keeping jail running-state during backup; starting jail after restore).
  • Works well with TrueNAS SCALE by running inside a privileged Docker container that can execute Jailmaker commands on the host via nsenter.

The Web UI is designed to make day-to-day container operations (create/start/stop/shell/logs/config) simple, while still keeping the underlying workflow transparent and fully usable from the command line.

Screenshot 2026-01-24 at 20 30 54 Screenshot 2026-01-24 at 20 31 13 Screenshot 2026-01-24 at 20 31 21

How it works (TrueNAS SCALE / Docker model)

On TrueNAS SCALE, the recommended mode is:

  • Container runs with:
    • privileged: true
    • pid: host
    • mounts /run for DBus and basic host access
  • Commands are executed on the host using:
    • nsenter -t 1 ... chroot /proc/1/root ...
  • Jailmaker (jlmkr.py) lives on your datasets, and this UI calls it.

Security note

This container can run host-level commands. Treat it as a trusted admin tool. Put it behind your LAN or a reverse proxy with strong authentication.


Requirements

  • TrueNAS SCALE with Apps/Docker support
  • Datasets mounted under /mnt/...
  • A place to store UI state (recommended dataset), e.g.:
    • /mnt/Data/jailmaker-webui-state
  • Jailmaker base directories (one per “root”), e.g.:
    • /mnt/applications/jailmaker
    • /mnt/backup/alina/jailmaker
    • etc.

Installation (Docker Compose on TrueNAS SCALE)

Below is a working example docker-compose.yml for TrueNAS SCALE using network_mode: host.

Important

  • Use strong secrets for JWT_SECRET and PASSWORD_RESET_CODE.
  • Ensure you mount each root path you want to manage into the container (rw).
  • Ensure you mount your state dataset to /data.
services:
  jlmkr-webui:
    image: kosztyk/jlmkr-webui:latest
    container_name: jlmkr-webui
    restart: unless-stopped
    user: "0:0"

    privileged: true
    pid: host

    # Easiest on TrueNAS; alternatively publish ports (see note below)
    network_mode: host

    environment:
      # Web UI
      PORT: "3000"
      # Set these to strong secrets
      JWT_SECRET: "changeme"
      PASSWORD_RESET_CODE: "changeme"
      STATE_DIR: "/data"
      JLMKR_DATA_DIRS: "/mnt/tank/path where jails will be saved/jailmaker"
      JLMKR_SCRIPT_PATHS: "/mnt/tank/path where jails will be saved/jailmaker/jlmkr.py"
      JLMKR_EXEC_MODE: "nsenter"

    volumes:
      - "/mnt/backup/alina/jailmaker:/mnt/backup/alina/jailmaker:rw"
      - "/mnt/backup/test:/mnt/backup/test:rw"
      - "/mnt/immichp/jailmaker:/mnt/immichp/jailmaker:rw"
      - "/mnt/applications/jailmaker:/mnt/applications/jailmaker:rw"
      - "/mnt/iCloud\\ sync/immich/jailmaker:/mnt/iCloud\\ sync/immich/jailmaker:rw"
      - "/mnt/Data/Backups/jails:/mnt/Data/Backups/jails:rw"
      - "/mnt/Data/jailmaker-webui-state:/data:rw"
      - /run:/run:rw
      - /sys/fs/cgroup:/sys/fs/cgroup:rw

Access the UI

With network_mode: host and PORT=3000, browse to:

  • http://<truenas-ip>:3000

First-time setup

1) Bootstrap admin user

On the login screen, use the bootstrap workflow (only possible when no users exist yet). After bootstrap, log in normally.

2) Configure roots (Installation tab)

A “root” is a Jailmaker base directory such as:

  • /mnt/applications/jailmaker

Each root should contain:

  • /mnt/.../jailmaker/jlmkr.py
  • /mnt/.../jailmaker/jails/ (created by Jailmaker as needed)

The UI supports multi-root, so you can keep different jails on different datasets.


Using the Web UI (tab by tab)

Jails tab

Purpose: View and control existing jails across all configured roots.

What you can do:

  • List jails (aggregated from enabled roots)
  • Start / Stop / Restart
  • Remove (delete jail files)
  • Open Shell (interactive terminal via host execution)
  • Refresh the list

Notes:

  • If no roots are configured, you’ll see a banner prompting you to configure Installation.

Create tab

Purpose: Create a new jail (streamed output).

Key fields:

  • Root selector (where the jail will be created)
  • Jail name
  • Distro / Release (from Jailmaker images index)
  • Additional options (start after create, binds, etc.)
  • Clear button resets the whole form

Optional feature:

  • Install Docker checkbox:
    • If checked, the UI injects a first-boot setup script that installs Docker + Docker Compose inside the jail (best-effort, distro-dependent).

Notes:

  • Creation runs as a streamed task; you’ll see progress and the final exit code.

Backup/Restore

Purpose: Backup and restore jail directories using streamed tasks.

Backup

  • Choose jail
  • Choose Backup root (or Auto-detect if available)
  • Backup is created as a .tar.gz archive in the configured backups location.

Running-state behavior:

  • If the jail was running before backup, the app stops it for consistency and starts it again after backup.

Restore

  • Choose backup archive
  • Choose Restore target root (this is important in multi-root setups)
  • Extracts into <targetRoot>/jails/<name>
  • After restore, the app attempts to start the jail

Installation tab

Purpose: Configure and verify roots.

What happens when you add a new path:

  • App validates / normalizes it into a Jailmaker root.
  • (If enabled in your build) it can:
    • ensure <path>/jailmaker exists
    • ensure <path>/jailmaker/jlmkr.py exists
    • download jlmkr.py from upstream if missing
    • chmod +x jlmkr.py

Verify:

  • “Verify all” checks:
    • path exists
    • script exists
    • jlmkr.py images runs successfully in TrueNAS nsenter mode

Theme toggle

Purpose: Switch between dark/light mode.

  • Theme preference is stored locally (browser) so the UI stays consistent across sessions.

Troubleshooting

Start/stop actions return HTTP 500

  • Check container logs:
docker logs --tail 200 jlmkr-webui

Common causes:

  • syntax error in server.js (container will crash-loop)
  • root resolution mismatch (invalid rootId)
  • missing host mounts (/run, datasets not mounted rw)

“Jail not found” when backing up/restoring

Usually means you’re targeting the wrong root.

  • Confirm jail exists on disk:
ls -la /mnt/<dataset>/jailmaker/jails
  • In UI, explicitly pick the correct Backup root / Restore target root.

Reverse proxy / subpath issues

If you host behind a reverse proxy using a subpath, ensure the UI is using relative API paths (recommended). If you see requests going to /api/... instead of ./api/..., fix your base path handling.


Related projects

This Web UI (Docker + nsenter TrueNAS model) is one option. You may also be interested in:

Similar GUI using SFTP connection:
https://github.com/Kosztyk/TrueNas-Scale-Jailmaker-GUI

Bare-metal Ubuntu/Debian approach:
https://github.com/Kosztyk/-Jail-like-Linux-containers-with-systemd-nspawn

Upstream Jailmaker:

https://github.com/Jip-Hop/jailmaker

License / Credits

  • Jailmaker concept and jlmkr.py originate from the upstream Jailmaker project.
  • This Web UI is an independent interface layer that executes upstream commands and follows upstream semantics.

About

A Docker-based Web UI for managing **Jailmaker** “jail-like containers” powered by **systemd-nspawn** on **TrueNAS SCALE**.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors