Every year a new language quietly wins over the developers who try it, and lately that language is Gleam (https://gleam.run). It's a small, friendly, statically-typed functional language that compiles to Erlang and runs on the BEAM — so you inherit decades of battle-tested concurrency and fault tolerance, with a type system and error messages that don't make you cry. Wisp (https://gleam.run/frameworks/) is its pragmatic web framework. Deploying a BEAM app used to mean learning rebar3 incantations; Gleam plus a container makes it genuinely simple. I run PandaStack; here's the path.
A tiny Wisp app
A minimal handler in src/app.gleam:
import gleam/erlang/process
import gleam/http/response.{type Response}
import mist
import wisp.{type Request}
import wisp/wisp_mist
pub fn handle_request(req: Request) -> Response(wisp.Body) {
case wisp.path_segments(req) {
[] -> wisp.html_response("<h1>Hello from Gleam on PandaStack</h1>", 200)
["health"] -> wisp.json_response("{\"ok\":true}", 200)
_ -> wisp.not_found()
}
}
pub fn main() {
wisp.configure_logger()
let secret = wisp.random_string(64)
let assert Ok(_) =
wisp_mist.handler(handle_request, secret)
|> mist.new
|> mist.port(8080)
|> mist.start_http
process.sleep_forever()
}Note the port 8080 — a host only needs your app to listen on a known port, and this one does. (Read the port from an env var if you want it configurable; Gleam has envoy and similar libraries for that.)
Step 1: Build a release
Gleam builds through its own tooling. Locally:
gleam deps download
gleam run # dev
gleam export erlang-shipment # produces a self-contained release in build/erlang-shipmentThe erlang-shipment export bundles your compiled app so it can run with just an Erlang runtime — no Gleam toolchain needed at runtime.
Step 2: Dockerfile
A two-stage build: compile with the Gleam image, run on a slim Erlang base.
FROM ghcr.io/gleam-lang/gleam:v1.6.0-erlang-alpine AS build
WORKDIR /app
COPY . .
RUN gleam deps download
RUN gleam export erlang-shipment
FROM erlang:27-alpine
WORKDIR /app
COPY --from=build /app/build/erlang-shipment ./
EXPOSE 8080
# the shipment includes an entrypoint script
CMD ["./entrypoint.sh", "run"]Pin the Gleam and Erlang versions to what your project targets — both move, and mismatches are the most common deploy failure here.
Step 3: Deploy on PandaStack
- 1Push to Git.
- 2https://dashboard.pandastack.io → New App → connect the repo. PandaStack detects the Dockerfile, builds it with rootless BuildKit, and deploys via Helm.
- 3Set any environment variables (secrets, config) in the encrypted env store.
- 4Expose port 8080. Add a custom domain under Domains — SSL is automatic.
- 5Every push redeploys.
CLI:
npm install -g @pandastack/cli
panda login
panda deployStep 4: Add a database
Gleam has Postgres libraries (like pog). Provision managed PostgreSQL on PandaStack (Databases → New Database → PostgreSQL), attach it to the app, and read DATABASE_URL from the environment. A quick connect:
import pog
import gleam/erlang/os
pub fn connect() {
let assert Ok(url) = os.get_env("DATABASE_URL")
// parse the URL and start a pog connection pool...
}The BEAM's process model makes connection pooling and concurrency feel natural — this is where running on Erlang pays off.
Step 5: Health checks and the BEAM's superpower
Point PandaStack's health check at /health. The nice thing about a BEAM app is that supervision trees keep parts of your app alive even when others crash — but the container-level health check is still your backstop: if the whole VM wedges, the platform restarts it. Belt and suspenders.
Honest tradeoffs
- Gleam's ecosystem is young. The language and stdlib are lovely, but you'll find fewer libraries than in Node or Python. Check that what you need exists before committing a production service.
- Versions move. Gleam and its libraries iterate quickly — pin everything and expect to bump versions deliberately.
- BEAM cold starts are reasonable but the runtime image isn't tiny; free-tier scale-to-zero adds some cold-start latency. Keep it warm on a paid tier for latency-sensitive endpoints.
- PandaStack is a newer platform too — great DX, growing ecosystem.
Wrap-up
Gleam gives you a type-safe, friendly language on the rock-solid BEAM; Wisp gives you a clean web framework; gleam export erlang-shipment plus a two-stage Dockerfile gives you a portable container. Deploy it on PandaStack with Git-push, managed Postgres, automatic SSL, and health checks. A delightful stack that actually ships.
Docs: https://docs.pandastack.io. Start free: https://dashboard.pandastack.io.