Skip to content

Deploy A Gleam HTTP App

This tutorial walks through the first successful deploy path for a supported Gleam HTTP app. Follow it once from start to finish before trying a more complex app.

By the end, you should have:

  • A verified local beamup command.
  • A browser BeamUp account created through GitHub and a beta access code.
  • A CLI login stored in your OS keychain.
  • A checked beamup.toml.
  • One deployed app at https://<app>.beamup.run.
  • A status check, recent logs, and a cockpit view for the running app.

Before starting, make sure you have:

  • The BeamUp dashboard URL from your invitation.
  • A one-time beta access code if this is your first registration.
  • A Gleam HTTP app that targets Erlang.
  • A health path such as /healthz that returns HTTP 2xx without exposing secrets or debug state.

The supported app must build with:

Terminal window
gleam export erlang-shipment

It must read PORT from the environment and bind HTTP traffic on 0.0.0.0:<PORT>.

Use one command for your OS.

macOS with Homebrew:

Terminal window
brew install beamup-run/tap/beamup

Linux glibc 2.39+:

Terminal window
curl -fsSL https://beamup.run/install.sh | sh

Windows PowerShell:

Terminal window
pwsh -NoProfile -Command "irm https://beamup.run/install.ps1 | iex"

The Linux shell installer writes to $HOME/.beamup/bin and prints the exact PATH line to add when needed. The Windows installer writes to %LOCALAPPDATA%\BeamUp\bin, updates only the current user’s PATH, and may require a new shell before beamup is visible.

Then verify:

Terminal window
beamup --version

See Install The BeamUp CLI for supported targets, the Windows PowerShell fallback, update commands, and the checksum trust boundary.

Open the dashboard URL from your invitation.

  1. Select Continue with GitHub.
  2. Complete GitHub sign-in in the hosted browser flow.
  3. Enter your one-time beta access code.
  4. Submit the form.
  5. Confirm that you land on the app dashboard.

The beta code is only for first registration. Returning browser logins use the same GitHub identity and do not require another code.

Do not paste the beta code into a shell command, URL, issue, chat, or log. It is single-use and should stay out of recorded terminal output.

After browser registration, authenticate the CLI:

Terminal window
beamup login
beamup whoami

beamup login starts a device-code flow. It prints a URL and user code, opens a browser when possible, exchanges the provider token for a BeamUp API token, and stores only the BeamUp token in the OS keychain.

For a headless terminal:

Terminal window
beamup login --no-browser

Leave the CLI running while you complete the browser step. If the device code expires or is denied, rerun beamup login.

If you see registration_required, finish browser registration first, then run beamup login again.

From the root of your Gleam app, run your normal checks:

Terminal window
gleam test
gleam export erlang-shipment

Start the exported app locally with a port:

Terminal window
PORT=8000 ./build/erlang-shipment/entrypoint.sh run

In another terminal, check the health path:

Terminal window
curl -i http://127.0.0.1:8000/healthz

The response should be HTTP 2xx. The health response should be simple and should not include secrets, request headers, env values, or internal debug state.

From the same app root:

Terminal window
beamup init

Open the generated beamup.toml and check the important fields:

app = "hello-gleam"
runtime = "erlang"
app_root = "."
start = ["./build/erlang-shipment/entrypoint.sh", "run"]
health = "/healthz"
[build]
target = "erlang"
env = "prod"
[deploy]
strategy = "blue_green"

Change app if needed before the first deploy. It must be a DNS-safe slug: lowercase letters, numbers, and single hyphens, starting and ending with a letter or number.

Do not put tokens, beta codes, env values, database URLs, or secrets in beamup.toml. Runtime configuration belongs in beamup env set or the dashboard env/secrets forms.

Run:

Terminal window
beamup deploy

Plain output should report:

  • The app slug or ID.
  • The deployment ID.
  • The compressed archive size.
  • The included file count.
  • The initial deployment state.
  • The command to fetch build logs for this deployment.

BeamUp creates an immutable deployment, builds the source, starts a candidate runtime, checks PORT binding and the configured health path, then moves the active pointer only after the candidate is healthy.

A failed build, startup failure, port failure, or health-check failure does not replace the current healthy active deployment.

Run:

Terminal window
beamup status

Or, from outside the project directory:

Terminal window
beamup --app hello-gleam status

When the deployment is active, the app URL is:

https://<app>.beamup.run

Open the URL in a browser or check it with curl:

Terminal window
curl -i https://<app>.beamup.run/

Fetch recent runtime logs once:

Terminal window
beamup --app hello-gleam logs --no-follow

Fetch build logs for the deployment:

Terminal window
beamup --app hello-gleam logs --build --deployment <deployment-id> --no-follow

Use the deployment ID printed by beamup deploy or shown by status and the dashboard.

BeamUp shows explicit truncation and retention boundaries. It does not present truncated logs as complete.

Open the dashboard URL from your invitation and select the deployed app.

Use the cockpit to inspect:

  • App URL and active deployment.
  • Latest deployment state.
  • Build logs.
  • Runtime logs.
  • Env var and secret key metadata.
  • Rollback targets.
  • Latest safe BEAM runtime snapshot.
  • Top mailbox queues.
  • Drain or shutdown state during replacement.

The cockpit is read-only for BEAM internals. It does not expose message contents, request bodies, process dictionaries, ETS contents, arbitrary stack traces, env values, secret values, remote shell access, or process-control actions.

After the deploy, record:

  • App shape and framework.
  • Whether this was a real, representative, or sample app.
  • Time from beamup login completion to live URL.
  • Time from beamup deploy to live URL.
  • Whether founder help was needed.
  • Any failure state and how you recovered.
  • Whether the cockpit changed your confidence after deploy.
  • Whether you would keep the cockpit open while developing or operating this app.
  • missing_gleam_toml: run from the Gleam project root or fix app_root.
  • unsupported_target: use an Erlang-targeted Gleam project.
  • invalid_config: fix the named beamup.toml field.
  • compile_failure: read build logs and rerun the Gleam build locally.
  • port_binding_failure: read PORT and bind on 0.0.0.0:<PORT>.
  • startup_failure: inspect runtime logs and fix the start command or app startup path.
  • health_check_failure: make the configured health path return HTTP 2xx.

For reference details, see Deploying Existing Gleam Apps, Logs And Debugging, and Runtime Cockpit.