Nothing to guard, so no credential to keep
The web image was private, which is the registry's default, and a private image means Modal needs a pull credential on every cold start -- a rickub deploy token living as a Modal Secret, because the workflow's own registry token is short-lived by design. What that credential would be guarding is `build/web` and a python to serve it. The URL hands that bundle to anyone who opens it. So the image is public and `registry_secret` is gone: one less thing to create, rotate, or discover has expired when a container happens to go cold. The other way is still written down, in container.toml rather than only in a commit message, because it is the right choice the moment this image carries something the site does not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5581b0f parent: 627b785 modified
.modal/web/README.md +12 -12 | @@ -18,18 +18,18 @@ tested, and a deploy is a pull rather than a compile. The workflow is | ||
| 18 | 18 | it up, and deploying again replaces it in place because the app is |
| 19 | 19 | named by `[container] name`. |
| 20 | 20 | |
| 21 | -Two credentials live outside the repo, both one-time setup: | |
| 21 | +One credential and one setting live outside the repo, both one-time: | |
| 22 | 22 | |
| 23 | 23 | * `MODAL_TOKEN_ID` / `MODAL_TOKEN_SECRET`, as rickub repository |
| 24 | - secrets. The registry needs no secret of its own -- rickub | |
| 25 | - authenticates docker before a workflow's first step. | |
| 26 | -* A Modal Secret named `rickub-registry`, holding `REGISTRY_USERNAME` | |
| 27 | - and `REGISTRY_PASSWORD` for a rickub deploy token (Settings → | |
| 28 | - Packages; pull-only, and the username is any label). Modal pulls the | |
| 29 | - private image on every cold start rather than once at deploy time, | |
| 30 | - so this has to be Modal's to keep and cannot be the run's own | |
| 31 | - short-lived registry token. | |
| 24 | + secrets. The registry needs none of its own -- rickub authenticates | |
| 25 | + docker before a workflow's first step. | |
| 26 | +* The image set to **public** on rickub: its detail page, Manage, | |
| 27 | + visibility. Private is the default, and the first push creates it | |
| 28 | + private, so this is done once after the first green run. | |
| 32 | 29 | |
| 33 | -Making the image public instead -- its detail page, Manage, | |
| 34 | -visibility -- removes the need for that second one entirely, at the | |
| 35 | -price of anyone being able to pull the bundle. | |
| 30 | +The second is why there is no `registry_secret` in `container.toml`. | |
| 31 | +Modal pulls on every cold start rather than once at deploy time, so a | |
| 32 | +private image would want a long-lived rickub deploy token held as a | |
| 33 | +Modal Secret -- and what it would be guarding is `build/web`, which | |
| 34 | +the URL hands to anyone who opens it. The alternative is written down | |
| 35 | +in `container.toml` for whoever wants it. | |
| @@ -18,18 +18,18 @@ tested, and a deploy is a pull rather than a compile. The workflow is | |||
| 18 | it up, and deploying again replaces it in place because the app is | 18 | it up, and deploying again replaces it in place because the app is |
| 19 | named by `[container] name`. | 19 | named by `[container] name`. |
| 20 | 20 | ||
| 21 | -Two credentials live outside the repo, both one-time setup: | 21 | +One credential and one setting live outside the repo, both one-time: |
| 22 | 22 | ||
| 23 | * `MODAL_TOKEN_ID` / `MODAL_TOKEN_SECRET`, as rickub repository | 23 | * `MODAL_TOKEN_ID` / `MODAL_TOKEN_SECRET`, as rickub repository |
| 24 | - secrets. The registry needs no secret of its own -- rickub | 24 | + secrets. The registry needs none of its own -- rickub authenticates |
| 25 | - authenticates docker before a workflow's first step. | 25 | + docker before a workflow's first step. |
| 26 | -* A Modal Secret named `rickub-registry`, holding `REGISTRY_USERNAME` | 26 | +* The image set to **public** on rickub: its detail page, Manage, |
| 27 | - and `REGISTRY_PASSWORD` for a rickub deploy token (Settings → | 27 | + visibility. Private is the default, and the first push creates it |
| 28 | - Packages; pull-only, and the username is any label). Modal pulls the | 28 | + private, so this is done once after the first green run. |
| 29 | - private image on every cold start rather than once at deploy time, | ||
| 30 | - so this has to be Modal's to keep and cannot be the run's own | ||
| 31 | - short-lived registry token. | ||
| 32 | 29 | ||
| 33 | -Making the image public instead -- its detail page, Manage, | 30 | +The second is why there is no `registry_secret` in `container.toml`. |
| 34 | -visibility -- removes the need for that second one entirely, at the | 31 | +Modal pulls on every cold start rather than once at deploy time, so a |
| 35 | -price of anyone being able to pull the bundle. | 32 | +private image would want a long-lived rickub deploy token held as a |
| 33 | +Modal Secret -- and what it would be guarding is `build/web`, which | ||
| 34 | +the URL hands to anyone who opens it. The alternative is written down | ||
| 35 | +in `container.toml` for whoever wants it. | ||
modified
.modal/web/container.toml +14 -8 | @@ -6,14 +6,20 @@ description = "the web bundle CI built, served at a URL" | ||
| 6 | 6 | # spec is read, so the tag is whatever commit the deploy job is deploying. |
| 7 | 7 | # Unset, it fails loudly rather than deploying something stale. |
| 8 | 8 | registry = "${FRQ_WEB_IMAGE}" |
| 9 | -# Images on registry.rickub.com are private by default, so Modal needs | |
| 10 | -# credentials to pull -- and it pulls on every cold start, not once at deploy | |
| 11 | -# time, so the CI job's own registry token is no use: it is short-lived by | |
| 12 | -# design. A Modal Secret of this name holds REGISTRY_USERNAME and | |
| 13 | -# REGISTRY_PASSWORD for a rickub *deploy* token, which is pull-only by | |
| 14 | -# construction. The username is a label of your choosing; only the token is | |
| 15 | -# checked. | |
| 16 | -registry_secret = "rickub-registry" | |
| 9 | +# No registry_secret, which is a decision and not an omission. Images on | |
| 10 | +# registry.rickub.com are private by default and Modal pulls on every cold | |
| 11 | +# start -- not once at deploy time -- so a private image here would need a | |
| 12 | +# long-lived rickub deploy token kept as a Modal Secret, since the workflow's | |
| 13 | +# own registry token is short-lived by design. The image is made public | |
| 14 | +# instead. It holds `build/web` and a python to serve it, and that bundle is | |
| 15 | +# what the URL hands to anyone who opens it, so there is nothing in there to | |
| 16 | +# keep: a credential to rotate would be guarding a copy of the public site. | |
| 17 | +# | |
| 18 | +# To go the other way, set the image private on rickub and add: | |
| 19 | +# registry_secret = "rickub-registry" | |
| 20 | +# naming a Modal Secret with REGISTRY_USERNAME / REGISTRY_PASSWORD for a | |
| 21 | +# pull-only deploy token (rickub Settings -> Packages; the username is any | |
| 22 | +# label). | |
| 17 | 23 | # Not a Sandbox: a Sandbox is a run that ends, and this is meant to stay up |
| 18 | 24 | # between pushes. `web` is a Function that Modal fronts with a stable https |
| 19 | 25 | # URL and `modal deploy` leaves running. |
| @@ -6,14 +6,20 @@ description = "the web bundle CI built, served at a URL" | |||
| 6 | # spec is read, so the tag is whatever commit the deploy job is deploying. | 6 | # spec is read, so the tag is whatever commit the deploy job is deploying. |
| 7 | # Unset, it fails loudly rather than deploying something stale. | 7 | # Unset, it fails loudly rather than deploying something stale. |
| 8 | registry = "${FRQ_WEB_IMAGE}" | 8 | registry = "${FRQ_WEB_IMAGE}" |
| 9 | -# Images on registry.rickub.com are private by default, so Modal needs | 9 | +# No registry_secret, which is a decision and not an omission. Images on |
| 10 | -# credentials to pull -- and it pulls on every cold start, not once at deploy | 10 | +# registry.rickub.com are private by default and Modal pulls on every cold |
| 11 | -# time, so the CI job's own registry token is no use: it is short-lived by | 11 | +# start -- not once at deploy time -- so a private image here would need a |
| 12 | -# design. A Modal Secret of this name holds REGISTRY_USERNAME and | 12 | +# long-lived rickub deploy token kept as a Modal Secret, since the workflow's |
| 13 | -# REGISTRY_PASSWORD for a rickub *deploy* token, which is pull-only by | 13 | +# own registry token is short-lived by design. The image is made public |
| 14 | -# construction. The username is a label of your choosing; only the token is | 14 | +# instead. It holds `build/web` and a python to serve it, and that bundle is |
| 15 | -# checked. | 15 | +# what the URL hands to anyone who opens it, so there is nothing in there to |
| 16 | -registry_secret = "rickub-registry" | 16 | +# keep: a credential to rotate would be guarding a copy of the public site. |
| 17 | +# | ||
| 18 | +# To go the other way, set the image private on rickub and add: | ||
| 19 | +# registry_secret = "rickub-registry" | ||
| 20 | +# naming a Modal Secret with REGISTRY_USERNAME / REGISTRY_PASSWORD for a | ||
| 21 | +# pull-only deploy token (rickub Settings -> Packages; the username is any | ||
| 22 | +# label). | ||
| 17 | # Not a Sandbox: a Sandbox is a run that ends, and this is meant to stay up | 23 | # Not a Sandbox: a Sandbox is a run that ends, and this is meant to stay up |
| 18 | # between pushes. `web` is a Function that Modal fronts with a stable https | 24 | # between pushes. `web` is a Function that Modal fronts with a stable https |
| 19 | # URL and `modal deploy` leaves running. | 25 | # URL and `modal deploy` leaves running. |