Bash on Miren
Bash can't listen on a socket by itself, but it can write an HTTP response to standard
output — and that's all you need. This guide puts socat in front of a Bash script:
socat owns the socket, and runs the script for each connection.
Ask your AI coding agent to "set up this shell script on Miren" after installing the
Miren agent skills. It adds the Dockerfile.miren and the socket
front-end, and deploys — using this page as its reference.
Do you need a Dockerfile?
Yes. 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.
The script
The script prints a complete HTTP response — status line, headers, a blank line, then the body:
#!/usr/bin/env bash
printf 'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nHello from Bash on Miren!\n'
The socket front-end
The script doesn't bind a port — socat does. Miren injects PORT, and socat's
TCP-LISTEN binds all interfaces; fork runs the script once per connection:
web: socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:/app/hello.sh
This same socat pattern serves any program that writes an HTTP response to stdout —
see the COBOL guide for another example.
Miren's HTTP ingress terminates TLS and handles the public HTTP layer in front of your
app, so socat only needs to hand each accepted connection to your program — it isn't
exposed to raw internet traffic. The one practical limit is that fork spawns a process
per request, so this suits low-traffic endpoints and tooling rather than high-throughput
services.
The Dockerfile
Create Dockerfile.miren in your project root:
FROM debian:12-slim
RUN apt-get update -y && apt-get install -y bash socat && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY hello.sh .
RUN chmod +x hello.sh
EXPOSE 8080
.dockerignore
.git
Deploy
Create .miren/app.toml naming your app and deploy from your project root:
name = "bash-bench"
miren deploy
Even with a Dockerfile.miren, Miren needs at least one service defined — the web:
line above. Without it the deploy stops with no services defined.
Agent quick reference
- Detection: none — requires
Dockerfile.miren - Serving: the script prints a full HTTP response;
socatowns the socket - Service is required:
Procfileweb: socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:/app/hello.sh - Port:
socat TCP-LISTEN:$PORTbinds0.0.0.0 - Pattern: works for any executable that writes an HTTP response to stdout
Next steps
- COBOL on Miren — the same
socatpattern for a compiled program - Using Dockerfile.miren — how custom builds work
- Deployment — how deploys build and activate