PHPackages                             wineworlds/deployer-recipes - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [DevOps &amp; Deployment](/categories/devops)
4. /
5. wineworlds/deployer-recipes

ActiveDeployer-recipes[DevOps &amp; Deployment](/categories/devops)

wineworlds/deployer-recipes
===========================

A collection of recipes for deployer

1.3.2(1mo ago)02.7k↓71.4%MITPHP

Since Apr 13Pushed 1mo ago3 watchersCompare

[ Source](https://github.com/wineworlds/deployer-recipes)[ Packagist](https://packagist.org/packages/wineworlds/deployer-recipes)[ RSS](/packages/wineworlds-deployer-recipes/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (2)Versions (17)Used By (0)

Deployer Recipes for TYPO3 and Shopware
=======================================

[](#deployer-recipes-for-typo3-and-shopware)

A collection of recipes for [Deployer](https://deployer.org/) — with a full, production-tested toolkit for **Shopware 6**: deploy, one-time provisioning, publishing a local instance, moving a shop between servers, and selective data migration (relaunch).

Install
-------

[](#install)

```
composer require --dev deployer/deployer
composer require --dev wineworlds/deployer-recipes
```

Import a recipe in your `deploy.yaml` (see below). Then run tasks with `vendor/bin/dep  `.

Recipes
-------

[](#recipes)

RecipeImport pathWhat you get**Shopware**`recipe/shopware.php``deploy`, `sw:shared:init`, `sw:publish`, `sw:transfer`, `migrate:*`, `fetch`TYPO3 (rsync)`recipe/typo3-rsync.php`Legacy TYPO3 deploy + fetch/sync/transferShopware (rsync, legacy)`recipe/shopware-rsync.php`Older git+build+rsync Shopware deploygeneric`recipe/fetch.php`, `recipe/sync.php`, `recipe/transfer.php`Bare DB/file primitives---

Shopware
========

[](#shopware)

Mental model
------------

[](#mental-model)

There are three places, and it helps to keep them apart:

```
  LOCAL (control machine)              SERVER (per host)
  ─ runs `vendor/bin/dep`              ─ {{deploy_path}}/releases/…   (each deploy)
  ─ .env.local     → local dev DB      ─ {{deploy_path}}/current       (symlink → newest release)
  ─ .env.   → target templates  ─ {{deploy_path}}/shared        (persists across releases)
  ─ bin/migrate.tables (whitelist)         └─ shared/.env.local  = the REAL secrets
                                            └─ shared/files, public/media, …  = media

```

**The env files** (this is the part people trip over):

FileWherePurpose`.env`committed, shipped in every releasebase / dev defaults only — **no real secrets**`.env.local`local only, git-ignoredyour **local dev** DB/secrets (used by `sw_local_db`)`.env.`local only, **git-ignored**template for a target host → uploaded once as its `shared/.env.local``shared/.env.local`on the server, in `shared/`the host's **real** secrets, symlinked into every releaseThe recipe reads real credentials from `.env.local` (server: the shared one; local: your dev one) — never from the committed `.env`.

> **Prerequisites:** a `shopware/production`-style project with `shopware/deployment-helper` installed (`composer require shopware/deployment-helper`); the deploy runs `vendor/bin/shopware-deployment-helper run` on the target.

Configure `deploy.yaml`
-----------------------

[](#configure-deployyaml)

Minimal, annotated — this is all you need for `deploy`, `sw:shared:init`, `sw:publish` and `migrate:*`:

```
import:
  - vendor/wineworlds/deployer-recipes/recipe/shopware.php

config:
  # chmod avoids needing ACL/sudo on shared hosting (recommended):
  writable_mode: chmod

  # ONLY needed for `sw:transfer` — the alias of the OLD/source server:
  # sync_from_host: old

hosts:
  prod:
    hostname:    server.example.de
    remote_user: deployer
    deploy_path: /var/www/prod        # releases/, current, shared/ live here
    bin/php:     /usr/bin/php83        # PHP binary on the server (for bin/console)
    keep_releases: 3                  # optional (Deployer default: 10)
    # optional — clears opcache after the symlink:
    # cachetool: /run/php/php83-fpm.sock

after:
  deploy:failed: deploy:unlock
```

Add more hosts as needed — each host `` maps to a local template `.env.` (see `sw_env_template` to change the naming).

### Host keys that matter

[](#host-keys-that-matter)

KeyRequiredMeaning`hostname` / `remote_user`yesSSH target (also honors `port:` and your `~/.ssh/config`)`deploy_path`yesbase dir on the server (holds `releases/`, `current`, `shared/`)`bin/php`recommendedPHP CLI on the server used for `bin/console``keep_releases`nohow many releases to keep`cachetool`nophp-fpm socket/URL → opcache is cleared after each deploy### Local files you must keep (git-ignored)

[](#local-files-you-must-keep-git-ignored)

```
# .gitignore
.env.local          # your local dev secrets
.env.*              # per-host templates (.env.prod, .env.old, …) — REAL secrets!
```

Create a host template by copying `.env` and filling in the **real** values for that server (`DATABASE_URL`, `APP_URL`, `APP_SECRET`, `MAILER_DSN`, `APP_ENV=prod`, …):

```
cp .env .env.prod   # then edit .env.prod
```

---

Commands
--------

[](#commands)

### `deploy` — release a new version

[](#deploy--release-a-new-version)

```
vendor/bin/dep deploy prod
```

Pipeline: `deploy:prepare` → `deploy:clear_paths` → `sw:deployment:helper`(migrations, plugins, theme, cache via the deployment-helper) → `sw:touch_install_lock` → `sw:health_checks` → `deploy:publish`.

- **Needs:** `sw:shared:init` must have run once before the first deploy (so `shared/.env.local` and the shared dirs exist).
- **Headless (no storefront):** set `sw_health_check: false` in `config:` — the `system:check --context=pre_rollout` step only makes sense with a storefront.

### `sw:shared:init` — one-time provisioning (run once per host)

[](#swsharedinit--one-time-provisioning-run-once-per-host)

```
vendor/bin/dep sw:shared:init prod
```

Creates `shared/` + all shared dirs, uploads `.env.prod` → `shared/.env.local`, uploads config files (`auth.json`, `public/.htaccess`, `public/.user.ini`) and your local media, and fixes group permissions. **Idempotent** — existing env/config on the host is never overwritten.

- **Needs:** local `.env.prod` (the host template). Errors clearly if missing.
- Sub-tasks if you want the pieces: `sw:shared:skeleton` (no media) and `sw:shared:media:upload`.

### `sw:publish` — bring a locally developed instance online

[](#swpublish--bring-a-locally-developed-instance-online)

```
vendor/bin/dep sw:publish prod            # aborts if the target is locked/exists
vendor/bin/dep sw:publish prod --force    # ignore lock + skip confirmations
```

Does it all in one go: `sw:target:guard` → `sw:shared:init` → `sw:db:publish`(your **complete local DB** → the target DB) → `deploy` → `sw:target:lock`.

- **Needs:** local `.env.prod`, local `.env.local` (your dev DB), and `shopware/deployment-helper`.
- **Protection:** a lock file (`{{deploy_path}}/.sw-publish.lock`) marks a published instance. A second `sw:publish` aborts unless `--force`. If the target already has a `current/` without a lock, it asks for confirmation.
- `sw:db:publish prod` is also callable on its own (overwrites the target DB).

### `sw:transfer` — move a shop to another server

[](#swtransfer--move-a-shop-to-another-server)

```
# in config: sync_from_host: old
cp .env .env.newserver                     # fill in the new server's values
vendor/bin/dep sw:transfer newserver --force
```

Migrates an existing shop **source → target**: shared media **and** the complete DB are copied from `sync_from_host` to the selected host, then a fresh release is deployed. Media + DB are routed through your local machine, so **no direct source→target SSH is required** (Deployer already has SSH to both).

- **Needs:** `config.sync_from_host` (source alias), both hosts defined, and a local `.env.newserver` template for the target.
- **Call it on the TARGET host** (`dep sw:transfer newserver`); the source comes from `sync_from_host`.
- Same lock protection and `--force` as `sw:publish`.

### `migrate:*` — selective data migration (relaunch)

[](#migrate--selective-data-migration-relaunch)

Copies selected **business data** (customers, orders, newsletter, number ranges, promotions …) from your locally migrated DB into an **existing** target shop — without touching the target's catalog/config. This runs **local → target host**(no `sync_from_host`).

```
vendor/bin/dep migrate:backup prod             # 1. rollback point (dumps target DB)
vendor/bin/dep migrate:integrity-check prod    # 2. schema / orphan / row-count report
vendor/bin/dep migrate:tables prod             # 3. push whitelisted tables (atomic)
vendor/bin/dep migrate:postprocess prod        # 4. fix refs + cache:clear + dal:refresh:index

# if needed:
vendor/bin/dep migrate:rollback prod -o backup=var/migrate-backups/.sql.gz
vendor/bin/dep migrate:switch:domain prod -o sc_from=old.de -o sc_to=new.de -o app_url=https://new.de
vendor/bin/dep migrate:maintenance:enable prod   # / :disable
```

- **Needs:** a whitelist file `bin/migrate.tables` (one table per line, `#` = comment) and a local DB holding the migrated source data.
- **Configure** the specifics in `config:` (all optional, sensible defaults):

```
config:
  migrate_tables_file: bin/migrate.tables          # whitelist location
  migrate_backup_dir:  var/migrate-backups         # where backups are stored (local)
  migrate_fallback_shipping_method: ''             # 32-char hex id, for orphaned deliveries
  migrate_shipping_method_map: {}                  # { oldHexId: newHexId } (applied first)
```

Example `bin/migrate.tables`:

```
# Customers
customer
customer_address
# Orders
order
order_line_item
order_delivery
# Number ranges (order/customer counters!)
number_range_state

```

### `fetch` — pull a remote state to local

[](#fetch--pull-a-remote-state-to-local)

```
vendor/bin/dep fetch:db prod       # dump remote DB → import into local
vendor/bin/dep fetch:files prod    # download shared media → local
vendor/bin/dep fetch prod          # both
```

Reads the remote credentials from the host's `.env.local`.

---

Typical workflows
-----------------

[](#typical-workflows)

GoalCommands**First time online** (local shop → new server)`cp .env .env.prod` (edit) → `dep sw:publish prod`**Routine deploy** (code only)`dep deploy prod`**Server move** (old → new)set `sync_from_host: old`, `cp .env .env.new` (edit) → `dep sw:transfer new`**Relaunch** (migrate live data into a rebuilt shop)`dep migrate:backup` → `migrate:integrity-check` → `migrate:tables` → `migrate:postprocess`Settings reference
------------------

[](#settings-reference)

SettingDefaultPurpose`sw_env_template``.env.`local env template uploaded as `shared/.env.local``sw_shared_config_files``auth.json`, `public/.htaccess`, `public/.user.ini`config uploaded once by `shared:init``sw_shared_media_dirs``files`, `public/media`, `public/thumbnail`, `public/sitemap`, `public/export`media moved by publish/transfer`sw_deploy_lock_file``{{deploy_path}}/.sw-publish.lock`publish/transfer protection lock`sw_mysqldump_options``--single-transaction --quick --no-tablespaces --skip-comments --default-character-set=utf8mb4`dump options for full dumps`sw_health_check``true`run `system:check` during deploy (false for headless)`dotenv``{{current_path}}/.env.local`file Deployer sources before each `run()` (real secrets). Migrating from an old hoster that keeps creds in `.env`? override with `{{current_path}}/.env``migrate_tables_file``bin/migrate.tables`whitelist for `migrate:tables`---

TYPO3 / generic
===============

[](#typo3--generic)

```
import:
  - vendor/wineworlds/deployer-recipes/recipe/typo3-rsync.php

config:
  sync_from_host: live
  sync_to_host: preview
```

```
vendor/bin/dep sync preview        # sync:db + sync:files (host → host)
vendor/bin/dep fetch preview       # fetch:db + fetch:files (host → local)
vendor/bin/dep transfer preview    # sync:db + full deploy_path rsync
```

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance93

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community5

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~79 days

Recently: every ~227 days

Total

16

Last Release

34d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cc19060018e2f7d2b0ecd6776e204a086c7a9ecc99009031af9c6945bfaab240?d=identicon)[melnikov](/maintainers/melnikov)

### Embed Badge

![Health badge](/badges/wineworlds-deployer-recipes/health.svg)

```
[![Health](https://phpackages.com/badges/wineworlds-deployer-recipes/health.svg)](https://phpackages.com/packages/wineworlds-deployer-recipes)
```

###  Alternatives

[lorisleiva/laravel-deployer

Laravel Deployer is a lightweight wrapper of Deployer giving Artisan the power of zero-downtime deployment.

1.7k1.3M4](/packages/lorisleiva-laravel-deployer)[sourcebroker/deployer-extended

Library with some additional tasks for deployer (deployer.org).

25297.9k12](/packages/sourcebroker-deployer-extended)[hypernode/deploy-configuration

Hypernode deploy configuration files

11140.1k](/packages/hypernode-deploy-configuration)[ngmy/webloyer

Webloyer is a Web UI for managing Deployer deployments

2191.1k](/packages/ngmy-webloyer)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
