baptouuuu / tower
tool to deploy servers structured as a tree
Requires
- php: >=5.3.3
- monolog/monolog: 1.6.*
- swiftmailer/swiftmailer: @stable
- symfony/config: 2.5.*
- symfony/console: 2.5.*
- symfony/dependency-injection: 2.5.*
- symfony/filesystem: 2.5.*
- symfony/finder: 2.5.*
- symfony/process: 2.5.*
- symfony/yaml: 2.5.*
This package is not auto-updated.
Last update: 2022-02-01 12:40:26 UTC
README
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 childs' 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 command set is updated, no one is impacted
- Esaily 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 childs (if node is hacked the subtree is compromised)
- A node need to know how to connect to its parent to retrieve sources (lower the load on master repository)
- Cross relation between parent and childs
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 twr deploy B --cascade
and done!
Or if you want to only deploy H
, just to be sure everythings deploying fine, connect to the machine and locally run twr deploy:env prod
or add this as one of the child on your local machine (A
) and run twr deploy H
. Once again it's a tree, you can start from wherever you want.
But in a normal case you would just hace B
and C
as childs of your machine.
To be really efficient (meaning not overloading your VCS server, especially if deploying asynchronously), setup childs 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 your not forced to use it (but cool kids do ;))
Note: When cascading, if a child fail to deploy, it's 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
This is done via composer. Run the following command to install to install Tower as a global dependency.
composer global require baptouuuu/tower
This will install the binary file in ~/.composer/vendor/bin
.
Now to have the bin file as global command you need to set the folder in your system path. You can do by adding the line below in ~/.bash_profile
or ~/.bashrc
.
export PATH=~/.composer/vendor/bin:$PATH
Configuration
log_path: %root_dir%/deploy.log # path where you want to get your log (%root_dir% is the path to the tower directory) mail: # optional, used to send a mail when a env deploy fails transport: mail|sendmail|smtp username: ~ password: ~ host: ~ port: ~ to: sysadmin@company.tld from: server.name@company.tld macros: macroName: # set of commands (can be nested) - mysqldump - git clone git@host:repo.git releases/xxxx-xx-xx envs: prod: # define where is a local environment + how to deploy it path: /var/www/my-awesome-project exports: #optional - echo "ENV_KEY=someEnvVariableAvailableToAllCommands" - echo "FOO=$ENV_KEY" commands: - %macroName% - curl -sS https://getcomposer.org/installer | php ; ./composer.phar install rollback: # this is optional (useful to cleanup if the deployment fails) - rm -rf release/xxxx-xx-xx # you can define multiple environments childs: subNodeName: host: hostname.tld path: /path/to/tower/folder # path for the `subNodeName`server # you can define multiple childs
Notes:
- rotate your logs, every output for a local deployment is logged (so it can quickly become huge)
- a macro can contain another macro, still the same syntax:
%macroName%
- setup ssh keys between a node and its childs to connect without password, otherwise cascade deployment will fail
- an export command can reuse the previous exported values, all the exported values are available in
commands
androllback
ones - the mail sent when an env fails to deploy contains the log file as attachment
Usage
Deploy an env when your on the machine:
twr deploy:env envName [... envNameX] [--continue]
The continue
flag is useful when you deploy multiple environments, if one fails it will continue to deploy the others (this flag is off by default, and always off when deploying in cascade)
Deploy a child
twr deploy child [... childX] [--env=env1] [--env=envX] [--async] [-c|--cascade]
This would run the command twr deploy:env env1 envX
on the machine called child
.
async
flag run the previous command in background and displays you the resulting PID, and then move to the next child specified to deploy.
cascade
flag tells the child to deploy its childs when itself is deployed succesfully.
Important: when cascading, all childs and subchilds of the node you specified will be deployed (so be sure how to architect your tree).