PHPackages                             innmind/tower - 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. [CLI &amp; Console](/categories/cli)
4. /
5. innmind/tower

AbandonedArchivedLibrary[CLI &amp; Console](/categories/cli)

innmind/tower
=============

Application deployment tool

2.2.0(5y ago)011MITPHPPHP ~7.4|~8.0CI failing

Since Mar 11Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/Innmind/Tower)[ Packagist](https://packagist.org/packages/innmind/tower)[ Docs](http://github.com/Innmind/Tower)[ RSS](/packages/innmind-tower/feed)WikiDiscussions develop Synced 3d ago

READMEChangelogDependencies (11)Versions (10)Used By (0)

Tower
=====

[](#tower)

[![Build Status](https://github.com/Innmind/Tower/workflows/CI/badge.svg?branch=master)](https://github.com/Innmind/Tower/actions?query=workflow%3ACI)[![codecov](https://camo.githubusercontent.com/9b6c9dae4d38f502b89b2b2e3f8c0c7175c9a4d245996b27d215c9947c38baa6/68747470733a2f2f636f6465636f762e696f2f67682f496e6e6d696e642f546f7765722f6272616e63682f646576656c6f702f67726170682f62616467652e737667)](https://codecov.io/gh/Innmind/Tower)[![Type Coverage](https://camo.githubusercontent.com/b01e02f1802480d4bed2b65b1b189da89aab9e5bcf9d0cd1ee6d4f05d7a4807c/68747470733a2f2f73686570686572642e6465762f6769746875622f496e6e6d696e642f546f7765722f636f7665726167652e737667)](https://shepherd.dev/github/Innmind/Tower)

This is a command line tool to deploy your code base with a new approach. Instead of building another tool sending a set of shell commands over ssh with a logic of point to point, Tower takes the approach of servers as nodes of a tree where from a node you trigger the *tower* of sub-nodes.

The setup:

- one install of Tower per server
- the config to deploy the server is localised on it
- a *node\** only knows its neighbours' servers

Advantages:

- One only knows what can be deployed on a server (not how)
- Keep the *know how to deploy* on the server
- If the actions are updated, no one is impacted
- Easily cascade deployment (if a node retrieve sources from its parent)
- Nodes at the same level can be deployed in parrallel (via background jobs, loose direct output)
- Commands run locally, everything's logged so you can trace what/when an env is deployed

Drawbacks:

- A node need to know how to connect to its neighbours (if node is hacked the subtree is compromised) (specific to the `ssh` transport, `tcp` not affected)
- A node need to know how to connect to its parent to retrieve sources (lower the load on master repository) (only if you decide such a strategy)
- Cross relation between parent and neighbours

Example:

```
              A (you)
             / \
            /   \
           /     \
   (prod) B       C (staging)
         / \       \
        /   \       \
       /     \       \
      D       E       F
      |       |
      |       |
      G       H

```

Say here the tree below `B` is also for production, with this tool you could easily place the same Tower setup on the five servers and to deploy all of them, you would run a command like `tower ping B` and done! Or if you want to only deploy `H`, just to be sure everythings deploying fine, connect to the machine and locally run `tower trigger` or add this as one of the neighbour on your local machine (`A`) and run `tower ping H`. Once again it's a tree, you can start from wherever you want.

But in a normal case you would just have `B` and `C` as neighbours of your machine.

To be really efficient (meaning not overloading your VCS server), setup neighbours to retrieve code from their parent. For instance, setup `B` and `C` with your VCS server as `git remote`; `D` and `E` have `B` as `git remote`, and so on...

*Note*: I talk about git here, but you're not forced to use it

*Note*: When cascading, if a neighbour fail to deploy, its subtree won't be deployed

Another use case would be you have a single server for your app, and other servers for related services required by your first server. You could imply, with this notion of tree, that every time you deploy your app it triggers the deployment of those related services (so everything is always up-to-date).

Installation
------------

[](#installation)

```
composer global require innmind/tower
```

Configuration
-------------

[](#configuration)

```
neighbours:
    _name_:
        url: ssh://example.com:80/path/to/config/on/neighbour/server.yml # scheme can be tcp or ssh, path only used via ssh
        tags: [foo, bar] # optional

exports: # optional
    - 'echo "ENV=value"' # contains list of env variables that will be available to each action

actions:
    - 'some bash command'
```

The `actions` set will be the commands run on you server when the server the configuration is on is pinged. Each actions will have as environment variables the ones built via the `exports` section, this array must be commands that will produce an output of the form `ENV=value`.

Finally the `neighbours` section is the list of the servers that will be pinged when the one the configuration is on is pinged. You can decide to ping a server either by `ssh` (leaving the server vulnerable to the outside world, but is the easiest) or by a `tcp` socket (allows to close all direct access to the machine but opens to a DOS attack).

Usage
-----

[](#usage)

### Via `ssh`

[](#via-ssh)

On your machine configure a `tower.yml` file with the following:

```
neighbours:
    gateway:
        url: ssh://gateway.com:22/path/to/configuration/on/gateway
```

Once done you can run `tower ping gateway` in this folder. This will connect to `gateway.com` via the port `22`, move to the folder `/path/to/configuration/on/gateway` and run the command `tower trigger`; you'll need to create a file `tower.yml` in the folder that will either describe the actions to do or the neighbours to ping.

### Via `tcp`

[](#via-tcp)

On your machine configure a `tower.yml` file with the following:

```
neighbours:
    gateway:
        url: tcp://gateway.com:1337
```

On the server you need to create a similar file named `tower.yml` containing either the actions to run or the neighbours to ping; then in this folder run `tower listen 1337 -d`. This last command opens a tcp connection on port `1337` and waits for incoming pings.

Now you can run on your machine `tower ping gateway`.

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance55

Moderate activity, may be stable

Popularity5

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity74

Established project with proven stability

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

Recently: every ~82 days

Total

8

Last Release

1910d ago

Major Versions

1.2.0 → 2.0.02020-03-28

PHP version history (3 changes)1.0.0PHP ~7.2

2.0.0PHP ~7.4

2.2.0PHP ~7.4|~8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/851425?v=4)[Baptiste Langlade](/maintainers/Baptouuuu)[@Baptouuuu](https://github.com/Baptouuuu)

---

Top Contributors

[![Baptouuuu](https://avatars.githubusercontent.com/u/851425?v=4)](https://github.com/Baptouuuu "Baptouuuu (74 commits)")

---

Tags

clideploygraph

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/innmind-tower/health.svg)

```
[![Health](https://phpackages.com/badges/innmind-tower/health.svg)](https://phpackages.com/packages/innmind-tower)
```

###  Alternatives

[acmephp/acmephp

Let's Encrypt client written in PHP

649155.1k](/packages/acmephp-acmephp)[access9/dbtabledump

The database table dumper

1014.0k](/packages/access9-dbtabledump)

PHPackages © 2026

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