---
title: "Deploy to Railway, Alpine and musl support"
date: "2026-04-18"
---

## One-click deploy to Railway

Self-hosting Fabro on Railway no longer requires bespoke Dockerfile work. A new `railway.toml` and Railway deploy button ship with the project, along with a full guide covering volume setup at `/storage`, required environment variables, dev-token retrieval, and pointing your CLI at the deployed server.

The runtime container now binds `0.0.0.0:${PORT:-32276}`, so Railway, Fly, Render, and Cloud Run can route traffic without manual port configuration. Default behavior on local `docker run` and `docker-compose` is unchanged.

## Alpine and musl Linux support

The release pipeline now builds `x86_64-unknown-linux-musl` and `aarch64-unknown-linux-musl` tarballs alongside the glibc Linux targets. The `install.sh` script detects musl-based distributions via `ldd --version` and downloads the right archive automatically, so installs on Alpine and other musl hosts work out of the box.

The published Docker image switched to `alpine:3.22` on musl, dropping from ~287 MB to ~96 MB (66% smaller) with a reduced attack surface. The image and the `install.sh` tarball now ship the same binary.

## Production Docker compose with Caddy

A new `docker-compose.prod.yaml` stands up a Caddy 2 sidecar that handles auto-HTTPS on ports 80/443 and proxies to the Fabro service. Set `FABRO_DOMAIN` to your domain and Caddy provisions and renews the certificate; certs persist in a named volume. The base `docker-compose.yaml` has moved to the repo root.

## More

<Accordion title="Fixes">
- Fixed Gemini API keys being sent as URL query parameters; they now go through the `x-goog-api-key` header so they don't leak into access logs, proxies, or request traces
- Hardened the `fabro-demo` cookie with `HttpOnly` unconditionally and `Secure` when the web URL is HTTPS
- Fixed a path-traversal issue where authenticated users could send percent-encoded `..` segments in the GitHub repo lookup endpoint and redirect the server's privileged token to an unintended GitHub API path; owner and repo now require `[A-Za-z0-9._-]` with length caps
</Accordion>
