Skip to content
Docs

The settings file, tanzahost.json

Every field of tanzahost.json - language, version, commands, system packages, folders to keep, the health address and PHP's settings - with examples.

Updated 17 Oct 20263 min read

Most apps need no settings file: we read your code and work out how to build and start it. When you want something else, add tanzahost.json to the top folder of your code. It's read on every build, and anything you set in the app's Build and run settings in the dashboard wins over it.

An example

Asha's Laravel shop pins PHP 8.4, adds two extensions, raises the upload size, and gets visitors only once /up answers:

json
{
  "language": "php",
  "version": "8.4",
  "health": "/up",
  "release": "php artisan migrate --force",
  "php": {
    "extensions": ["intl", "gd"],
    "ini": {
      "upload_max_filesize": "64M",
      "post_max_size": "64M"
    }
  }
}

Every field

FieldWhat it setsExample
languageThe language, when we shouldn't guess: php, nodejs, python, go, ruby, java, rust or static"nodejs"
versionAn exact version we offer"22"
rootThe folder inside your repository that holds the app"apps/api"
installThe install command, instead of ours"npm ci"
buildThe build command, instead of ours"npm run build:prod"
startHow the web process starts"npm run serve"
releaseThe command run before going live"python manage.py migrate"
healthThe path a new version must answer before it gets visitors"/up"
permanentFolders of your code kept between deploys["storage"]
packagesSystem packages to install, up to 30["ffmpeg"]
phpPHP's extensions and ini settingsSee below

The file must be valid JSON, at most 64 KB. A field we don't know is an error: the build stops and says which one, so a typo never goes unnoticed.

Language and version

The version must be one we offer, or the build stops and lists the ones we do. What we offer today: PHP 8.0 to 8.5, Node.js 22 and 24, Python 3.10 to 3.14, Go 1.26 and 1.27, Ruby 3.3, 3.4 and 4.0, Java 21 and 25, and Rust 1.98. Without a version, we use what your code asks for (like require.php in composer.json or .nvmrc for Node.js).

Commands

install, build and start replace ours; leave one out to keep ours. Each may be up to 4,000 characters. release must be on one line: join several commands with &&.

The web process must listen on the port in PORT, which is 8080:

json
{
  "start": "gunicorn shop.wsgi:application --bind 0.0.0.0:${PORT} --workers 2"
}

Permanent folders

Each deploy starts with fresh files from your code, which can't be changed while the app runs. The folders in permanent are kept instead: the first deploy fills them from your code, and later deploys keep what's there. Up to 10 folders, each a folder of your code like storage or public/uploads.

For Laravel, storage is permanent without asking, and bootstrap/cache is a small scratch folder made fresh at each start. Setting permanent replaces the list, so a Laravel app that adds a folder keeps storage in it:

json
{
  "permanent": ["storage", "public/uploads"]
}

Your app's home folder is kept too.

System packages

packages installs system packages by name before your build, like ffmpeg or imagemagick. Up to 30, with names of lowercase letters, digits and +.-.

PHP settings

php.extensions adds extensions from this list: bcmath, bz2, calendar, exif, gd, gmp, imagick, intl, mysqli, opcache, pcntl, pdo_mysql, pdo_pgsql, pgsql, redis, soap, sockets, xsl, zip. The common ones (mbstring, curl, openssl, pdo and others) are always there.

php.ini changes these settings, and no others:

SettingAllowed
upload_max_filesize, post_max_sizeA size up to 2G, like 64M
memory_limitA size up to your app's memory limit
max_execution_time, max_input_time0 to 600 seconds
max_input_vars0 to 100000
display_errors, opcache.enableOn or Off
date.timezoneA time zone, like Europe/London or UTC
session.gc_maxlifetimeUp to 2592000 seconds (30 days)

For an app that isn't PHP, the php field is ignored, and the build says so.

An app in a folder

With root, we read your app from that folder of the repository. A tanzahost.json inside that folder counts too, and wins over the one at the top.

json
{
  "root": "apps/api",
  "language": "nodejs"
}

Where each setting comes from

  1. What we find in your code.

  2. Then tanzahost.json.

  3. Then Build and run in the dashboard. An empty field there uses the file, or what we found.