FerryDocs
Guides

Variables and secrets

Set the variables of a service, keep secrets safe, share values and point a variable to a database.

Edit on GitHub

Each has its own . Your app reads its settings and its secrets from them. Ferry gives them to each when it starts.

Terminal
ferry env set api LOG_LEVEL=info

Set and remove variables

Terminal
ferry env set api LOG_LEVEL=info REGION=eu
ferry env unset api LOG_LEVEL
Output (last line)
Saved. Restarting 'api' with the new environment.

ferry env set and ferry env unset save the change, then the service. The restart applies the change.

  • Add --no-restart to save only.
  • Add --follow to see the log of the restart.

You can also give variables when you create a service: ferry create api -e KEY=VALUE or ferry up -e KEY=VALUE.

A key has 256 characters at most, with no = and no space. A value has 32 at most. All the variables of one service have 256 KiB at most.

See the variables

Terminal
ferry env api                  # the own variables of the service
ferry env api --effective      # with the variables of its env groups

The second command shows the . Ferry merges three layers, and a later layer wins:

  1. the variables that Ferry adds: PORT and FERRY_*
  2. the variables of the of the service, in the order of the links
  3. the own variables of the service

Thus an own variable replaces a variable with the same key from a group.

Keep secret values safe

Ferry has no special type for a secret. A password, a token or a key is an environment variable, the same as other settings.

  • The dashboard hides the values. Click Reveal to see them.
  • ferry env and the API show the values to each person who has a session or an .
  • For the password of a , use a reference. Do not copy the password.
  • To make a random secret, use openssl:
Terminal
ferry env set api "SESSION_SECRET=$(openssl rand -hex 32)"

A also gets the variables, as . A Dockerfile that Ferry makes keeps them out of the . In your own Dockerfile, mount the secret in the step that needs it:

Dockerfile
RUN --mount=type=secret,id=NPM_TOKEN,env=NPM_TOKEN npm ci

Do not put a secret in an ARG. Docker records the value of an ARG in the history of the image, and each person who has the image can read it.

Share variables with an env group

An env group is a set of variables with a name. Link it to each service that needs the same values.

Terminal
ferry env-group create shared LOG_LEVEL=info REGION=eu
ferry env-group link api shared
ferry restart api

The name of a group has 1 to 64 characters: letters, digits, -, _ or ..

CommandWhat restarts
ferry env-group link api sharedNothing. Run ferry restart api to apply it.
ferry env-group unlink api sharedNothing. Run ferry restart api to apply it.
ferry env-group set shared REGION=usEach linked live service, if its merged environment changed. Add --no-restart to prevent it.
ferry env-group unset shared REGIONThe same as set
ferry env-group show sharedNothing. It shows the variables and the linked services.
ferry env-group rm sharedNothing. Ferry deletes the group, but it refuses while a service has a link to the group.
ferry env-group rm shared --force --restartFerry also deletes a linked group, and it restarts the linked services.

In the dashboard, click Env groups in the icon rail.

Connect to a datastore or a service

A value can contain a . Ferry replaces it with the real value each time a container starts. Thus your app always gets the current address and password. A reference finds a datastore or a service of the of the service only. When two environments have a db, the reference of each service finds the db of its environment. The references of an env group follow the environment of each service that uses the group.

Terminal
ferry env set api 'DATABASE_URL=${{datastore.app-db.connectionString}}'

The containers of api then get DATABASE_URL=postgresql://app_db:<password>@app-db:5432/app_db.

Use single quotes around ${{…}}

Put a value that contains ${{…}} between single quotes. If not, your changes the text before ferry gets it.

A reference has three parts between ${{ and }}: the kind, the name and the property. The kind is datastore (or db) or service (or svc). The name is the name of the datastore or the service. The property is case-sensitive.

ReferenceValue in the container
${{datastore.NAME.connectionString}}The URL on the : postgresql://USER:PASSWORD@NAME:5432/DATABASE or redis://default:PASSWORD@NAME:6379
${{datastore.NAME.externalConnectionString}}The same URL with the port that the datastore publishes on the server
${{datastore.NAME.host}}The name of the datastore
${{datastore.NAME.port}}5432 for Postgres, 6379 for Redis
${{datastore.NAME.user}}The Postgres user, or default for Redis
${{datastore.NAME.password}}The password that Ferry made
${{datastore.NAME.database}}The name of the Postgres database. Redis has none.
${{service.NAME.host}}The name of the service on the private network
${{service.NAME.port}}The port where the service listens
${{service.NAME.hostport}}NAME:PORT, for example api:3000
${{service.NAME.internalUrl}}http://NAME:PORT
${{service.NAME.url}}The public URL. Only web services and static sites have one.

A value can have text around a reference, or many references:

Terminal
ferry env set web 'API_URL=${{service.api.internalUrl}}/v1'

To write a literal ${{ in a value, write $${{. The value $${{ name }} reaches the app as ${{ name }}.

When a change applies

Ferry freezes the environment of a when the deploy starts its containers. This is the . A replacement after a crash, a scale up, a resume and a job use the snapshot of the live deploy. Thus a saved change applies only at the next deploy or restart.

Terminal
ferry restart api --follow

A restart uses the live image again with the current variables. It does not build. The new instances must pass the before the old instances stop.

State of the serviceAfter ferry env set
LiveFerry restarts it ( env_change).
A deploy in progressThe restart waits behind that deploy. You do not lose the new values.
Never deployedNothing restarts. The first deploy uses the new values.
SuspendedNothing restarts. After ferry resume, run ferry restart NAME.

When a datastore or a target service changes, the containers that run keep the old values. Restart the service to get the new values.

If a reference does not resolve

The CLI checks the syntax before it saves. It also gives a warning for a name that does not exist:

Terminal
warning: X: reference to unknown datastore 'nope'; deploys fail until it resolves

At the deploy or the restart, Ferry resolves each reference. If one fails, the deploy fails with the status deploy_failed, and the previous deploy continues to answer. The deploy log gives the cause:

MessageCause
reference to unknown datastore 'x' or reference to unknown service 'x'No datastore or service has that name.
service 'x' has no known port (deploy it first)The target service has no live deploy and no port setting.
service 'x' has no public URLYou used url on a service that is not a web service or a static site.
datastore 'x' has no database nameYou used database on a Redis datastore.
datastore 'x' has no external port yetYou used externalConnectionString before the datastore has a published port.
datastore 'x' is not in environment 'staging' (it is in 'production')The target is in another environment. The deploy fails before the build, with the status build_failed. See Environments.

Fix the variable with ferry env set. The restart then uses the new value.

Ferry refuses to delete a datastore or a service that other services reference. The error lists the services and their variables. With --force, Ferry deletes it, and the services that reference it fail at their next deploy or restart.

On this page