Stack Up ======== Stack Up is a simple deployment tool that performs given set of commands on multiple hosts in parallel. It reads Supfile, a YAML configuration file, which defines networks (groups of hosts), commands and targets. # Demo [![Sup](https://github.com/pressly/sup/blob/gif/asciinema.gif?raw=true)](https://asciinema.org/a/19742?autoplay=1) *Note: Demo is based on [this example Supfile](./example/Supfile).* # Installation $ go get -u github.com/pressly/sup/cmd/sup # Usage $ sup [OPTIONS] NETWORK COMMAND [...] ### Options | Option | Description | |-------------------|----------------------------------| | `-f Supfile` | Custom path to Supfile | | `-e`, `--env=[]` | Set environment variables | | `--only REGEXP` | Filter hosts matching regexp | | `--except REGEXP` | Filter out hosts matching regexp | | `--debug`, `-D` | Enable debug/verbose mode | | `--disable-prefix`| Disable hostname prefix | | `--help`, `-h` | Show help/usage | | `--version`, `-v` | Print version | ## Network A group of hosts. ```yaml # Supfile networks: production: hosts: - api1.example.com - api2.example.com - api3.example.com staging: # fetch dynamic list of hosts inventory: curl http://example.com/latest/meta-data/hostname ``` `$ sup production COMMAND` will run COMMAND on `api1`, `api2` and `api3` hosts in parallel. ## Command A shell command(s) to be run remotely. ```yaml # Supfile commands: restart: desc: Restart example Docker container run: sudo docker restart example tail-logs: desc: Watch tail of Docker logs from all hosts run: sudo docker logs --tail=20 -f example ``` `$ sup staging restart` will restart all staging Docker containers in parallel. `$ sup production tail-logs` will tail Docker logs from all production containers in parallel. ### Serial command (a.k.a. Rolling Update) `serial: N` constraints a command to be run on `N` hosts at a time at maximum. Rolling Update for free! ```yaml # Supfile commands: restart: desc: Restart example Docker container run: sudo docker restart example serial: 2 ``` `$ sup production restart` will restart all Docker containers, two at a time at maximum. ### Once command (one host only) `once: true` constraints a command to be run only on one host. Useful for one-time tasks. ```yaml # Supfile commands: build: desc: Build Docker image and push to registry run: sudo docker build -t image:latest . && sudo docker push image:latest once: true # one host only pull: desc: Pull latest Docker image from registry run: sudo docker pull image:latest ``` `$ sup production build pull` will build Docker image on one production host only and spread it to all hosts. ### Local command Runs command always on localhost. ```yaml # Supfile commands: prepare: desc: Prepare to upload local: npm run build ``` ### Upload command Uploads files/directories to all remote hosts. Uses `tar` under the hood. ```yaml # Supfile commands: upload: desc: Upload dist files to all hosts upload: - src: ./dist dst: /tmp/ ``` ### Interactive Bash on all hosts Do you want to interact with multiple hosts at once? Sure! ```yaml # Supfile commands: bash: desc: Interactive Bash on all hosts stdin: true run: bash ``` ```bash $ sup production bash # # type in commands and see output from all hosts! # ^C ``` Passing prepared commands to all hosts: ```bash $ echo 'sudo apt-get update -y' | sup production bash # or: $ sup production bash <<< 'sudo apt-get update -y' # or: $ cat < sup -f ./services/scheduler/Supfile $SUP_ENV $SUP_NETWORK restart db-up: desc: Migrate database local: > sup -f ./database/Supfile $SUP_ENV $SUP_NETWORK up ``` # Common SSH Problem if for some reason sup doesn't connect and you get the following error, ```bash connecting to clients failed: connecting to remote host failed: Connect("myserver@xxx.xxx.xxx.xxx"): ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain ``` it means that your `ssh-agent` dosen't have access to your public and private keys. in order to fix this issue, follow the below instructions: - run the following command and make sure you have a key register with `ssh-agent` ```bash ssh-add -l ``` if you see something like `The agent has no identities.` it means that you need to manually add your key to `ssh-agent`. in order to do that, run the following command ```bash ssh-add ~/.ssh/id_rsa ``` you should now be able to use sup with your ssh key. # Development fork it, hack it.. $ make build create new Pull Request We'll be happy to review & accept new Pull Requests! # License Licensed under the [MIT License](./LICENSE).