# fcgi
[](https://hex.pm/packages/fcgi)
[](https://hexdocs.pm/fcgi/)
A FastCGI Responder server for Gleam, designed to sit behind a reverse proxy such as Caddy. Speaks the FastCGI Responder role over a Unix domain socket and exposes a `gleam/http`-shaped handler API.
## Installation
```sh
gleam add fcgi
```
## Usage with `gleam/http`
```gleam
import fcgi
import gleam/erlang/process
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
pub fn main() {
let assert Ok(_) =
fcgi.new(handle_request)
|> fcgi.listen_unix("/tmp/fcgi.sock")
|> fcgi.start
process.sleep_forever()
}
fn handle_request(
_request: Request(fcgi.BodyReader),
_ctx: fcgi.Context,
) -> Response(fcgi.ResponseData) {
response.new(200)
|> response.set_header("content-type", "text/plain; charset=utf-8")
|> response.set_body(fcgi.string("hello, joe!"))
}
```
## Usage with Wisp
A working Wisp adapter lives in [`examples/wisp_hello`](examples/wisp_hello). Copy
`examples/wisp_hello/src/wisp_fcgi.gleam` into your own project alongside the
`wisp` dependency, then wire it up:
```gleam
import fcgi
import gleam/erlang/process
import wisp
import wisp_fcgi
pub fn main() {
let secret_key_base = wisp.random_string(64)
let assert Ok(_) =
handle_request
|> wisp_fcgi.handler(secret_key_base)
|> fcgi.new
|> fcgi.listen_unix("/tmp/fcgi.sock")
|> fcgi.start
process.sleep_forever()
}
fn handle_request(_request: wisp.Request) -> wisp.Response {
wisp.ok()
|> wisp.string_body("hello, joe!")
}
```
The socket file is created when the server starts and removed on shutdown.
## Reverse-proxy with Caddy
```caddy
example.com {
reverse_proxy unix//tmp/fcgi.sock {
transport fastcgi {
env PATH_INFO {http.request.uri.path}
}
}
}
```
HTTP-shaped FastCGI parameters become a `gleam/http.Request`. Trusted CGI metadata (client address, auth, script name, etc.) is passed separately as `fcgi.Context`, with anything unrecognized in `extra`.