Configuration Reference
Complete reference for config.yaml (or config.json). Configuration is validated against a JSON schema: wrong types are rejected, and so is a key the tool does not know, so a misspelled ignore_tabel is reported instead of quietly doing nothing. Keys beginning with x or . are left to you, which keeps YAML anchor blocks such as .defaults: &defaults usable.
The configuration is executable input
A configuration file decides which machine this tool logs into, which binaries it runs there and which SQL it executes. Several keys are passed to a shell or a database by design:
| Key | Goes to |
|---|---|
script (before, after, error) | your local shell, as a command |
console.* | the endpoint, as the path of the binary to run |
additional_dump_options, use_rsync_options, files_options | the command line of the dump binary / rsync, as options |
post_sql, anonymize.*.value, where | the database, as SQL |
Treat a configuration file the way you treat a Makefile or a CI pipeline definition: review one before you run it, and give the repository that holds it the same protection as the code it syncs. Values are quoted so that a database password or a path cannot become a command, but a key documented as a command stays a command.
Root Keys
| Key | Type | Description |
|---|---|---|
type | enum | Framework: TYPO3, Symfony, Drupal, WordPress, Laravel. Optional if db credentials are given. |
origin | object | Source endpoint (see Client Object). |
target | object | Destination endpoint (see Client Object). |
ignore_table | array | Tables to exclude from the dump. A table* entry is expanded against the origin. |
truncate_tables | array | Tables to empty on the target before the import. A table* entry is expanded against the target. |
backup_before_import | boolean | Dump the target database before anything overwrites it (default: off). |
check_dump | boolean | Verify the dump was written to the end before importing it (default: on). |
additional_dump_options | string | Extra options for the dump binary. additional_mysqldump_options, the name the Python tool used, is still read. |
log_file | string | Path to a log file. |
json_log | boolean | Write the log file as JSON lines. |
check_for_updates | boolean | Check Packagist for a newer release at the start of each run (default: off). See CLI Reference. |
ssh_agent | boolean | Insist on the running SSH agent. A loaded agent is used on its own when an endpoint has no key and no password, see Authentication. |
use_sshpass | boolean | Hand rsync a password through sshpass. Set on its own when a password is in play and the binary is installed, so it rarely needs configuring. |
ssh_strict_host_key_checking | boolean | accept-new | SSH host-key verification (default: enabled). accept-new trusts an unknown host once, writes it to known_hosts, and verifies against it afterwards; see Authentication. |
files | array | File-transfer entries (see File Synchronization). |
Client Object
Both origin and target accept the same structure:
| Key | Type | Description |
|---|---|---|
name | string | Informative name for logging (e.g. Production). |
host | string | SSH host. Its presence makes the endpoint remote. |
user | string | SSH user. |
port | number | SSH port (default: 22). |
password | string | SSH password (prefer ssh_key or an agent). |
ssh_key | string | Path to an SSH private key. |
path | string | Path to the framework config file for credential detection. |
link | string | Reference to a host definition, e.g. @prod. |
dump_dir | string | Directory for temporary dump files (default: /tmp/). |
keep_dumps | number | Retention: keep only the N most recent dumps in dump_dir. |
after_dump | string | Additional SQL file to import after the main import. |
post_sql | array | SQL statements to execute after import, in one batch. |
protect | boolean | Refuse to use this endpoint as an import target without confirmation. |
console | object | Custom binary paths, keyed by the binary they replace (php, mysql, mysqldump, mariadb, mariadb-dump, psql, pg_dump). |
script | object | Lifecycle commands: before, after, error. They run on the machine driving the sync, not on the endpoint. scripts is accepted as well. |
db | object | Manual database credentials (see Database Object). |
jump_host | object | SSH jump host (see Jump Host Object). |
anonymize | object | Masking rules per table and column, target only (see Data Anonymization). |
Database Object
Under origin.db / target.db:
| Key | Type | Description |
|---|---|---|
name | string | Database name. |
host | string | Database host. |
user | string | Database user. |
password | string | Database password. |
port | number | Database port (default: 3306, PostgreSQL: 5432). |
ssl_disabled | boolean | Turn TLS off entirely for the MySQL connection. |
ssl_skip_verify | boolean | Keep TLS on but do not verify the server certificate. |
ssl_ca | string | Path to the CA certificate. |
ssl_capath | string | Directory of trusted CA certificates in PEM format. |
ssl_cert | string | Path to the client certificate. |
ssl_key | string | Path to the client key. |
ssl_cipher | string | Allowed cipher list. |
type | enum | Database system: mysql, mariadb, postgres (default: mysql). The MySQL and MariaDB binary names are detected on the endpoint, so this rarely needs setting for either. See PostgreSQL. |
The ssl_* keys configure a MySQL or MariaDB client and are written into the same temporary credential file as the password, so no path reaches the process list. A postgres endpoint that sets any of them aborts the run rather than connecting without them: psql takes its TLS settings from the environment instead.
Overriding single detected values
An endpoint that carries a path reads its credentials from the application's own configuration. Anything you also write under db wins over the detected value, field by field, so you can correct one of them and leave the rest auto-detected:
type: Symfony
origin:
host: prod.example.com
user: deploy
path: /var/www/html/shared/.env
db:
host: 127.0.0.1 # name, user, password and port still come from DATABASE_URLThe case this exists for is a containerised application: in a Docker Compose deployment DATABASE_URL names the compose service (postgres, db, mysql), which resolves inside the container network but not on the host that runs the dump. Published ports make the same database reachable on 127.0.0.1 there.
Three details:
- Detection still only runs when
db.nameis empty. Adbblock that names a database is treated as complete and nothing is read frompath. - The credential check sees the merged result, so a configured value also stands in for one the application's own configuration does not carry: a
DATABASE_URLwithout a password plusdb.passwordin the sync configuration is accepted. typeis not overridable this way. An unset type is indistinguishable from an explicitmysql, so the detected driver stays authoritative.
DDEV
DDEV 1.25 moved to a Trixie image whose MySQL server presents a self-signed certificate. ssl_skip_verify: true keeps the connection encrypted and only skips verification, which is the narrower fix than ssl_disabled: true.
Jump Host Object
Under origin.jump_host / target.jump_host:
| Key | Type | Description |
|---|---|---|
host | string | Jump host address. |
user | string | SSH user (defaults to the endpoint user). |
port | number | SSH port (defaults to the endpoint port). |
password | string | SSH password for the jump host. |
ssh_key | string | SSH private key for the jump host. |
Full Example
# Framework for credential detection (optional if db is given)
type: TYPO3
# Tables excluded from the dump (wildcards supported)
ignore_table:
- cache_*
- sys_log
# Optional logging
log_file: /var/log/php-sync-tool.log
json_log: false
origin:
name: Production
host: prod.example.com
user: deploy
port: 22
ssh_key: /home/user/.ssh/id_ed25519
path: /var/www/html/typo3conf/LocalConfiguration.php
dump_dir: /var/backups/db/
keep_dumps: 5
target:
name: Local
path: /var/www/local/typo3conf/LocalConfiguration.php
protect: false
post_sql:
- "UPDATE be_users SET password = '' WHERE 1;"
script:
before: php artisan down
after: php artisan upDump Files and Retention
Generated dumps are named sync-tool_<database>_<YYYY-MM-DD_HH-MM-SS>.sql.gz. Two things follow from that name:
keep_dumpsonly ever deletes dumps the tool wrote itself. Retention globs on thesync-tool_prefix, so other.sqland.gzfiles indump_dirare left alone. That matters because the defaultdump_diris/tmp/, which is rarely yours exclusively.- A dump written with
--dump-nameis yours, not ours. It carries no prefix and is therefore never pruned automatically. - Retention goes by modification time, not by the name, so a restored or re-transferred dump counts as recent.
The timestamp is precise to the second, so repeated runs within the same minute produce distinct files instead of overwriting each other.
A log file that log_file points at is created with owner-only permissions (0600), because it records the hosts, users, databases and commands of the run. An existing file keeps whatever permissions it has.
Common Configurations
Receiver Mode (Remote → Local)
type: TYPO3
origin:
host: prod.example.com
user: deploy
path: /var/www/html/typo3conf/LocalConfiguration.php
target:
path: /var/www/local/typo3conf/LocalConfiguration.phpSender Mode (Local → Remote)
type: TYPO3
origin:
path: /var/www/local/typo3conf/LocalConfiguration.php
target:
host: staging.example.com
user: deploy
path: /var/www/html/typo3conf/LocalConfiguration.phpManual Database Credentials
origin:
host: prod.example.com
user: deploy
db:
name: production_db
host: localhost
user: db_user
password: db_password
port: 3306
target:
db:
name: local_db
host: localhost
user: root
password: rootFile Formats
Configuration can be written in YAML or JSON:
type: TYPO3
origin:
host: prod.example.com
user: deploy
path: /var/www/html/LocalConfiguration.php
target:
path: /var/www/local/LocalConfiguration.php{
"type": "TYPO3",
"origin": {
"host": "prod.example.com",
"user": "deploy",
"path": "/var/www/html/LocalConfiguration.php"
},
"target": {
"path": "/var/www/local/LocalConfiguration.php"
}
}