Modal Host Setup¶
Run the entire Mirumoji app (the server and the frontend) privately on your own Modal account with one command, no local Docker and no public exposure
Modal Host vs Modal Transcription Backend
-
The
Modal Transcription BackendRuns MirumojiLocallyWith Docker And OffloadsonlyThe Heavy GPU Transcription To Modal. Everything Else (The Server, The Frontend, Your Data) Stays On Your Machine -
The
Modal HostRunsEverythingOn Modal. There Is No Local Docker At All, And Your Data Lives In AModal VolumeInstead Of A Local One -
Both Use The Same Modal Tokens, Your
Configuration Variables, And The Same GPU Offload Worker Under The Hood
How It Works¶
By default a deploy creates two Modal apps and one volume in your workspace
| Resource | Role | Scaling |
|---|---|---|
mirumoji-host |
The Server (With The Modal Backend) + Built Frontend, Served By One FastAPI App |
CPU-Only, One Always-Warm Container |
mirumoji-offload |
Whisper Transcription + Media Conversion | GPU, Scales To Zero When Idle |
mirumoji-data |
A Persistent Data Volume Holding Your Database + Media | Persistent |
Why Two Apps
-
The interactive parts of Mirumoji (watching videos, tokenizing Japanese, dictionary lookups) are
CPU-Only, so the host runs on a cheap CPU container which is kept warm so that background jobs are never cut off and the single-writer database always has exactly one instance -
Only transcription or conversion needs a GPU, so the host hands that work to the
mirumoji-offloadapp (the same one the localmodalbackend uses), which the server creates on demand and always scales to zero when idle -
Keeping a GPU container running idle is expensive, so this split means you only ever pay for the GPU while a transcription or conversion is actually running
The Cost Trade-Off
-
The always-warm CPU host is a small standing cost, since it never scales to zero (that is what keeps the app instantly reachable and background jobs alive)
-
The expensive part, the GPU worker, still costs nothing while idle
-
You can configure the container's provisioned hardware with the
Modal Host Configuration Variables
Compute Modes
The two-app split above is the default, but you can change how the host runs
-
CPU Host + Offload (default) → The always-warm container is
CPU-Onlyand offloads transcription tomirumoji-offload, so a GPU is paid for only while a job runs. This suits most immersion use -
Single-App GPU Host → Set
MIRUMOJI_HOST_ON_GPU=1to run the whole app in one container on the GPU named byMIRUMOJI_MODAL_GPU, withfaster-whisperin-process and no offload worker. Transcription starts instantly, but the GPU is now always-warm (more expensive), so this suits heavy back-to-back transcription -
Non-Preemptible CPU Host → Set
MIRUMOJI_HOST_NONPREEMPTIBLE=1to run theCPU-Onlyhost on guaranteed capacity (a 3x price) so a spot reclaim never restarts it mid-job.Modaldoes not allow this on a GPU host, so the two options can't be combined -
A restart matters because a job that was running at the time is marked failed rather than re-queued. Re-running it automatically could duplicate an output that had already been written but not yet recorded, so the retry is left to you. Long batches are the case that benefits most from guaranteed capacity
Prerequisites¶
You'll need a Modal account with your MODAL_TOKEN_ID + MODAL_TOKEN_SECRET configured. This is the same token pair that the modal backend uses, so if you have already set that up you are ready. If not, follow Get Your API Token Pair
Deploy¶
# Set The App's Login Password
mirumoji config set MIRUMOJI_WEB_PASSWORD <your-password> # (1)!
mirumoji modal deploy # (2)!
- Skip This And Pass
--generate-password(-gp) TodeployTo Generate + Save A Strong One Automatically - The First Deploy Composes The Image And Takes A Few Minutes. Later Deploys Are Near-Instant
This Prints The App URL + The Login Username (always mirumoji) + Password + Link To The Modal Dashboard
-
Open the desktop launcher (
mirumoji gui) and go to theModal Hostpanel -
Set
MIRUMOJI_WEB_PASSWORDunderSettings→Modal Hostfirst, or tickGenerate Passwordon the panel -
Click
Deploy. When it finishes, the panel shows the app URL as a clickable link along with the login details
Idempotent Deploys
-
Re-running
deployonly rolls the app forward when themirumojiversion changes, so it never creates duplicates -
Pass
--force(-f) to redeploy the same version through the CLI
Open It¶
Open The Printed URL. Your Browser Will Show A Login Prompt
-
Username→mirumoji -
Password→ The Value OfMIRUMOJI_WEB_PASSWORD
Once you log in, the whole app loads and works exactly like a local install, with a real, publicly trusted certificate (Modal serves everything over HTTPS on a *.modal.run address), so there is no certificate to install as there is when serving on LAN ips
Why A Browser Login Prompt
-
The hosted app is protected with
HTTP Basic Auth, which is the only scheme a browser handles natively at the edge -
A
401makes the browser show its own prompt and then attach the credentials toeverylater request (the page, the assets, the API, the uploads) automatically -
That gates the whole app without a login page or any change to the server or frontend, which keeps
Mirumojifree of auth for its primary use as a self-hosted tool -
After the first login the host sets a persistent,
HttpOnlycookie and accepts it in place of the prompt, so an installediOSPWA(which drops theBasic Authcredential cache whenever it is closed) does not re-prompt for the password on every reopen. ChangingMIRUMOJI_WEB_PASSWORDinvalidates it -
See
Sharing Outside Your Networkfor how this compares to the other sharing options and how to add identity-based access if you need it
Your Data¶
Unlike a local install (which keeps your data in local Docker volumes), the hosted app stores your media and database in the mirumoji-data Modal Volume, created automatically on the first deploy
How It Stays Fast And Durable
-
The host does not read and write directly on the volume, whose network layer is slow for the many small, random reads that video playback and the database make. It operates on the container's local disk and mirrors your media and database to the volume in the background. Scratch a job re-creates each run is skipped, and a file still being written is only mirrored once it is complete
-
Modalcommits the volume as the app runs and on shutdown, and the host restores it into the container on every start, so your data survives a redeploy, a stop, or a spot preemption -
This covers your stored data, not work in progress. A job that was running when the container restarted is marked failed and has to be submitted again (see
How It Worksfor the non-preemptible option that avoids the restart entirely)
Download everything in the volume to a local folder at any time
- Defaults To A
mirumoji-dataFolder In The Current Directory. Re-downloading Overwrites The Existing Copies
Tuning The Host (Optional)¶
The host container reserves CPU and Memory so the server never gets throttled into a failed health check. The defaults are a sensible balance, but you can adjust them
| Variable | Default | What It Does |
|---|---|---|
MIRUMOJI_HOST_CPU |
2 |
CPU Cores Reserved For The Always-Warm Web Container (Higher Is Faster But Costs More) |
MIRUMOJI_HOST_MEMORY |
4096 |
Memory In MiB Reserved For The Web Container (Higher Avoids Restarts But Costs More) |
MIRUMOJI_HOST_MAX_CONCURRENT_REQUESTS |
100 |
How Many Requests The One Container Serves At Once |
MIRUMOJI_HOST_ON_GPU |
0 |
Run The Host On A GPU With Whisper In-Process (1) Instead Of A CPU Host + Offload Worker (0). Uses MIRUMOJI_MODAL_GPU For The GPU Type |
MIRUMOJI_HOST_NONPREEMPTIBLE |
0 |
Run The CPU-Only Host On Non-Preemptible Capacity (1) At A 3x Cost. Not Available With A GPU Host |
The GPU worker is tuned by the same Modal Variables that the local modal backend uses (MIRUMOJI_MODAL_GPU, MIRUMOJI_MODAL_SCALEDOWN_WINDOW, ...). Change any of these, then redeploy for them to take effect
Managing The Deployment¶
- Show The Host App, The Data Volume, And The URLs
- Stop The Host App (Your Data Volume Is Kept)
- Stop The Host App + Delete The Data Volume
The GPU offload worker is owned by the server, which stops it during shutdown, so modal down does not touch it and modal status does not list it
This Is A Publicly Reachable Service
-
A Modal web endpoint is reachable by anyone who has both the URL and the password, so use a strong
MIRUMOJI_WEB_PASSWORD(letting--generate-passwordcreate one is the safe default) -
Anyone who can log in can read and modify the hosted profiles, media, and clips
-
For identity-based access instead of a shared password, see the
Sharingguide