Lua on Miren
Lua isn't auto-detected, so you deploy it with a Dockerfile.miren. This guide uses
lua-http — a proper Lua HTTP server —
installed with LuaRocks. (For a heavier stack, OpenResty (nginx + Lua) works too.)
Ask your AI coding agent to "set up this Lua app on Miren" after installing the
Miren agent skills. It adds the Dockerfile.miren, binds the server to
0.0.0.0:$PORT, and deploys — using this page as its reference.
Do you need a Dockerfile?
Yes. Miren doesn't auto-detect Lua, so add a Dockerfile.miren to your project root.
Miren builds from it instead of guessing the stack — see
Using Dockerfile.miren.
Miren auto-detects and builds common stacks (Python, Node, Bun, Go, Ruby, Rust) without a Dockerfile. This language isn't one of them yet — if you'd like first-class support, request it.
Bind to the injected port
Miren injects PORT and routes traffic to it, so read PORT and bind 0.0.0.0. With
lua-http:
local server = require "http.server"
local headers = require "http.headers"
local port = tonumber(os.getenv("PORT") or "8080")
local function on_stream(_, stream)
stream:get_headers()
local res = headers.new()
res:append(":status", "200")
res:append("content-type", "text/plain")
stream:write_headers(res, false)
stream:write_chunk("Hello from Lua on Miren!\n", true)
end
local s = assert(server.listen {
host = "0.0.0.0",
port = port,
onstream = on_stream,
})
assert(s:listen())
print("listening on 0.0.0.0:" .. port)
assert(s:loop())
The Dockerfile
Create Dockerfile.miren in your project root. LuaRocks builds lua-http and its C
dependencies (cqueues, luaossl), so the image needs a compiler and OpenSSL headers:
FROM debian:12-slim
RUN apt-get update -y \
&& apt-get install -y lua5.4 liblua5.4-dev luarocks gcc make m4 libssl-dev git \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN luarocks --lua-version=5.4 install http
COPY . /app
EXPOSE 8080
Debian's luarocks can target several Lua versions. Pass --lua-version=5.4 (matching
the lua5.4/liblua5.4-dev packages) so the rock and its C parts build against the
same interpreter you run with.
.dockerignore
.git
Set up the app
Even with a Dockerfile.miren, Miren needs at least one service defined — it
doesn't use the image's CMD as the start command. Add a Procfile:
web: lua5.4 /app/app.lua
Then create .miren/app.toml naming your app and deploy from your project root:
name = "lua-bench"
miren deploy
If no service is defined, the build succeeds but the deploy stops with
no services defined: please define at least one service in a Procfile or .miren/app.toml.
Environment variables
Set variables with miren env set — -e for plain values, -s for secrets (masked in
output and logs). Read them with os.getenv("KEY"):
miren env set -e LOG_LEVEL=info
miren env set -s API_TOKEN
See App Configuration — Environment Variables.
Agent quick reference
- Detection: none — requires
Dockerfile.miren - Library: lua-http via
luarocks --lua-version=5.4 install http(needsgcc make m4 libssl-dev) - Service is required: define a
Procfile(web: lua5.4 /app/app.lua) — the imageCMDis not used - Port:
os.getenv("PORT");server.listen { host = "0.0.0.0", port = port } - Env vars:
miren env set -e/-s; read withos.getenv - Heavier option: OpenResty (nginx + Lua) for a production Lua web stack
Next steps
- Using Dockerfile.miren — how custom builds work
- App Configuration — customize
.miren/app.toml - Deployment — how deploys build and activate