Ferry

A self-hosted deploy tool for docker-compose projects

Put a compose project online with one command.

Ferry builds the project you already run with docker compose on one OVH server, serves it at its own subdomain with HTTPS, and keeps the previous version live when a deploy fails.

See a failed deploy
~/Projects/ferry-demo
  1. Upload
  2. Build
  3. Start
  4. Live

          
What ferry deploy printed when it put this page online, 28 Sep.

The compose file on your laptop is the deploy file.

Add one label to the service that answers the web, with its container port. Ferry reads everything else as it is.

  • Ports are Ferry's job. It ignores ports: and routes the labelled service through Caddy, so two projects can both use 8080.
  • Databases stay put. A service with a named volume keeps running while new versions of the other services replace the old ones.
  • Secrets stay off the upload. .env files never leave your machine. Set values with ferry env set; they are encrypted on the server and never shown again.
compose.yaml
services:
  web:
    build: ./web
    labels:
      ferry.http.port: "8080"
    depends_on: [api]
  api:
    build: ./api
    ports: ["8080:8080"]  ignored: Caddy routes web
  db:
    image: postgres:18-alpine
    volumes: [dbdata:/var/lib/postgresql]  kept across deploys
volumes:
  dbdata:
Two lines added, one ignored. Nothing else changes.

When a deploy fails, you learn what broke, and visitors see no change.

Ferry starts each new version beside the running one and moves traffic only when every service is healthy. A build that breaks, or a service that never gets healthy, leaves the previous deploy serving. Ferry's end-to-end tests check both cases on every build.

Simulation
  1. Upload
  2. Build
  3. Start
  4. Live
$ ferry deploy
Press "Deploy a broken build" to start deploy 9.
ferry-demo.ayokunlepaul.dev

Deploy 8

Serving every request

Requests answered
0
Errors
0

A backup counts once it has been restored.

“A successful backup only proves that Coolify created a file.”

Coolify's backup docs, read 2026-09-25

Every night at 02:00, Ferry dumps each Postgres database, encrypts it with your own key and keeps it for 7 days in OVH Object Storage. ferry db drill restores a backup into a throwaway container and counts the rows, so you know it works before you need it. A real restore saves the current database first.

    Simulation
    $ ferry db drill 2026-09-28

    Light enough to leave room for your projects.

    Ferry is one Go program, Caddy and PostgreSQL. Here is what they used together on Ferry's own server, set against what two other self-hosted tools ask for.

    Coolify asks for 2 GB
    Dokploy asks for, plus 30 GB of disk 2 GB
    Ferry used, measured 93 MB

    Coolify and Dokploy: their installation docs, read 2026-09-25. Ferry: ferryd 9 MB, Caddy 12 MB and PostgreSQL 72 MB, idle, on a 4-core, 8 GB OVH VPS, measured 2026-09-28. A requirement and a measurement are different things; read the gap as an order of magnitude.

    This page is a Ferry project.

    It was put online with ferry deploy: a web service that serves this page and an API service that answers the numbers beside it. They are live figures from the server in Beauharnois, Quebec, not an illustration.

    Status
    Asking the server
    Live since
    –
    Up for
    –
    Container
    –
    Round trip from you
    –

    Round trips are measured from your browser every few seconds.

    Straight answers

    Coolify and Dokploy already deploy compose files. Why Ferry?

    Ferry deploys the compose file you run locally without a separate copy for the server, and stays small: one Go program, Caddy and PostgreSQL. When something breaks, it names the service, the step and the deploy that is still serving, and its restore drills test that a backup can actually be restored.

    Is it one more thing to maintain?

    Ferry upgrades itself. Each change merged to its main branch is built, and the server installs it within 5 minutes. If the new version does not become ready, the previous one goes back and that build is never tried again.

    What if the server fails?

    Every project runs on one server, so it is a single point of failure. The nightly backups live off the server in OVH Object Storage, encrypted with a key you keep, and ferry db restore brings a database back in one command.

    Can I use it?

    Ferry is Ayokunle Paul's own deploy tool for his projects at ayokunlepaul.dev. It is not offered as a hosted service.