All apps · 0 apps
Typr
Docker app from max.prime's Repository
Overview
Readme
View on GitHubSelf-host Typr
Typr's self-hosted image serves the browser application; it is not a project server. Projects, settings, browser Git data, and sync bindings remain in each browser's IndexedDB and OPFS by default. The container has no project or appdata volume, and replacing it does not migrate or delete browser data.
Self-hosted Typr and Typr Server are separate images and repositories:
ghcr.io/max-prime-math/typrserves the Typr PWA.ghcr.io/max-prime-math/typr-serveris the optional native Typr Server.
Both are unauthenticated trusted-environment services. Run them only on a trusted machine, trusted LAN, or private VPN. Never expose either service to the public Internet. A reverse proxy and TLS improve transport and browser compatibility; they do not add application authentication or make public exposure safe. Any optional client-side sign-in screen is a convenience layer, not a network security boundary.
Choose an image
The full and lite variants contain the same application files and disable Google Drive at build time. Browser-local storage remains the default in both.
| Variant | Moving tag | Exact tag | Compiler assets | Network needed to load the pinned compiler core |
|---|---|---|---|---|
| Full | latest (latest-full is explicit) |
X.Y.Z or X.Y.Z-full |
Exact release bundled in the image | No |
| Lite, R2 | latest-lite |
X.Y.Z-lite |
Exact release proxied from assets.typr.ca through the Typr origin |
Yes |
| Lite, local | latest-lite |
X.Y.Z-lite |
Exact release mounted read-only at /compiler-assets |
No |
For reproducible deployment and rollback, replace moving tags with the complete
X.Y.Z and X.Y.Z-lite tags or a registry digest. Bare tags always select the
full image. X.Y, X, and latest are moving full aliases; their -full and
-lite forms make the variant explicit. sha-<12 characters> is an immutable
full-image diagnostic alias and the suffixed SHA aliases select an explicit
variant. Do not mix an asset directory from one release with another image:
lite/local validates the manifest, exact file set, sizes, and SHA-256 hashes
before it becomes healthy.
"Full" means the pinned Typst compiler and BusyTeX bundles are included. Some user-selected packages, external images, links, GitHub operations, and optional services can still require a network connection.
Docker Compose
The default compose.yaml runs the full image on loopback:
docker compose up -d
curl -fsS http://127.0.0.1:8080/healthz
Open http://127.0.0.1:8080. The Compose file uses a non-root image, read-only
root filesystem, bounded no-exec tmpfs, dropped capabilities, no-new-privileges,
and PID/memory/CPU limits.
Run the lite image with its pinned R2 source by selecting it in the same Compose file:
TYPR_IMAGE=ghcr.io/max-prime-math/typr:X.Y.Z-lite docker compose up -d
To run the same lite image with a local compiler release, first download and
extract the exact release directory described by that image's release notes.
Put both persistent selections in .env so every later Compose command uses the
same variant and mount:
TYPR_IMAGE=ghcr.io/max-prime-math/typr:X.Y.Z-lite
TYPR_COMPILER_ASSETS_DIR=/srv/typr/compiler-assets
docker compose -f compose.yaml -f compose.local-assets.yaml up -d
One way to obtain the exact pack without broad host mounts is to copy it from the matching full image. Use the same complete version for both image variants:
mkdir -p /srv/typr/compiler-assets
docker create --name typr-asset-source ghcr.io/max-prime-math/typr:X.Y.Z
docker cp typr-asset-source:/compiler-assets/. /srv/typr/compiler-assets
docker rm typr-asset-source
The directory must contain manifest.json, core/busytex/..., and
typst/typst_ts_web_compiler_bg.wasm at its root. It must be mounted read-only;
the container rejects writable or nested writable mounts, symlinks, special
files, missing files, extra files, wrong sizes, and wrong hashes.
Set TYPR_IMAGE to an exact image tag or digest before a Compose command to pin
or roll back. Put the selection in a local .env file so every later Compose
command keeps the same variant:
TYPR_IMAGE=ghcr.io/max-prime-math/typr:X.Y.Z-lite
Update that selected variant with:
docker compose pull
docker compose up -d
Use the same -f arguments for lite/local. There is no in-container updater.
Export project backups before an update even though replacing the container
does not itself touch browser data.
Network and browser-origin rules
The Compose examples bind 127.0.0.1 by default. This is the safest single-host
configuration, and browsers treat loopback HTTP as a secure-context exception.
To listen on a LAN interface, set TYPR_BIND_ADDRESS deliberately—for example,
TYPR_BIND_ADDRESS=192.168.1.20—and enforce trusted-LAN/VPN access with the host
firewall. Do not bind a publicly reachable interface.
Plain HTTP on a non-loopback LAN address is not a secure context. Normal editing and IndexedDB storage can still work, but service-worker installation/offline updates, File System Access/local-folder sync, and other secure-context features may be unavailable. Trusted HTTPS is required for the full cross-device PWA experience.
Browser storage belongs to the exact origin: scheme, hostname, and port. Moving
from http://nas:8080 to https://typr.example, changing a port, or changing a
hostname creates a different storage silo. Export a Typr project backup from the
old origin before changing the URL, then import it at the new origin. Clearing
site data can remove the browser's only project copy.
An HTTPS Typr page cannot call a plain HTTP/WS Typr Server because the browser blocks mixed content. For cross-device Typr Server use, give both services trusted HTTPS endpoints restricted to the LAN/VPN, forward Typr Server WebSocket upgrades, and add the exact Typr origin to the Typr Server allowlist. HTTPS is not permission to expose either endpoint publicly.
Private HTTPS with Tailscale on Unraid
On Unraid, use the official Tailscale plugin on the host and Tailscale Serve as the private HTTPS reverse proxy. Keep the per-container Use Tailscale switch off for both Typr images: Unraid's injected container hook needs a different privilege and mount model than these non-root, read-only containers.
For example, if Typr is published on host port 7080, run this from an Unraid
terminal:
tailscale serve --bg --https=8444 http://127.0.0.1:7080
tailscale serve status
Open the resulting https://UNRAID-NAME.TAILNET.ts.net:8444 URL only from a
device joined to the authorized tailnet. Use a different private HTTPS port for
Typr Server as documented in its Unraid guide. Changing from the LAN URL to the
Tailscale URL creates a new browser-storage origin, so export projects from the
old origin before moving. Tailscale Serve stays within the tailnet;
Funnel must remain disabled because these services must never be public.
Optional Typr Server and mapped workspace
Typr works without Typr Server. A fresh self-hosted browser profile makes no Typr Server or mapped-workspace request. To opt in, install Typr Server from its separate repository, enter its URL under Settings → Editor → Typr Server, paste its API key when the server requires one, and apply the connection settings. The key is masked in Settings, stored in that browser's IndexedDB, and attached to HTTP and live-preview WebSocket connections without being placed in the Typr Server URL.
The optional host workspace is mounted into the Typr Server container—not the Typr web container. When an administrator enables that single scoped directory, a user may explicitly link the selected browser-local project under Settings → Sync and run a manual synchronization. Unlinking never deletes server files, and browser autosave continues if Typr Server is unavailable.
Unraid
templates/typr.xml is the Typr web template. It uses
the full image and needs only port 8080; project files are not stored in Unraid
appdata. To use lite, manually select its Repository tag and then choose R2 mode
or an exact read-only compiler pack in the advanced fields; never map project
files or a broad share there. templates/typr-server.xml
is the canonical Community Applications template for the independently maintained
Typr Server; install it when
native LaTeX or a mapped workspace is wanted. Keeping both templates in this
repository groups both apps under one Community Applications repository profile.
For private Tailscale access, leave each container's Use Tailscale switch off
and follow the host-level Serve setup above.
Before Community Applications submission, validate both templates on a real
Unraid host, including install, health, browser access, update, rollback, and
removal. Put a maintained support destination in each template's Support
field; an optional profile Forum field may point to the same destination. Then run
npm run test:unraid -- --submission-ready plus the portal's Validate and Scan
actions. Portal approval makes them Community Applications listings; the same
files remain usable as direct user templates before approval.
Verify and remove
docker compose ps
curl -fsS http://127.0.0.1:8080/healthz
docker compose logs typr
Remove the container with docker compose down, using the same -f arguments
used to start it. This removes no browser projects. To remove a browser project
copy, use Typr's project controls or the browser's site-data controls only after
exporting any required backup.
Install Typr on Unraid in a few clicks.
Find Typr in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Requirements
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/max-prime-math/typr:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8080]/- Network
bridge- Shell
sh- Privileged
- false
- Extra Params
--restart=unless-stopped --user=101:101 --read-only --tmpfs=/tmp:rw,nosuid,nodev,noexec,size=33554432 --cap-drop=ALL --security-opt=no-new-privileges:true --pids-limit=64 --memory=256m --memory-swap=256m --cpus=1
Template configuration
Host port for the Typr web interface. Container port must remain 8080.
- Target
- 8080
- Default
- 8080
- Value
- 8080
The full image uses local. For a lite image, use r2 without a mount or local with the exact matching read-only compiler pack.
- Target
- TYPR_COMPILER_ASSETS_MODE
- Default
- local
- Value
- local
Optional exact compiler-release directory for lite/local only. Never map /, /mnt, /mnt/user, an appdata root, project files, or the Docker socket.
- Target
- /compiler-assets