GetFlowingGetFlowing
Build

What every app needs to deploy

The port, the health check and its path, the start time, memory, build time and settings every app on GetFlowing is held to, however it is built.

GetFlowing runs every app as a container. It builds the container from a Dockerfile: your own, or one GetFlowing writes for the stack it finds. However it is built, the app has to do the same few things to deploy. The app contract has every number in one table.

The checklist

WhatWhat your app must do
ListenOn all interfaces (0.0.0.0, not localhost), on the port in the PORT variable, which is 8080
Answer its health checkAnswer GET /, or the path set in its Settings, with a status from 200 to 399 within 5 seconds
StartBe ready within 60 seconds of starting
Fit in memoryRun within 512 MB
BuildBuild its image within 20 minutes
ConfigurationRead settings and secrets from environment variables, never from a file in the repository

Listen on PORT

GetFlowing sets PORT to 8080 and sends your app's traffic and its health checks there. Read the port from PORT, and listen on 0.0.0.0 so requests from outside the container reach it. An app that listens on localhost or 127.0.0.1 cannot be reached, and its deploy fails.

// Node, with Express
app.listen(Number(process.env.PORT) || 8080, '0.0.0.0');
# Python, with gunicorn
gunicorn app:app --bind 0.0.0.0:$PORT

Do not set PORT to another number, in your Dockerfile or in your app's variables. Health checks always go to 8080, so an app listening anywhere else never becomes healthy.

The health check

While your app runs, GetFlowing asks it for GET / every 10 seconds, or for the path set in the app's Settings (below).

  • Any status from 200 to 399 is healthy, so a redirect counts. A 404 never does.
  • The answer has to arrive within 5 seconds.
  • A new container has 60 seconds to start before failed checks count against it.
  • It takes 2 healthy answers in a row to go live, and 3 failed ones in a row to be taken out of service.

A new version only takes traffic once it passes. If it never does, the deploy fails and the version that was running keeps serving your visitors.

Set the health check path

An app with nothing at /, such as an API, names a path it answers on instead.

  1. Open the app's Settings, under General, and find Health check.
  2. Type the path in Health check path, such as /health, and choose Save. Leave it empty for /.
  3. Deploy the app. The new path is asked from the app's next deploy.

The path starts with a single /, never //, and holds letters, digits and . _ ~ / - only. The statuses that count as healthy stay the same, so the path must answer with a status from 200 to 399.

Two things that trip apps up

  • An API with nothing at /. If GET / answers 404, the health check fails. Set a path it answers on, as above, or add a route at / that answers 200.
  • A framework that checks the host name. The health check asks your app by its own address, not by your domain. If your framework only answers host names it knows, as Django does with ALLOWED_HOSTS, make sure it still answers the health check. For a Django app GetFlowing builds without a Dockerfile, see Django.

Memory and start time

Your app runs with 512 MB of memory. An app that uses more is stopped and started again. Keep start-up work small too: a new container that is not answering within 60 seconds is replaced.

Configuration and secrets

Read every setting and secret from an environment variable. Set the values in GetFlowing, in the app's Settings, under Variables. See Variables and secrets.

  • Commit a .env.example with each variable's name and no value, so GetFlowing finds every variable your app reads.
  • Never commit .env or any file that holds a secret.
  • Never copy .env into the image in your Dockerfile.

Some frameworks cannot start without a secret only you can give, such as Laravel's APP_KEY. When GetFlowing builds an app without a Dockerfile, it asks for these before the deploy. See What an app cannot start without.

Run as a user other than root

Every Dockerfile GetFlowing writes runs the app as a user other than root. In a Dockerfile of your own, do the same: add a USER line after the install steps. See What to check.

What your app can reach

The app can reach anything over HTTPS and HTTP, and its own database, cache and mail servers on their usual ports. Port 25 is closed, so send mail through a mail provider.

Make it safe before you deploy

GetFlowing scans every app's code, secrets, packages, settings and image. By default what it finds is advice: the app still deploys, and the findings are on the app's Health tab for you to fix. An owner or admin can make findings block a deploy instead. See Security scans.

Before you deploy, it is worth doing the same checks yourself:

  • Audit your dependencies with your stack's audit tool, and upgrade any package with a high or critical vulnerability.
  • Commit your lockfile, so the versions you audited are the versions that are built.
  • Keep secrets out of the code, the repository and the image.
  • Build from a maintained base image with a pinned version, and run your app as a user other than root.
  • Leave debug modes, stack traces and admin consoles off.

GetFlowing does not build, host or run software meant to harm: malware, phishing or credential harvesting, tools that attack systems their user is not allowed to test, cryptocurrency mining, spam, or an app that hides what it does from the people using it.

On this page