PHPackages                             survos/deployment-bundle - 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. survos/deployment-bundle

ActiveSymfony-bundle[DevOps &amp; Deployment](/categories/devops)

survos/deployment-bundle
========================

Tools for deploying Survos projects to dokku

2.18.0(2w ago)13.2k↑46.7%[1 issues](https://github.com/survos/deployment-bundle/issues)MITPHPPHP ^8.5

Since Nov 12Pushed 2w ago2 watchersCompare

[ Source](https://github.com/survos/deployment-bundle)[ Packagist](https://packagist.org/packages/survos/deployment-bundle)[ GitHub Sponsors](https://github.com/kbond)[ RSS](/packages/survos-deployment-bundle/feed)WikiDiscussions main Synced 2w ago

READMEChangelogDependencies (131)Versions (774)Used By (0)

Survos Deployment Bundle
========================

[](#survos-deployment-bundle)

Helpers for deploying a Symfony app to **Dokku** (e.g. on Hetzner). Provides a single `dokku` console command that creates the app, scaffolds the deployment files (`Procfile`, `nginx.conf`, `fpm_custom.conf`, `app.json`), manages config and storage, and deploys.

```
composer require --dev survos/deployment-bundle
```

The `dokku` command
-------------------

[](#the-dokku-command)

```
bin/console dokku  [param] [--app=NAME] [--host=HOST] [--force]

```

ActionWhat it does`bootstrap` (default)`init` + `scaffold` in one go`init`Create the Dokku app + add the `dokku` git remote`scaffold`Create/update `Procfile`, `nginx.conf`, `fpm_custom.conf`, `app.json``config [KEY=value]`Show all config, or set one var`storage [/host:/container]`List or add a persistent mount`deploy``git push dokku main``logs` / `ps` / `restart` / `destroy`App lifecycle- **Preview by default.** Without `--force`, mutating steps are only *listed*. Add `--force` to actually create the app, write files, and set config.
- `--host` defaults to `ssh.survos.com`; the app name is auto-detected from the `dokku` git remote, else the directory name. Pass `--app=ai-demo` to override.
- Requires SSH access as `dokku@` (test: `ssh dokku@ssh.survos.com apps:list`).

### Standalone app — happy path

[](#standalone-app--happy-path)

```
bin/console dokku bootstrap --app=myapp --force   # app + remote + scaffold files
bin/console dokku config OPENAI_API_KEY=sk-...      # set secrets (repeat per var)
bin/console dokku deploy --force                    # git push dokku main
bin/console dokku logs                              # watch
```

The app is served from `public/` via `heroku-php-nginx` (see the generated `Procfile`). The PHP buildpack runs `composer install --no-dev` on the server, so `require-dev` packages (including this bundle) are NOT deployed.

---

Deploying an app that lives in a **monorepo subdirectory**
----------------------------------------------------------

[](#deploying-an-app-that-lives-in-a-monorepo-subdirectory)

Dokku deploys whatever you `git push`, and `dokku deploy` runs a plain `git push dokku main`. That only works when the app **is its own git repo**. If the app is a subdirectory of a larger monorepo (e.g. `demo/` inside `symfony/ai`), a plain push would send the whole monorepo with the wrong root.

The fix: build a **throwaway git repo from the app directory** and push *that*. Drop a `bin/deploy` script in the app (this is exactly what we use for the `symfony/ai` demo → `ai-demo.survos.com`):

```
#!/usr/bin/env bash
# Deploy a monorepo-subdir Symfony app to Dokku via a throwaway git repo.
set -euo pipefail
APP="${DOKKU_APP:-ai-demo}"
DOKKU_HOST="${DOKKU_HOST:-ssh.survos.com}"
cd "$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"; ROOT="$(pwd)"

# 1) Config/secrets from .env.local (values never printed; .env.local stays gitignored)
CFG=( APP_ENV=prod APP_DEBUG=0 )
if [ -f .env.local ]; then
  while IFS= read -r line; do
    case "$line" in
      OPENAI_API_KEY=*|MISTRAL_API_KEY=*|ANTHROPIC_API_KEY=*|CEREBRAS_API_KEY=*)
        key="${line%%=*}"; val="${line#*=}"; val="${val%\"}"; val="${val#\"}"; val="${val%\'}"; val="${val#\'}"
        CFG+=( "${key}=${val}" );;
    esac
  done /dev/null

# 2) Throwaway repo built from THIS dir → push (triggers the build)
TMP_GIT="${ROOT}/.git-deploy"; rm -rf "$TMP_GIT"; trap 'rm -rf "$TMP_GIT"' EXIT
G() { git --git-dir="$TMP_GIT" --work-tree="$ROOT" "$@"; }
G init -q -b main
G add -A
G add -f composer.lock          # see gotcha below
G -c user.email=deploy@survos.com -c user.name=deploy commit -q -m "deploy ${APP}"
G remote add dokku "dokku@${DOKKU_HOST}:${APP}"
G push -f dokku main
```

Run `bin/console dokku scaffold --app= --force` once to generate the `Procfile`/`nginx.conf`/`app.json` in the subdir, then deploy with `bin/deploy`. (`git subtree push --prefix= dokku main` is an alternative, but the throwaway repo is simpler and keeps the monorepo history untouched.)

> A `bin/deploy` can equally be a **Castor** task or a **justfile** recipe — plain bash just avoids an extra dependency.

---

Gotchas (learned deploying `ai-demo`)
-------------------------------------

[](#gotchas-learned-deploying-ai-demo)

1. **Track `composer.lock` for apps.** The PHP buildpack requires it. Monorepos often gitignore `composer.lock` globally (correct for *libraries*); add a negation in the app's own `.gitignore` so the app commits its lock:

    ```
    !composer.lock
    ```
2. **`app.json` `WEB_CONCURRENCY` must have a `value`, not a `generator`.** The scaffolded template used `"generator": "echo 5"`; Dokku can't run generators non-interactively and the release fails with *"required env var WEB\_CONCURRENCY has no value … no TTY for prompt"*. Use:

    ```
    "WEB_CONCURRENCY": { "description": "workers", "value": "2" }
    ```
3. **Trim `app.json` for minimal apps.** The default template declares `dokku-postgres`/`dokku-redis` addons and a predeploy that runs `secrets:decrypt-to-local` + `doctrine:migrations:migrate`. If your app doesn't use a DB or the Symfony Vault, those fail or waste time — strip the `addons` and reduce `predeploy` (the AI demo only needs `bin/console asset-map:compile`).
4. **Secrets:** set API keys via `dokku config:set` (the `bin/deploy` above pulls them from `.env.local`, which stays gitignored and is never pushed) **or** via the Symfony Vault (then set `SYMFONY_DECRYPTION_SECRET` as a Dokku config var and keep `secrets:decrypt-to-local` in `predeploy`). Set config **before** the push so `APP_ENV=prod` is present at build time (asset compilation, cache warmup).
5. **Consuming a fork live.** If the app depends on an unreleased fork (e.g. `symfony/ai:dev-tac`), the app's `composer.json` must carry the VCS `repositories` entry + `minimum-stability: dev` so the buildpack's `composer install` can fetch it on the server. No local paths (`../`) survive a Dokku build.

---

Verifying
---------

[](#verifying)

```
bin/console dokku logs                 # or: ssh dokku@ logs  -t
curl -sI http://./          # expect 200
```

Further reading
---------------

[](#further-reading)

- dokku CLI:
-
- Survos clusters:

###  Health Score

51

—

FairBetter than 95% of packages

Maintenance76

Regular maintenance activity

Popularity22

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity81

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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 ~1 days

Recently: every ~10 days

Total

773

Last Release

20d ago

Major Versions

1.6.39 → 2.0.152025-09-28

PHP version history (4 changes)1.5.79PHP ^8.1

1.5.411PHP ^8.3

1.6.17PHP ^8.4

2.8.4PHP ^8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/21b39551f92ed4143772c622f9e571589c5a72c96ab3c53fe67489ce0d83e806?d=identicon)[tacman1123](/maintainers/tacman1123)

---

Top Contributors

[![tacman](https://avatars.githubusercontent.com/u/619585?v=4)](https://github.com/tacman "tacman (14 commits)")

---

Tags

symfonydevsymfony-ux

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/survos-deployment-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/survos-deployment-bundle/health.svg)](https://phpackages.com/packages/survos-deployment-bundle)
```

###  Alternatives

[chameleon-system/chameleon-base

The Chameleon System core.

1029.4k6](/packages/chameleon-system-chameleon-base)

PHPackages © 2026

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