FerryDocs
Get started

Install Ferry

Install the Ferry server and CLI, create your account and connect the CLI to your server.

Edit on GitHub

Ferry is two programs: , the server, and ferry, the . On a fresh Ubuntu or Debian server, one command installs the two programs and starts the server.

Install with one command

Run this command on the server, as or with .

Terminal
curl -fsSL https://github.com/rogerbentcha/ferry/releases/latest/download/install.sh | sudo sh

The works on Ubuntu 22.04, 24.04 and 26.04, and on Debian 12 and 13, with an or an CPU. If you are root and the server has no sudo, end the command with | sh.

The script does all its checks before the first change. If a check fails, the server stays as it was. If the server has no or no git, the script installs them. Then it puts ferryd and ferry in /usr/local/bin, and creates the user ferry and a unit. systemd starts ferryd now and at each boot.

Output (end)
Create your account. On your computer:
  1. Open an SSH tunnel to this server (use the address you connect to):
       ssh -N -L 7878:127.0.0.1:7878 [email protected]
  2. Open this link in your browser:
       http://127.0.0.1:7878/setup?code=5b0e…

Do the two steps on your computer. The brings the to your machine. Then create your account.

Add your domain and HTTPS

Terminal
curl -fsSL https://github.com/rogerbentcha/ferry/releases/latest/download/install.sh | sudo sh -s -- --base-domain apps.example.com --acme-email [email protected]
OptionEffect
--base-domain apps.example.comThe : your apps are at <name>.apps.example.com, on port 80.
--acme-email [email protected]HTTPS on port 443, with certificates from . It needs a base domain.

Without options, your apps are at <name>.localhost:8080. The script writes the settings in /etc/ferry/ferryd.env. After a change in this file, run sudo systemctl restart ferryd. Before you use a domain, point its DNS to the server. See Domains and HTTPS.

Upgrade

Run the same command again. The script installs the latest release and restarts ferryd. It keeps /var/lib/ferry and /etc/ferry/ferryd.env. Thus your apps, your data and your settings stay.

For a server on the internet, do the Production checklist.

Install on another system

Ferry runs on Linux and macOS. On another system, install the two programs yourself.

What you need

ToolVersionUse
DockerEngine 27.3 or newer, or Runs your apps and the builds
gitA recent versionClones repositories for git deploys
Rust1.89 or newer (rustup)Builds ferryd and ferry. Only to build.
Node.js20.19 or newer, with Builds the dashboard. Only to build.

ferryd finds the through DOCKER_HOST, or through the file /var/run/docker.sock. The daemon must run on the same machine as ferryd. On macOS, Docker Desktop works with no change. Colima and OrbStack use another . Give its socket to ferryd before you start it:

Terminal
export DOCKER_HOST=$(docker context inspect --format '{{.Endpoints.docker.Host}}')

Download the programs

On Linux x86_64 or arm64, download the two programs from the latest release. You need no build tools.

Terminal
archive=ferry-$(uname -m)-unknown-linux-gnu.tar.gz
curl -fsSLO https://github.com/rogerbentcha/ferry/releases/latest/download/$archive
curl -fsSLO https://github.com/rogerbentcha/ferry/releases/latest/download/SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS
sudo tar -xzf $archive -C /usr/local/bin ferryd ferry

The first line selects the archive of your CPU: uname -m prints x86_64 or aarch64. If the checksum is not correct, do not install the archive. Download it again. The programs need 2.35 or newer: Ubuntu 22.04 or newer, Debian 12 or newer.

Build from source

On macOS, build the two programs from the source.

Terminal
git clone https://github.com/rogerbentcha/ferry
cd ferry
(cd web && npm ci && npm run build)
cargo build --release
sudo install -m 0755 target/release/ferryd target/release/ferry /usr/local/bin/

Build the dashboard first. The Rust build puts web/dist into ferryd. Then makes target/release/ferryd and target/release/ferry. The last command puts them on your .

Start the server

If you used the install script, systemd runs ferryd already. Go to Create your account.

On another install, run ferryd as a user that can use Docker.

Terminal
ferryd
Output
  Ferry 0.1.0 is running in the background (pid 48213)
  Dashboard + API : http://127.0.0.1:7878
  Dashboard (proxy): http://ferry.localhost:8080
  Apps            : http://<name>.localhost:8080
  Docker          : 29.2.0 (8 CPUs, 7.7 GiB)
  Data            : /home/you/ferry-data
  Limits          : 512 MiB / 1 CPU per container (default), 1024 pids, logs rotated at 10 MiB × 3
  Free disk check : deploys need 1 GiB free

  Create your account: http://127.0.0.1:7878/setup?code=5b0e…

  Logs            : ferryd logs -f
  Stop            : ferryd stop

The server continues to run after you close the terminal. To make sure that it answers, run curl http://127.0.0.1:7878/healthz. It prints ok.

If Docker does not run, or another program uses a port, ferryd prints the error. Then it stops with 1. See Troubleshooting.

Create your account

  1. Open the Create your account link in a browser.
  2. Enter your email and a password of 8 characters or more. The from the link is in the form already.
  3. Click Create account.

Ferry creates the account and signs this browser in to the dashboard. This is the only user of the server. Ferry has no teams and no roles.

If you lost the link, run ferryd status. It prints the link again. With the install script, run sudo ferryd status --data-dir /var/lib/ferry. If you forget the password, run ferryd reset-password on the server.

The account controls the full server

A person who signs in can deploy code and read each environment variable of the server. Do not open the API to the internet without HTTPS. See Security.

Set up the CLI

The ferry command sends each of your commands to the API of ferryd. It works on the server, on your laptop or in a job.

Install the CLI

The install script, the release archive and the build all give you ferry. It is one with no dependencies. To control Ferry from another machine, copy ferry to that machine, for example to /usr/local/bin.

Terminal
ferry --version

Log in

Terminal
ferry login --server http://127.0.0.1:7878
Output
To connect this terminal, open this page and sign in:

  http://127.0.0.1:7878/cli-login?id=d54ce0ee…

Approve the request there if it shows this code:  MRDB-M7EE
Waiting for the approval... (Ctrl-C to cancel)

The command opens the page in your browser. On a machine with no browser, add --no-browser and open the URL yourself. Sign in, and compare the code with the code in your terminal. Then click Approve.

Output
Logged in to http://127.0.0.1:7878 (Ferry 0.1.0)
Saved to /home/you/.config/ferry/config.json

The terminal now has its own . A request expires after 10 minutes. To test the connection at a later time, run ferry info.

Reach a remote server

ferryd listens on 127.0.0.1 only. On your laptop, open an SSH tunnel to the server. Then log in to the local address.

Terminal
ssh -N -L 7878:127.0.0.1:7878 you@your-server &
ferry login --server http://127.0.0.1:7878

Log in with a token

If no person can approve the login, give a token. Examples: a CI job, a script, a machine with no browser.

Terminal
ferry login --server http://127.0.0.1:7878 --token <token>
TokenWhere you get it
A named API tokenThe dashboard: Server → Account → API tokens. The dashboard shows it one time.
The The file <data-dir>/api_token on the server, for scripts on the server

A token starts with fy_ and can use the full API. Do not commit a token. Revoke each token that you do not use, in Server → Account.

Where the CLI finds the server

ferry login saves the server URL and the token in the ~/.config/ferry/config.json. Only your user can read it (mode 0600). The file keeps one login. A new ferry login replaces it.

Each command uses the first value that it finds:

  1. The flags --server and --token.
  2. The variables FERRY_SERVER and FERRY_TOKEN.
  3. The config file.
  4. The default server http://127.0.0.1:7878, with no token.

The saved token goes only to its own server. For another server, give its token too.

Use the CLI in CI

deploy.sh
export FERRY_SERVER=https://ferry.apps.example.com
export FERRY_TOKEN="$FERRY_API_TOKEN"   # from your CI secrets

ferry deploy api --follow   # exits with 1 if the deploy fails

Keep the token in the secrets of your CI, not in the script.

Output and exit codes

ItemWhat to know
OutputResults go to . Progress, warnings and errors go to .
--jsonPrints the exact answer of the API. A log gives one JSON object on each line.
--follow, -fShows the log until the deploy or the job stops. Ctrl+C stops the follow, not the deploy.
--yes, -yferry delete, db rm, env-group rm, deploy-hook rotate and domains disconnect ask a question first. In a script, they need --yes.
Exit codes0 success. 1 failure, or a failed deploy with --follow. 2 usage error. 130 Ctrl+C.
QuotesPut a value with a ${{…}} in single quotes. If not, your changes it.

The CLI reference has each command and each option.

Ports and URLs

WhatDefault addressFlag
API and dashboardhttp://127.0.0.1:7878--api-addr
Public HTTP , where your apps are0.0.0.0:8080--proxy-addr
Public HTTPS proxyoff--https-addr with --acme-email

With the defaults, your apps are at http://<name>.localhost:8080, and the dashboard is also at http://ferry.localhost:8080. Browsers send each *.localhost name to 127.0.0.1. Thus you set up no DNS on your machine.

The API documentation of your server is at http://127.0.0.1:7878/api/docs. Do not open the API to the public. Use an SSH tunnel.

The data directory

The has the full state of the server. Make a backup of it. The default is ./ferry-data, in the folder where you start ferryd. The install script uses /var/lib/ferry.

Terminal
ferryd --data-dir /var/lib/ferry

FERRY_DATA_DIR does the same. The data of a is in a Docker , not in this folder.

PathContents
ferry.dbThe database: services, deploys, variables, datastores, the account and its tokens
api_tokenThe server token (mode 0600)
setup_codeThe code that creates the account, while there is no account
ferryd.logThe output of a server in the background
logs/Deploy logs and job logs
certs/The TLS certificates

Run ferryd in the background

From a terminal, ferryd starts the server in the and gives the terminal back. From other places, it runs in the : systemd, a container, a pipe or a script. A needs ferryd run in its unit file.

CommandWhat it does
ferryd startStarts the server in the background. It takes the options of ferryd.
ferryd runRuns the server in the foreground, with its log in the terminal.
ferryd statusTells you if the server runs and where it listens. The exit code is 0 if it runs, and 3 if not.
ferryd logsPrints the last 100 lines of the server log. -f continues with the new lines.
ferryd stopStops the server.
ferryd reset-passwordReplaces the password of the account and signs each browser out.

stop, status, logs and reset-password find the server through its data directory. Run them in the folder where you started ferryd, or give the same --data-dir.

Terminal
# A server of the install script
sudo ferryd status --data-dir /var/lib/ferry

Under systemd, the log of ferryd goes to the journal. Read it with sudo journalctl -u ferryd -f.

Stop the server

Terminal
ferryd stop   # stop the server
ferryd        # start it again

For a server in the foreground, press Ctrl+C. Under systemd, run sudo systemctl stop ferryd.

When ferryd stops, your containers continue to run. But the proxy is a part of ferryd, thus the public URLs do not answer. At the next start, ferryd puts the routes back.

The stop is a . Open API requests get up to 10 seconds. The engine stops the jobs in progress and records the deploys in progress as interrupted. To stop immediately, run ferryd stop a second time.

On this page