Want to take your software engineering career to the next level? Join the mailing list for career tips & advice Click here


Super simple deployment tool - think of it like 'make' for a network of servers

Subscribe to updates I use sup

Statistics on sup

Number of watchers on Github 2179
Number of open issues 55
Average time to close an issue 27 days
Main language Go
Average time to merge a PR about 15 hours
Open pull requests 32+
Closed pull requests 9+
Last commit over 1 year ago
Repo Created over 5 years ago
Repo Last Updated 24 days ago
Size 23.2 MB
Homepage https://pressly.g...
Organization / Authorpressly
Latest Releasev0.5.3
Page Updated
Do you use sup? Leave a review!
View open issues (55)
View sup activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Evaluating sup for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

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.



Note: Demo is based on this example Supfile.


$ go get -u github.com/pressly/sup/cmd/sup




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


A group of hosts.

# Supfile

            - api1.example.com
            - api2.example.com
            - api3.example.com
        # 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.


A shell command(s) to be run remotely.

# Supfile

        desc: Restart example Docker container
        run: sudo docker restart example
        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!

# Supfile

        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.

# Supfile

        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
        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.

# Supfile

        desc: Prepare to upload
        local: npm run build

Upload command

Uploads files/directories to all remote hosts. Uses tar under the hood.

# Supfile

        desc: Upload dist files to all hosts
          - src: ./dist
            dst: /tmp/

Interactive Bash on all hosts

Do you want to interact with multiple hosts at once? Sure!

# Supfile

        desc: Interactive Bash on all hosts
        stdin: true
        run: bash
$ sup production bash
# type in commands and see output from all hosts!
# ^C

Passing prepared commands to all hosts:

$ echo 'sudo apt-get update -y' | sup production bash

# or:
$ sup production bash <<< 'sudo apt-get update -y'

# or:
$ cat <<EOF | sup production bash
sudo apt-get update -y
uname -a

Interactive Docker Exec on all hosts

# Supfile

        desc: Exec into Docker container on all hosts
        stdin: true
        run: sudo docker exec -i $CONTAINER bash
$ sup production exec
ps aux
strace -p 1 # trace system calls and signals on all your production hosts


Target is an alias for multiple commands. Each command will be run on all hosts in parallel, sup will check return status from all hosts, and run subsequent commands on success only (thus any error on any host will interrupt the process).

# Supfile

        - build
        - pull
        - migrate-db-up
        - stop-rm-run
        - health
        - slack-notify
        - airbrake-notify

$ sup production deploy

is equivalent to

$ sup production build pull migrate-db-up stop-rm-run health slack-notify airbrake-notify


See example Supfile.

Basic structure

# Supfile
version: 0.4

# Global environment variables
  NAME: api
  IMAGE: example/api

      - localhost
      - stg1.example.com
      - api1.example.com
      - api2.example.com

    desc: Print some env vars
    run: echo $NAME $IMAGE $SUP_NETWORK
    desc: Print OS name and current date/time
    run: uname -a; date

    - echo
    - date

Default environment variables available in Supfile

  • $SUP_HOST - Current host.
  • $SUP_NETWORK - Current network.
  • $SUP_USER - User who invoked sup command.
  • $SUP_TIME - Date/time of sup command invocation.
  • $SUP_ENV - Environment variables provided on sup command invocation. You can pass $SUP_ENV to another sup or docker commands in your Supfile.

Running sup from Supfile

Supfile doesn't let you import another Supfile. Instead, it lets you run sup sub-process from inside your Supfile. This is how you can structure larger projects:


Top-level Supfile calls sup with Supfiles from sub-projects:

    desc: Restart scheduler
    local: >
      sup -f ./services/scheduler/Supfile $SUP_ENV $SUP_NETWORK restart
    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,

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
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

ssh-add ~/.ssh/id_rsa

you should now be able to use sup with your ssh key.


fork it, hack it..

$ make build

create new Pull Request

We'll be happy to review & accept new Pull Requests!


Licensed under the MIT License.

sup open issues Ask a question     (View All Issues)
  • almost 4 years a suggest, Supfile default filename should be Supfile.yml
  • almost 4 years need new environment variable like $SUP_PATH
  • almost 4 years target call target, display "Unknown command/target"
  • almost 4 years Use environment variables in inventory
  • almost 4 years Running commands/processes in the background from Sup command (e.g. &)
  • about 4 years Can't close interactive bash session
  • about 4 years Use ~/.ssh/config or allow user to override key
  • over 4 years Group commands based on networks?
  • over 4 years Supfile: Multiple runs in a single command?
  • over 4 years Uploading with rsync
  • over 4 years Remote depends on GNU/Bash
  • over 4 years Supfile: Allow argument on script
  • over 4 years Add conditionals (skip_if_run, skip_if_script)
  • over 4 years Error handling suggestion
  • over 4 years Move <target> option to <commands>
  • over 4 years Refactor local tar to using archive/tar pkg
sup open pull requests (View All Pulls)
  • LocalTar: Don't create intermediate bash process
  • Support parsing argument for script
  • Add homebrew
  • [DO NOT MERGE] Delegate ^C Interrupt signal
  • Add sudo option
  • [WIP] Use posix shell explicitly for remote commands
  • Implement passing env vars via CLI --env flag
  • [WIP] Added support to RSYNC upload
  • [WIP] Basic support for hashbangs
  • [WIP] Allow ssh key override
  • Add extra ssh auth method
  • Mark host to be asked for password
  • parse ssh_config for useful data
  • Fix uploading issue when `src` is an absolute path
  • Print usage items (networks/targets/commands) in order
  • WIP: SSH interactive passwords
  • Add support for SSH remote port forwarding
  • 128 identity file
  • Add SUPFILE_DIR as default environment variable
  • Switch sup to using Go modules
  • ssh: Specify HostKeyCallback in ClientConfig
  • Provide user feedback for common SSH configuration issues
  • Support usernames in Supfile host entries
  • add modules and fix issue-19767
  • improve ssh auth
  • added download operation
  • Update vendor golang.org/x/crypto
  • Ignore unreachable client error
  • Show connected status for each host.
  • parse ssh host info from per host string using 'net/url'
  • Support bastion command
  • Test sup command
sup questions on Stackoverflow (View All Questions)
  • Redirect HTTP to HTTPS excluding one sup domain and add www if needed
  • <span> + <sup> having a white-space inbetween caused by a line-break
  • Don't allow <sup> to break line
  • Overriding <sup> styling
  • JS sup() displaying tags in html
  • Styling the <sup> tag
  • how to show sup Total in WPF datagrid?
  • Adding superscript <sup> tags around all trademark and registered trademark symbols
  • I am trying to prepare a XElement with glyphicon "&#xAE;" with <sup> tag but in out put i am getting "&amp;#xAE;" how shold i prevent it
  • parsing <sup> tag inside <html:text>
  • Application is crashing when camera is opened and zoomed. This is hybrid app running in HWC. SUP is middle war
  • Correcting Webkit Vertical Alignment Issue with <sup> and CSS vertical-align:top on TD
  • Use a substituted for sup tag in PDFBundle in Symfony2
  • How can I use <sup></sup> in <option></option> in Html
  • add sup tag in ul li goes next line
  • <H2> followed by <Sup>
  • HTML <sup /> tag affecting line height, how to make it consistent?
  • sup tag doesnt work inside title tag
  • how to get the synchronizationGroup names in SUP 2.2?
  • relative font-size of <sub> or <sup> and their descendants in IE
  • Best practices recommended while developing android applications using SUP - SAP
  • BAPI gets called multiple times in Android SUP application Async Task
  • Inserting superscript using <sup> tag
  • Adding <sup> asterisk to placeholder, or a nice way to mark required fields via placeholder
  • turn all <sup> into links with the link being the contents of the sup tag
  • Register CallBackHandler IOS application,SUP,Xcode
  • Remove space between text and <sup>reference</sup> when text is justified
  • jQuery or CSS: replacing the ® mark with <sup>&reg;</sup>
  • Correcting <sup> & <sub> line-height
  • use Javascript to wrap all regmarks with <sup> tags unless they already have <sup> tags
sup list of languages used
sup latest release notes
v0.5.3 Pass through --env CLI variables when running inventory commands
--env and -e env variables set on the CLI will now overwrite env set on the network level. This supports use cases where users want to access environment variables on the inventory call.
v0.5.2 Experimental build for Windows; Network inventory improvement
  • Run network's inventory only when actually used
v0.5.1 Supfile.yml and SSH config improvements
  • Supfile.yml is now supported
  • Private SSH keys are read from all files matching ~/ssh/id_* wildcard
  • --sshconfig=~/.ssh/config reads your SSH Config file
  • Built with go 1.9
Other projects in Go