Multiple servers
Run two Ferry servers on one Docker daemon, send commands to each, and move or remove a server.
More than one ferryd can share one Docker daemon. For example, run a staging server next to your production server on the same machine. Or run a temporary server for tests next to your real server. To test changes on one server with one account, an environment is simpler.
ferryd --data-dir /var/lib/ferry-staging \
--name-prefix staging \
--api-addr 127.0.0.1:7879 \
--proxy-addr 0.0.0.0:8081 \
--base-domain staging.localhostThis command starts a second server, staging. The production server keeps the defaults: the prefix ferry, the API on port 7878 and the proxy on port 8080.
Run a second server
Each server must have its own values for these options:
| What | Option | Why |
|---|---|---|
| data directory | --data-dir | It holds the database, the logs and the certificates of the server. The server that uses a data directory locks it. |
| name prefix | --name-prefix | Each Docker resource of the server has it. It must be unique for each Docker daemon. |
| API address | --api-addr | Two servers cannot listen on the same port. |
| Proxy addresses | --proxy-addr, --https-addr | The same cause. Only one server can own ports 80 and 443. |
| base domain | --base-domain | Then the apps of the two servers do not answer to the same hostnames. |
After the start:
- Account. Each server has its own account, sessions and API tokens, in its own data directory. At its first start, the staging server prints its own
Create your accountlink, at its own API address:http://127.0.0.1:7879/setup?code=…. - Apps. The apps of the staging server are at
http://<name>.staging.localhost:8081. - Stop, status, logs.
ferryd stop,ferryd statusandferryd logsact on the server of the data directory that you give.
ferryd stop --data-dir /var/lib/ferry-stagingThis command stops staging. Production continues to run.
On a public server, give the second server its own base domain, for example --base-domain staging.example.com. Put it on a different port or on another IP address.
Choose the server in the CLI
The CLI saves one server when you run ferry login. A command with no option goes to this server. A flag or an environment variable sends one command to another server:
FERRY_SERVER=http://127.0.0.1:7879 FERRY_TOKEN=$(cat /var/lib/ferry-staging/api_token) ferry ls
ferry --server http://127.0.0.1:7879 --token fy_… lsThe saved server does not change. The next command with no option goes to production again. A token works only on the server that it belongs to.
| You are | Token |
|---|---|
| On the machine of the server | The server token in its data directory. The first command above reads it. |
| On another machine | Create an API token under Server → Account in the dashboard of the staging server. |
ferry login --server http://127.0.0.1:7879 also works. But it replaces the saved server.
Give each server its own name prefix
The name prefix (default ferry) is part of each Docker name that a server creates:
| Resource | Name |
|---|---|
| Private networks | <prefix> for production, <prefix>-env-<environment> for the other environments |
| Service containers | <prefix>-<service>-<deploy>-<random> |
| Job containers | <prefix>-job-<service>-<job> |
| Datastore containers and volumes | <prefix>-ds-<name>, <prefix>-ds-<name>-data |
| Service disks | <prefix>-svc-<service id>-disk |
| Built images | <prefix>/<service>:<deploy id> |
| Ownership marker volume | <prefix>-owner |
Outside production, <service> and <name> also have the name of the environment: api.staging. Thus the same name in two environments gets two sets of Docker names.
Each container also has the label ferry.instance=<prefix>. A server lists and controls only the containers with its own prefix.
Two servers must never share a prefix. The reconciler of a server removes the containers under its prefix that it does not know. Each such container is an orphan. With the same prefix, each server deletes the apps of the other.
With different prefixes, the servers stay apart. They have different networks, thus their services cannot call each other by name. They also have different images and volumes.
The safety checks
At each start, ferryd makes sure that no other server uses its data directory or its prefix. If a check fails, ferryd does not start.
One server for each data directory. ferryd holds a lock on <data-dir>/ferryd.lock.
Error: another ferryd is already running with data directory /var/lib/ferryOne data directory for each prefix. At its first start, a server writes its identity and its data directory on the marker volume <prefix>-owner. Its identity is the file <data-dir>/instance_id. After that, a server with another data directory refuses the prefix.
Error: Docker resources with prefix 'ferry' belong to another Ferry server (data dir /var/lib/ferry). Run this server with a different --name-prefix, stop the other server, or pass --take-over to adopt the resources (the other server's containers will then be managed — and possibly removed — by this one).An empty data directory. The server refuses to start if its data directory is empty and no marker explains the containers under its prefix.
Error: found 3 Docker container(s) with prefix 'ferry' that this (empty) data dir /home/you/projects/ferry-data doesn't know. They probably belong to another Ferry server. Run this server with a different --name-prefix, …This check finds a common mistake: you start ferryd from another folder, with the default data directory ./ferry-data. Start it again with the correct --data-dir.
Move a server to another data directory
This procedure moves the data directory on the same machine.
- Stop
ferryd. - Move or copy the full directory. Keep its permissions: mode
0700, and the owner is the user that runsferryd. - Start
ferrydwith the new--data-dirand the same--name-prefix.
The file instance_id moves with the directory. Thus the server keeps its identity, and it still owns the prefix.
If the server refuses the prefix, the file instance_id did not move. For example, you restored only ferry.db. Then start the server one time with --take-over. The server replaces the marker with its own identity.
Never use --take-over for a second server
Do not use --take-over to start a second server on a prefix that another server uses. The new server removes the containers of the other server as orphans.
Remove a server
The volumes hold the datastores and the disks of the server. A removal deletes them. If you need this data, back it up first. See Back up the data.
Delete its services and datastores
Send these commands to the server that you remove. Delete each service with ferry delete NAME. Delete each datastore with ferry db rm NAME.
Stop the server
ferryd stop --data-dir /var/lib/ferry-stagingRemove what stays in Docker
These commands remove the containers, volumes, images and network of the prefix staging:
docker ps -aq --filter label=ferry.instance=staging | xargs docker rm -f
docker volume ls -q --filter label=ferry.instance=staging | xargs docker volume rm
docker image ls --filter reference='staging/*' --format '{{.Repository}}:{{.Tag}}' | xargs docker rmi
docker network rm stagingRemove the images by name, as above, not by image id. A server tags each image that it pulls under its own prefix: staging/web:dep-… for nginx:alpine, for example. A delete by id also deletes the original image and each other tag that shares it.