Skip to content

Quick start

This guide shows the shortest path from an existing Docker Compose project to a Tarsail deployment.

Use placeholders while learning. Do not commit real server addresses, private domains, credentials, or production .env contents to public repositories.

Local machine:

  • Docker;
  • Docker Compose v2;
  • ssh and scp when using key authentication;
  • Tarsail installed globally.

Remote server:

  • Linux;
  • SSH access;
  • Docker;
  • Docker Compose v2;
  • permission to run Docker commands;
  • a writable project path such as /opt/my-app.

PowerShell on Windows, macOS, or Linux:

Terminal window
irm https://tarsail.plystra.com/install.ps1 | iex

POSIX shell on Linux or macOS:

Terminal window
curl -fsSL https://tarsail.plystra.com/install.sh | sh

Verify:

Terminal window
tarsail version

For custom install directories and pinned release IDs, read Install and upgrade.

Every service must have an explicit image: value.

Good:

services:
web:
build:
context: .
dockerfile: Dockerfile
image: my-app-web:${TARSAIL_RELEASE_ID:-local}
ports:
- "80:8080"

Not supported:

services:
web:
build: .

Tarsail discovers image names from docker compose config, saves those images locally, uploads them, and loads them on the server. Without explicit image tags, the release cannot be bundled reliably.

From the root of your Compose project:

Terminal window
tarsail init

This creates tarsail.yml.

Edit it:

project: my-app
target:
name: prod
host: example.com
user: deploy
port: 22
path: /opt/my-app
compose:
file: compose.yaml
deploy:
keep_releases: 3

If the remote Compose app needs runtime variables, store the real file outside version control, for example:

.deploy/prod.env

Example contents:

APP_ENV=production
APP_BASE_URL=https://app.example.com
DATABASE_URL=postgres://user:[email protected]:5432/app
SESSION_SECRET=replace-with-a-long-random-value

Add it to tarsail.yml:

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

Tarsail uploads this file into <target.path>/shared/.env during deploy, then passes it to remote Docker Compose.

With the default SSH identity:

Terminal window
tarsail doctor

With a specific key:

Terminal window
tarsail --identity-file ~/.ssh/my-app-deploy-key doctor

With password authentication:

Terminal window
tarsail --ask-password doctor

Password mode prompts once for the remote user’s SSH password and reuses it for remote commands and uploads during that single Tarsail run.

Key authentication:

Terminal window
tarsail --identity-file ~/.ssh/my-app-deploy-key deploy

Password authentication:

Terminal window
tarsail --ask-password deploy

Tarsail prints each major step and then shows remote Compose status.

Terminal window
tarsail status
tarsail logs
tarsail logs web

Follow logs:

Terminal window
tarsail logs -f web

Limit log output:

Terminal window
tarsail logs --tail 100 web
Terminal window
tarsail rollback

Rollback reactivates the previous release’s Compose file and bundled images.

Rollback does not restore databases, Docker volumes, bind-mounted data, or external services.

Terminal window
tarsail prune

Non-interactive:

Terminal window
tarsail prune --yes

deploy.keep_releases controls how many releases should remain when pruning.

compose.yaml:

services:
web:
build: .
image: my-app-web:${TARSAIL_RELEASE_ID:-local}
environment:
APP_ENV: ${APP_ENV:-production}
APP_ADDR: ${APP_ADDR:-0.0.0.0:8080}
SESSION_SECRET: ${SESSION_SECRET}
ports:
- "80:8080"
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:8080/healthz"]
interval: 30s
timeout: 5s
retries: 3

tarsail.yml:

project: my-app
target:
name: prod
host: example.com
user: deploy
port: 22
path: /opt/my-app
compose:
file: compose.yaml
env_file:
source: .deploy/prod.env
target: shared/.env
mode: 600
deploy:
keep_releases: 5

Deploy:

Terminal window
tarsail --identity-file ~/.ssh/my-app-deploy-key deploy