Skip to content

Configuration

Tarsail reads tarsail.yml by default.

Use another config file with:

Terminal window
tarsail --config tarsail.production.yml deploy

The config file location defines the project root. Relative paths in the config are resolved from the directory containing the config file.

project: my-app
target:
name: prod
host: example.com
user: deploy
port: 22
path: /opt/my-app
compose:
file: compose.production.yaml
env_file:
source: .deploy/production.env
target: shared/.env
mode: 600
build:
steps:
- name: Build web assets
run: npm run build:web
deploy:
keep_releases: 5
files:
- source: apps/web/dist
target: files/web-dist
- source: deploy/nginx
target: files/nginx
secrets:
- source: .deploy/htpasswd
target: shared/auth/htpasswd
mode: 600
SectionRequiredPurpose
projectYesProject name used for bundle names, Compose project name, and metadata.
targetYesRemote Linux server and target path.
composeYesCompose file and optional env file.
buildNoLocal pre-bundle commands such as static asset builds.
deployNoRelease retention settings.
filesNoNon-secret release files copied into bundles.
secretsNoSecret files uploaded into remote shared/.

Unknown top-level keys are rejected.

Phase 0 also rejects reserved future sections such as targets, registry, registries, kubernetes, swarm, ci, plugins, nginx, caddy, tls, backups, and notifications.

Required string.

project: my-app

Allowed:

  • lowercase letters;
  • numbers;
  • hyphen;
  • underscore;
  • length from 1 to 64.

Pattern:

^[a-z0-9_-]{1,64}$

Tarsail uses this value for:

  • local Docker Compose project name;
  • remote Docker Compose project name;
  • bundle file names;
  • manifest metadata.

Required object.

target:
name: prod
host: example.com
user: deploy
port: 22
path: /opt/my-app

Required string.

Allowed:

  • lowercase letters;
  • numbers;
  • hyphen;
  • underscore;
  • length from 1 to 64.

Phase 0 supports one target, but the target still has a name so config files can remain clear.

Required string.

Allowed characters:

  • letters;
  • numbers;
  • dot;
  • hyphen.

Use a hostname or IPv4 address:

host: example.com
host: 192.0.2.10

Required string.

The SSH username.

Allowed pattern:

^[A-Za-z_][A-Za-z0-9_-]{0,63}$

Examples:

user: deploy
user: root

Prefer a dedicated deploy user when possible.

Optional integer.

Default:

port: 22

Allowed range: 1 to 65535.

Required absolute remote path.

Example:

path: /opt/my-app

The path must:

  • be absolute;
  • be clean;
  • not contain ..;
  • use simple path characters;
  • not be /;
  • not be a broad system directory.

Rejected broad paths:

/opt
/var
/usr
/home
/etc
/root
/tmp

Use a project-specific child path instead.

Required object.

compose:
file: compose.yaml

Required string.

Path to the Docker Compose file relative to the config root.

Rules:

  • must be relative;
  • must use forward slashes;
  • must not contain ..;
  • must not contain spaces or shell metacharacters;
  • must point to an existing file.

Examples:

compose:
file: compose.yaml
compose:
file: deploy/compose.production.yaml

Optional object.

compose:
file: compose.yaml
env_file:
source: .deploy/prod.env
target: shared/.env
mode: 600

This file is passed to remote Docker Compose with --env-file.

Fields:

FieldRequiredDefaultDescription
sourceNononeLocal file to upload before deployment.
targetNoshared/.envRemote path under the Tarsail target path.
modeNo600File mode applied after upload.

If source is omitted, Tarsail expects target to already exist on the server.

target must be under shared/.

Optional object.

build:
steps:
- name: Build web assets
run: npm run build:web

Use build.steps for local commands that must run before Tarsail creates the release bundle. Typical examples include Vite, Astro, Next static export, documentation, or other asset builds whose output is later copied through files.

During deploy, build steps run after local Compose discovery and before remote SSH checks, Compose image builds, and bundle creation. If a build step fails, Tarsail stops before uploading anything.

Fields:

FieldRequiredDefaultDescription
nameNostep <n>Human-readable label printed during deploy.
runYesnoneSingle-line local command to run through the operating system shell.
dirNoconfig rootWorking directory relative to the config root.

Rules:

  • run must be a single line;
  • dir must be a relative directory under the config root;
  • build steps receive TARSAIL_RELEASE_ID=<release-id>;
  • build steps run only during deploy, not during doctor;
  • generated file sources are checked before bundle creation.

Static web example:

build:
steps:
- name: Build web dist
run: npm run build:web
files:
- source: apps/web/dist
target: files/web-dist

Optional object.

deploy:
keep_releases: 3

Optional integer.

Default:

keep_releases: 3

Allowed range: 1 to 20.

This value is used by tarsail prune. It does not automatically prune during deploy.

Optional array.

files:
- source: deploy/nginx
target: files/nginx
- source: public/maintenance.html
target: files/maintenance.html

Use files for non-secret release-owned files. They are included in the release bundle and roll back with the release.

Fields:

FieldRequiredDescription
sourceYesLocal file or directory relative to the config root.
targetYesBundle target path under files/.

Rules:

  • source must exist before Tarsail creates the bundle;
  • source must be relative;
  • source must use forward slashes;
  • source must not contain ..;
  • symlink sources are rejected;
  • directories must not contain symlinks;
  • target must be under files/;
  • target must not use reserved names such as manifest.json, compose.yaml, or images.

If source is generated, add a build.steps entry that creates it before bundling.

Optional array.

secrets:
- source: .deploy/app.key
target: shared/secrets/app.key
mode: 600

Use secrets for explicit files copied to the remote shared/ directory.

Fields:

FieldRequiredDefaultDescription
sourceYesnoneLocal file relative to the config root.
targetYesnoneRemote path under shared/.
modeNo600File mode applied after upload.

Rules:

  • source must exist;
  • source must be relative;
  • target must be under shared/;
  • mode must be an octal permission such as 600 or 0644.

Secrets are not stored in release bundles.

Use forward slashes in config paths, even on Windows:

compose:
file: deploy/compose.production.yaml

Do not use backslashes:

compose:
file: deploy\compose.production.yaml

Tarsail rejects unsafe path components and common shell metacharacters in managed target paths.

During deploy, Tarsail sets:

TARSAIL_RELEASE_ID=<release-id>

It is supplied to local Compose commands during build and config discovery, and it is written to current/.tarsail.env for remote Compose.

Use it in image tags:

services:
web:
image: my-app-web:${TARSAIL_RELEASE_ID:-local}

The :-local fallback keeps ordinary local Compose commands usable.