Configuration
Tarsail reads tarsail.yml by default.
Use another config file with:
tarsail --config tarsail.production.yml deployThe config file location defines the project root. Relative paths in the config are resolved from the directory containing the config file.
Complete example
Section titled “Complete example”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: 600Supported top-level sections
Section titled “Supported top-level sections”| Section | Required | Purpose |
|---|---|---|
project | Yes | Project name used for bundle names, Compose project name, and metadata. |
target | Yes | Remote Linux server and target path. |
compose | Yes | Compose file and optional env file. |
build | No | Local pre-bundle commands such as static asset builds. |
deploy | No | Release retention settings. |
files | No | Non-secret release files copied into bundles. |
secrets | No | Secret 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.
project
Section titled “project”Required string.
project: my-appAllowed:
- lowercase letters;
- numbers;
- hyphen;
- underscore;
- length from
1to64.
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.
target
Section titled “target”Required object.
target: name: prod host: example.com user: deploy port: 22 path: /opt/my-apptarget.name
Section titled “target.name”Required string.
Allowed:
- lowercase letters;
- numbers;
- hyphen;
- underscore;
- length from
1to64.
Phase 0 supports one target, but the target still has a name so config files can remain clear.
target.host
Section titled “target.host”Required string.
Allowed characters:
- letters;
- numbers;
- dot;
- hyphen.
Use a hostname or IPv4 address:
host: example.comhost: 192.0.2.10target.user
Section titled “target.user”Required string.
The SSH username.
Allowed pattern:
^[A-Za-z_][A-Za-z0-9_-]{0,63}$Examples:
user: deployuser: rootPrefer a dedicated deploy user when possible.
target.port
Section titled “target.port”Optional integer.
Default:
port: 22Allowed range: 1 to 65535.
target.path
Section titled “target.path”Required absolute remote path.
Example:
path: /opt/my-appThe 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/tmpUse a project-specific child path instead.
compose
Section titled “compose”Required object.
compose: file: compose.yamlcompose.file
Section titled “compose.file”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.yamlcompose: file: deploy/compose.production.yamlcompose.env_file
Section titled “compose.env_file”Optional object.
compose: file: compose.yaml env_file: source: .deploy/prod.env target: shared/.env mode: 600This file is passed to remote Docker Compose with --env-file.
Fields:
| Field | Required | Default | Description |
|---|---|---|---|
source | No | none | Local file to upload before deployment. |
target | No | shared/.env | Remote path under the Tarsail target path. |
mode | No | 600 | File 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:webUse 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:
| Field | Required | Default | Description |
|---|---|---|---|
name | No | step <n> | Human-readable label printed during deploy. |
run | Yes | none | Single-line local command to run through the operating system shell. |
dir | No | config root | Working directory relative to the config root. |
Rules:
runmust be a single line;dirmust be a relative directory under the config root;- build steps receive
TARSAIL_RELEASE_ID=<release-id>; - build steps run only during
deploy, not duringdoctor; - 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-distdeploy
Section titled “deploy”Optional object.
deploy: keep_releases: 3deploy.keep_releases
Section titled “deploy.keep_releases”Optional integer.
Default:
keep_releases: 3Allowed 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.htmlUse files for non-secret release-owned files. They are included in the release bundle and roll back with the release.
Fields:
| Field | Required | Description |
|---|---|---|
source | Yes | Local file or directory relative to the config root. |
target | Yes | Bundle target path under files/. |
Rules:
sourcemust exist before Tarsail creates the bundle;sourcemust be relative;sourcemust use forward slashes;sourcemust not contain..;- symlink sources are rejected;
- directories must not contain symlinks;
targetmust be underfiles/;targetmust not use reserved names such asmanifest.json,compose.yaml, orimages.
If source is generated, add a build.steps entry that creates it before bundling.
secrets
Section titled “secrets”Optional array.
secrets: - source: .deploy/app.key target: shared/secrets/app.key mode: 600Use secrets for explicit files copied to the remote shared/ directory.
Fields:
| Field | Required | Default | Description |
|---|---|---|---|
source | Yes | none | Local file relative to the config root. |
target | Yes | none | Remote path under shared/. |
mode | No | 600 | File mode applied after upload. |
Rules:
sourcemust exist;sourcemust be relative;targetmust be undershared/;modemust be an octal permission such as600or0644.
Secrets are not stored in release bundles.
Path rules
Section titled “Path rules”Use forward slashes in config paths, even on Windows:
compose: file: deploy/compose.production.yamlDo not use backslashes:
compose: file: deploy\compose.production.yamlTarsail rejects unsafe path components and common shell metacharacters in managed target paths.
Environment variables supplied by Tarsail
Section titled “Environment variables supplied by Tarsail”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.