Quickstart¶
Use this guide to take a small HTTP app from a fresh GitHub repo to a Forge production app URL.
The example uses Node and a Dockerfile. The same deploy path works for any
language that follows the HTTP app contract: build from
a repo-root Dockerfile, listen on $PORT, and satisfy Forge runtime
readiness. The sample app also includes GET /health.
This guide is currently blocked before onboarding. No customer-supported signed
Aegis package is published, and aegis setup does not create the Map login state
required by map onboard. The current limitation is documented below; the
remaining steps are not a runnable customer path.
What you need¶
Before you start:
- an Apple Silicon Mac; no customer-supported signed Aegis package is published today, so this guide cannot be started from its install step;
- OpenAI Codex CLI (
codex) and Lima withlimactlon yourPATH; - Docker if you want to run the local container check before deploy;
- a GitHub repo you can push to;
- permission to install or request installation of the Forge GitHub App for that repo;
- the GitHub App installation ref for the customer account;
- tenant, account, and app/project refs when your account operator requires them.
Current limitation: Aegis writes account state under
~/.aegis/local/state/account/session.private.json. Map reads~/.config/mithran/login.jsonand requiresmap_control_endpointplus themap-controlaudience.map login saveneeds an endpoint and token thataegis setupdoes not provide, so no shipped bridge exists and the onboarding flow shown here is blocked.
If you administer the GitHub organization, tenant, or security review for the account, read Administer Forge and Security and Trust before granting repository access.
Use these values throughout the guide:
| Value | Replace with |
|---|---|
<owner/repo> |
Your GitHub repo, such as acme/forge-hello. |
<app_id> |
DNS-friendly app ID, usually the repo name. |
<app-ref> |
Served app ref for onboarding, route, version, and publish commands, usually app:<app_id>. |
<installation-ref> |
GitHub App installation ref for the customer account. |
For the shortest path, choose <app_id> as the repo name and use
<app-ref> as app:<app_id>. Onboarding accepts --app-ref for this value
and stores it in identity.project_ref because the manifest field has that
name. Use the same served app ref in map versions and map publish. If your
operator gives you different tenant, account, or app/project refs, use those
values consistently.
1. Install the CLI¶
No customer-supported signed Aegis package is published today. Dogfood
prerelease .pkg assets are not customer installs, so this quickstart cannot
proceed through the install step. See Install the CLI for the
current package status; the remaining steps are reference for the intended
Forge workflow.
2. Sign in and connect GitHub¶
From the local checkout whose origin points at <owner/repo>, run setup and
then prove the repo grant explicitly:
If the CLI gives you a GitHub setup link, use that link instead of going directly to GitHub's App page; the setup link ties the GitHub installation back to your Mithran setup profile. The repo-scoped grant check above proves whether the target repo is actually covered.
If GitHub requires an org owner, ask the owner to approve or install the App and grant the repo. See Connect GitHub.
3. Create the app files¶
From your local repo checkout, create a tiny HTTP app:
const http = require("http");
const port = Number(process.env.PORT || 8080);
http.createServer((req, res) => {
if (req.url === "/health") {
res.writeHead(200, { "content-type": "text/plain" });
res.end("ok");
return;
}
res.writeHead(200, { "content-type": "text/html" });
res.end("<h1>Hello from Forge</h1>");
}).listen(port, "0.0.0.0");
FROM node:22-alpine
WORKDIR /app
COPY package.json ./
COPY server.js ./
ENV PORT=8080
CMD ["npm", "start"]
4. Add mithran.yaml¶
Create mithran.yaml at the repo root:
apiVersion: map.mithran/v1
kind: MithranApp
metadata:
app_id: <app_id>
name: Forge Hello
identity:
project_ref: <app-ref>
capabilities:
- kind: http
route: /
runtime: nodejs22
startup:
command: npm start
public_edge:
type: platform
exposure: protected
app_env:
preview:
branch_pattern: "^refs/heads/main$"
image_tag: preview
production:
branch_pattern: "^refs/(heads/release/.*|tags/release/.*)$"
image_tag: prod
Replace <app_id> with a short DNS-friendly label and <app-ref> with the
served app ref you will use for onboarding, versions, and publishing, usually
app:<app_id>. The clean public URL uses the app ref label after you publish:
For the full manifest field list, see
mithran.yaml reference.
5. Check the app locally¶
Build and run the same container shape Forge will build:
In another terminal:
Expected result:
/healthreturns HTTP 200;/returnsHello from Forge;- the container keeps running until you stop it.
If this fails locally, fix it before deploying. Forge checks the same app contract at runtime.
6. Commit the app¶
Commit the app files locally:
The GitHub repo must already exist and be granted to the Forge GitHub App shown
by the customer setup link. If the remote repo does not exist yet, create it in
GitHub first, then add it as origin with the URL GitHub provides.
Confirm the local checkout points at the repo and set the local branch name before onboarding or pushing deploy refs:
7. Onboard the repo¶
The onboarding command below is blocked after aegis setup because no shipped
step creates the Map login state it requires. See the current limitation above.
Run onboarding from the same checkout. If <app-ref> is app:<repo-name>,
you can omit --app-ref because that is the CLI default:
Onboarding registers the repo with Forge and leaves your existing
mithran.yaml in place. Run it before pushing deploy refs so the webhook can
resolve the repo registration when the push arrives. The quickstart uses built-in
GitHub App webhooks, so no repo workflow is required.
Expected text output is shaped like this:
onboarded <owner/repo> (repo registration recorded).
app identity: <app-ref> (stored as identity.project_ref; used for deploy routing, versions, and publish).
next: commit + push mithran.yaml, then push a release/* ref (or tag) — the webhook deploys (no repo workflow needed).
If onboarding wrote a starter manifest, the output also includes
wrote ./mithran.yaml. This quickstart already created mithran.yaml, so the
CLI should not overwrite it.
If your operator gave you tenant, account, or app/project refs, pass them now. Use the served app ref that should own the app's route, versions, publish pointer, and access context:
map onboard \
--installation-ref <installation-ref> \
--tenant-ref <tenant-ref> \
--account-ref <account-ref> \
--app-ref <app-ref> \
<owner/repo> \
--repo-dir .
Confirm the registration:
map doctor --app adds route and recent-deploy diagnostics when those records
exist. It does not list the full onboarding record directly, so keep the
map onboard output with the app's repo registration record.
For onboarding details and custom-CI options, see Onboard a repo.
8. Push preview¶
Push main to start the built-in preview deploy:
Forge receives the GitHub App webhook for refs/heads/main, verifies the
installation and repo grant, snapshots the source, and targets the preview
app environment.
Webhook deploys do not print a deployment ref in your terminal. After the deploy starts, use the route view to discover the recorded deployment refs for the app:
If internal versions is still empty, wait a few seconds and run the command
again. Copy a deployment ref from internal versions or from the preview alias,
then inspect it:
9. Deploy a release¶
Create and push a release branch:
That push sends another GitHub App webhook to Forge. The built-in webhook
policy maps refs/heads/release/* to the production app environment. Forge
checks the repo registration, snapshots source, reviews the manifest and
source snapshot, builds the image, starts the runtime, programs the route, and
records deploy evidence.
List versions again and copy the release deployment ref from the production alias or internal versions section:
Use status and evidence to inspect that release deploy:
See Deploy status and evidence for the field list and evidence model.
10. Publish the clean public URL¶
List the versions for your app:
Copy the version label that points at the reviewed release deployment ref, then publish that version:
sha=$(git rev-parse HEAD)
map publish <app-ref> --version <version-from-output> --expected-sha "$sha"
--expected-sha tells Forge to move the clean public URL only if the selected
version still records the source SHA you reviewed.
Check the published hostname:
The quickstart manifest uses public_edge.exposure: protected, so anonymous
curl should reach the Forge auth boundary rather than the app body. Open the
same URL in a signed-in browser session to reach the Hello from Forge page.
Success checkpoints¶
Use these checkpoints before moving on. They keep source access, deploy state, publishing, and app behavior separate.
| Step | Continue when | If it does not match |
|---|---|---|
| GitHub grant | aegis github status --project-repo <owner/repo> --require --json exits successfully for the target repo. |
Finish the GitHub App grant through the customer setup link, then run the same command again. |
| Local app | / and /health return HTTP 200 from the local container. |
Fix the Dockerfile, startup command, $PORT binding, or app readiness behavior before deploy. |
| Onboarding | map onboard prints that the repo was onboarded and records the repo registration. |
Re-check the installation ref, repo grant, tenant/account/project refs, and map onboard output. |
| Preview deploy | map versions <app-ref> shows a preview alias or internal version with a deployment ref, and map --json status <deployment-ref> shows deployment.status.status: Succeeded. |
Use map --json evidence <deployment-ref> and the failed status field to decide whether the fix is source, manifest, build, runtime, or route. |
| Release deploy | map versions <app-ref> shows a production alias or internal version for the release branch deployment, and map --json status <deployment-ref> shows deployment.status.status: Succeeded. |
Confirm the pushed ref is refs/heads/release/*, the repo is still granted and onboarded, and the deploy status identifies the failed stage. |
| Publish | map publish prints published https://..., and map versions <app-ref> shows a published line for the same deployment ref. |
Re-run map versions, choose a reviewed internal version that reached Succeeded or Promoted, and use --expected-sha for the commit you reviewed. |
| Public URL | The published hostname no longer returns unknown_hostname; anonymous curl is denied before the app runtime, and a signed-in browser can reach the app. |
Confirm the published record, app ref, app hostname, deployed metadata.app_id, exposure, and route status. |
What happened¶
flowchart LR
A[map onboard] --> B[Repo registration]
B --> C[git push main or release/v1]
C --> D[GitHub App webhook]
D --> F[Forge control plane]
F --> G[Snapshot source]
G --> H[Review manifest and source snapshot]
H --> I[Build image]
I --> J[Start runtime]
J --> K[Program route]
K --> L[Record version and evidence]
L --> M[map publish]
M --> N[Clean public URL]
No Forge deploy secret is stored in your repo. Built-in deploys are authorized
through the Forge GitHub App grant, the active connector for the installation,
and the repo onboarding record. Publishing is a separate step that pins the
clean public URL to one reviewed version that reached Succeeded or
Promoted. More on the model: How Forge works.
If something fails¶
| Symptom | Start here |
|---|---|
| Setup or GitHub install does not complete. | Connect GitHub and Troubleshooting. |
map onboard returns an API error. |
Confirm the repo slug, installation ref, setup context, app ref, and GitHub App grant, then see Onboard a repo. |
| No deploy starts after the release push. | Webhook deploy does not start. |
| Build fails. | Build fails. |
| Runtime never becomes ready. | Runtime readiness fails / the app won't come up. |
The public URL returns unknown_hostname. |
Route propagation. |
| The URL still shows an older version. | Versions and publishing. |
Next¶
- Adapt your real service using the HTTP app contract.
- Review the
mithran.yamlreference. - Learn how versions and publishing move the clean public URL.
- Review App access and sharing before changing exposure.
- Use the Production checklist before the first customer-visible release.
- Share Administer Forge with the person who manages GitHub App access and tenant/account rollout.