Skip to main content

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.

Let your agent do this

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.

Want native support?

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.

Behind Miren's ingress

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
The Procfile is required

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; socat owns the socket
  • Service is required: Procfile web: socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:/app/hello.sh
  • Port: socat TCP-LISTEN:$PORT binds 0.0.0.0
  • Pattern: works for any executable that writes an HTTP response to stdout

Next steps