Configuration
Shippy is configured by a single .shippy.yaml in your project root. shippy init generates one for you; this page explains every part of it. For a terse key-by-key table, see the Configuration Options reference.
Basic Structure
hosts:
<hostname>:
# SSH connection
hostname: <server domain or IP>
port: <SSH port, default: 22>
remote_user: <SSH username>
ssh_key: <path to SSH private key>
ssh_options: <map of SSH options, see below>
# Deployment
deploy_path: <absolute path on server>
rsync_src: <local source directory>
keep_releases: <number of releases to keep, default: 5>
# File management
shared: <list of shared paths>
include: <allowlist - paths to deploy (deny-by-default)>
exclude: <carve-outs that win over includes>
commands:
- name: <command description>
run: <command to execute>The key under hosts: is the name you pass on the command line — shippy deploy production uses the hosts.production entry.
Two parts of this file are large enough to have their own pages:
include:/exclude:— Shippy deploys an explicit allowlist and ships nothing you haven't listed. See File Selection.commands:/rollback_commands:— including per-host scoping and running inside a container. See Deployment Commands.
Which files get deployed
Nothing ships unless you list it under include:; exclude: then punches holes in that allowlist, and a built-in junk list is carved out on top. This is covered in full on File Selection, including the pattern syntax, the default excludes and how to migrate a configuration written for an older version.
hosts:
production:
include:
- "public/" # Web root (ships the whole subtree)
- "vendor/" # Composer dependencies
- "config/" # TYPO3 configuration
- "composer.json"
- "composer.lock"
exclude:
- "public/typo3temp/" # Carve-outs win over includesTemplate Variables
Use {{key.path}} syntax to reference values from composer.json:
hosts:
production:
deploy_path: /var/www/{{name}} # Uses composer.json "name" fieldAccess nested values:
deploy_path: /var/www/{{extra.typo3/cms.web-dir}}Provide a fallback value with | (used when the key is not found in composer.json):
commands:
- name: Clear cache
run: ./{{config.bin-dir|vendor/bin}}/typo3 cache:flushRun shippy config validate to see what these expand to before deploying.
Environment Variables
Use ${VAR} syntax to reference environment variables:
hosts:
production:
hostname: ${DEPLOY_HOST}
remote_user: ${DEPLOY_USER}Provide a fallback value with | (used when the variable is not set):
hosts:
production:
deploy_path: ${DEPLOY_PATH|/var/www/html}WARNING
If an environment variable is not set and no fallback is provided, deployment will fail with an error.
This is how you keep secrets and per-environment values out of the repository — see CI/CD.
Shared Files/Directories
Files and directories in the shared: list are symlinked from the shared/ directory to each release:
shared:
- .env # Shared file
- var/log/ # Shared directory (note trailing slash)
- public/fileadmin/
- public/uploads/Anything that must survive a deployment — user uploads, logs, sessions, the environment file — belongs here. Everything else is replaced wholesale with each release.
Deployment Locking
To prevent two deployments from running against the same host at once, Shippy writes a lock file to the remote deploy_path at the start of a deploy and removes it when finished. Locking is enabled by default with a 15-minute timeout, after which a stale lock (e.g. from a crashed deployment) is considered expired and automatically overridden.
# Global defaults (can be overridden per host)
lock_enabled: true # Enable deployment locking (default: true)
lock_timeout: 15 # Minutes before a stale lock expires (default: 15)
hosts:
production:
hostname: example.com
remote_user: deploy
deploy_path: /var/www/myproject
# lock_enabled: false # Per-host override to disable lockingIf a deployment fails and leaves a stale lock behind before the timeout elapses, clear it manually with shippy unlock.
Directory Structure
Shippy creates the following structure on the server (following Deployer/Capistrano conventions):
/var/www/myproject/
├── current -> releases/20240109120000 # Symlink to latest release
├── releases/
│ ├── 20240109120000/ # Current release
│ ├── 20240109110000/ # Previous release
│ └── 20240109100000/ # Older release
└── shared/
├── .env # Shared files
├── var/
│ ├── log/
│ └── session/
└── public/
├── fileadmin/
└── uploads/Point your web server's document root at current/public (or wherever your web directory sits inside the project). Because current is a symlink that Shippy swaps atomically, no request ever sees a half-written release.
keep_releases controls how many entries under releases/ are retained after a successful deploy — it defaults to 5, and those are exactly the releases you can roll back to.
Next steps
- File Selection — the allowlist that decides what ships
- Deployment Commands — command scoping and
command_context - SSH Connections — keys, agent, ports, timeouts and host key verification
- Example Configurations — complete minimal and advanced files
- Configuration Options — every key in one table