apps.header.allAppsCount
Typr-Companion
apps.detail.types.app from max.prime's Repository
apps.detail.sections.overview
Readme
View on GitHubInstall Typr Companion on Unraid
Typr Companion can run on Unraid from the official
ghcr.io/max-prime-math/typr-server image. It is stateless by default. One
dedicated host directory can optionally be mapped for explicit manual project
sync; browser-local Typr remains authoritative.
The service has no authentication. Use it only on a trusted LAN or private VPN, with mutually trusted users and documents. Never expose it to the public Internet, through router port forwarding, a public tunnel, or a public reverse proxy. TLS improves transport and browser compatibility; it does not add application authentication.
Stock Unraid kernels may not provide Landlock. This template therefore opts into a narrowly limited fallback: Companion may run without its native filesystem sandbox only while it is stateless and has no host workspace mounted. Keep this mode limited to mutually trusted documents. If any workspace is configured, Companion still requires Landlock and refuses startup when it is unavailable.
Install the template
Until the template is listed in Community Applications, install it as a user template:
Open an Unraid terminal.
Download
unraid/typr-companion.xml:curl -fsSL \ https://raw.githubusercontent.com/max-prime-math/typr-server/main/unraid/typr-companion.xml \ -o /boot/config/plugins/dockerMan/templates-user/typr-companion.xmlOpen Docker → Add Container and select Typr-Companion.
Keep bridge networking and container port
8484.Add the exact self-hosted Typr origin to Allowed Typr origins if needed.
Leave Workspace directory and Workspace API root blank for the default stateless deployment. The prefilled Workspace ID is ignored while the root is blank.
Keep Allow stateless Unraid fallback set to
1on a stock Unraid kernel. This does not permit a mapped workspace without Landlock.Apply the template and wait for a healthy container.
The template enforces UID 1000, non-privileged operation, dropped capabilities, no-new-privileges, a read-only root, 512 MiB no-exec tmpfs, 256 PIDs, 2 GiB memory/swap, and two CPUs. The image probes its Landlock launcher before listening. When that probe fails, the explicit template opt-in permits only the volume-free stateless fallback and logs a prominent trusted-document warning. Without that opt-in, or whenever a workspace is mapped, startup fails closed.
Optional mapped workspace
Configure all three advanced workspace fields together:
This mode requires an Unraid kernel with working Landlock support. Stock kernels
that return Landlock is unavailable cannot safely enable the mapped workspace;
leave the directory and API root blank. The stateless fallback never bypasses
this check.
- Workspace directory: one newly created dedicated directory, mounted RW to
/workspace. - Workspace API root: exactly
/workspace. - Workspace ID: a stable opaque identifier such as
home-workspace.
The host directory must be readable and writable by UID 1000. Do not map /,
/mnt, /mnt/user, an entire share, an appdata root, a symlinked directory, or
the Docker socket. Create a narrowly named subdirectory and grant UID 1000 only
the access it needs.
The API exposes regular files below that exact root; it does not expose the host path or arbitrary browsing. Browser storage remains the primary copy and sync is manual. Unlinking or removing the container does not delete mapped files, but an explicit file-API deletion does delete that selected host file. Keep independent backups.
Verify the container
From Unraid:
curl -fsS http://127.0.0.1:8484/api/v1/status
The response reports protocol version 1, native compile capabilities, and
projectStorage: false unless all mapped-workspace fields are valid. The WebUI
link opens the same status response. In fallback mode, the container log states
that the native filesystem sandbox is unavailable and that trusted documents are
required. Startup failures are visible in the same log.
Add trusted HTTPS
In a browser on another device, 127.0.0.1 means that browser device, not the
Unraid server. An HTTPS Typr page also cannot call a plain HTTP/WS Companion
because the browser blocks mixed content. Create a dedicated client-trusted HTTPS
hostname restricted by firewall or VPN to trusted clients. Forward it to
http://UNRAID-IP:8484, enable WebSocket upgrades, use a long read timeout, and
allow request bodies of at least 25 MiB. For example:
location / {
proxy_pass http://UNRAID-IP:8484;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
client_max_body_size 25m;
}
Keep the hostname unreachable from the public Internet. Plain HTTP on a non-loopback LAN address is not a secure context and a self-hosted Typr page will lose service-worker/PWA and filesystem-related features. A self-signed certificate must be trusted by every client before it is useful.
Private HTTPS with Tailscale Serve
Install and connect the official Tailscale plugin on the Unraid host. Keep the Typr-Companion container's per-container Use Tailscale switch off. That Unraid feature injects a mounted startup hook which requires root privileges; Companion deliberately runs as UID 1000 with a read-only root, and its stateless fallback rejects unexpected mounts. Enabling the switch therefore causes a restart loop rather than a working tailnet endpoint.
With Companion running normally on host port 8484, use host-level Tailscale
Serve instead:
tailscale serve --bg --https=8443 http://127.0.0.1:8484
tailscale serve status
Enter the resulting base URL, such as
https://UNRAID-NAME.TAILNET.ts.net:8443, in Typr. Serve terminates trusted TLS
and proxies both the HTTP API and WebSocket upgrade within the tailnet. The
browser device must be connected to that tailnet and allowed by its access
rules. Keep Tailscale Funnel disabled: Funnel would make this unauthenticated
service public. If Typr itself uses a Tailscale HTTPS origin, add that exact
scheme, hostname, and port to Allowed Typr origins.
Connect Typr
- Open Typr in the browser that will use Companion.
- Open Settings → Editor → Typr Companion.
- Enter the browser-reachable HTTPS URL and select Apply.
- If a workspace is configured, open Settings → Sync and explicitly link the selected project.
The URL is saved only in that browser. Allowed origins contain exact scheme, host, and port values with no path or trailing slash. CORS is not authentication. Chrome or Edge may also request Local Network Access permission.
If the status remains unavailable, inspect the browser console, Companion logs,
reverse-proxy WebSocket settings, firewall/VPN rules, certificate trust, and
TYPR_COMPANION_ALLOWED_ORIGINS.
Update, pin, roll back, or remove
Use Unraid's normal container update action for latest. For reproducible
native TeX behavior, change Repository to a complete version after it is
published, for example:
ghcr.io/max-prime-math/typr-server:0.1.4
Rollback uses the same field with the prior known-good version. Removing the container removes no browser-local projects and no mapped host directory.
The template remains a direct user template until both public image tags exist,
it passes install/update/rollback/removal and HTTPS/WebSocket tests on a real
Unraid host, and a maintained support destination appears in the template's
Support field. An optional profile Forum field may point to the same
destination. Then run npm run test:unraid -- --submission-ready and the portal's
Validate and Scan actions before the maintainer explicitly approves Community
Applications submission.
apps.marketingCta.appInstallTitle
apps.marketingCta.appInstallDescription
apps.detail.sections.requirements
apps.detail.sections.categories
apps.detail.sections.related
apps.detail.related.exploreCategories
apps.detail.related.exploreAllapps.detail.sections.links
apps.detail.sections.details
ghcr.io/max-prime-math/typr-server:latestapps.detail.sections.runtime
- apps.detail.details.webui
http://[IP]:[PORT:8484]/api/v1/status- apps.detail.details.network
bridge- apps.detail.details.shell
sh- apps.detail.details.privileged
- false
- apps.detail.details.extraParams
--restart=unless-stopped --user=1000:1000 --read-only --tmpfs=/tmp:rw,nosuid,nodev,noexec,size=536870912 --cap-drop=ALL --security-opt=no-new-privileges:true --pids-limit=256 --memory=2g --memory-swap=2g --cpus=2
apps.detail.sections.configuration
Host port used by the reverse proxy and local status checks. Container port must remain 8484.
- apps.detail.config.target
- 8484
- apps.detail.config.default
- 8484
- apps.detail.config.value
- 8484
Comma-separated exact browser origins, including scheme, host, and port with no path or trailing slash. Add the self-hosted Typr origin. CORS is not authentication.
- apps.detail.config.target
- TYPR_COMPANION_ALLOWED_ORIGINS
- apps.detail.config.default
- https://typr.ca,https://beta.typr.ca,https://dev.typr.ca
- apps.detail.config.value
- https://typr.ca,https://beta.typr.ca,https://dev.typr.ca
Keep exactly 1 on stock Unraid: if Landlock is unavailable, allow trusted-document compilation only when no host workspace is mounted. A mapped workspace always fails closed without Landlock.
- apps.detail.config.target
- TYPR_COMPANION_ALLOW_UNSANDBOXED_STATELESS
- apps.detail.config.default
- 1
- apps.detail.config.value
- 1
Optional one exact dedicated project directory. Never map /, /mnt, /mnt/user, a broad share, appdata root, symlinked root, or the Docker socket. UID 1000 needs read/write access.
- apps.detail.config.target
- /workspace
Set exactly /workspace only when Workspace directory is configured. Leave blank to disable the file API.
- apps.detail.config.target
- TYPR_COMPANION_WORKSPACE_ROOT
Stable opaque letters/numbers/dot/underscore/hyphen identifier for browser bindings; never put a host path here. Ignored while the API root is blank.
- apps.detail.config.target
- TYPR_COMPANION_WORKSPACE_ID
- apps.detail.config.default
- unraid-workspace
- apps.detail.config.value
- unraid-workspace