{"id":18337221,"url":"https://github.com/team-supercharge/bashistrano","last_synced_at":"2025-08-13T18:35:34.484Z","repository":{"id":85131488,"uuid":"119664112","full_name":"team-supercharge/bashistrano","owner":"team-supercharge","description":"A bash deployment automation tool","archived":false,"fork":false,"pushed_at":"2018-07-10T10:47:53.000Z","size":16,"stargazers_count":22,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-06T04:36:10.541Z","etag":null,"topics":["bash","deployment","docker-image"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/team-supercharge.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-31T09:19:50.000Z","updated_at":"2023-07-11T12:15:25.000Z","dependencies_parsed_at":"2023-03-03T02:31:02.357Z","dependency_job_id":null,"html_url":"https://github.com/team-supercharge/bashistrano","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/team-supercharge/bashistrano","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/team-supercharge%2Fbashistrano","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/team-supercharge%2Fbashistrano/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/team-supercharge%2Fbashistrano/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/team-supercharge%2Fbashistrano/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/team-supercharge","download_url":"https://codeload.github.com/team-supercharge/bashistrano/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/team-supercharge%2Fbashistrano/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270289231,"owners_count":24558960,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","deployment","docker-image"],"created_at":"2024-11-05T20:10:29.131Z","updated_at":"2025-08-13T18:35:34.456Z","avatar_url":"https://github.com/team-supercharge.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bashistrano\n\n**Bashistrano** is a remote server automation tool heavily inspired by [Capistrano](http://capistranorb.com/). It is written purely in bash without any external dependency.\n\nThe main use-case of Bashistrano is to deliver containerized (Docker-based) projects to remote servers. Once it's set up, you can deploy your code as easily as:\n\n```\n$ cd project\n$ ./bashistrano deploy uat v1.0.2\n```\n\n## Getting started\n\n1. Download the `bashistrano` script and commit in your project's source code.\n2. Add a `/tmp` entry in your `.gitignore` file\n3. Follow the instructions below on how to use and configure Bashistrano.\n\n---\n\n# Contents\n\n* [Usage](#usage)\n* [Configuration](#configuration)\n  - [Stages](#stages)\n  - [SSH Authentication](#ssh-authentication)\n  - [Using Docker images](#using-docker-images)\n  - [Example configuration](#example-configuration)\n* [Phases and Steps](#phases-and-steps)\n  - [Step descriptions](#step-descriptions)\n* [Hooks](#hooks)\n  - [Stage specific hooks](#stage-specific-hooks)\n  - [Variables](#variables)\n  - [Functions](#functions)\n  - [SSH tunnels](#ssh-tunnels)\n* [Roadmap](#roadmap)\n* [Contributing](#contributing)\n* [Author](#author)\n* [License](#license)\n\n# Usage\n\n```\n$ ./bashistrano\n\nUsage:  ./bashistrano COMMAND\n\nA bash deployment automation tool\n\nOptions:\n  -h, --help     Display this help message\n  -v, --version  Print version information and quit\n\nCommands:\n  deploy           Deploys the application end-to-end\n  only:prepare     Prepares the environment for deployment\n  only:deliver     Delivers from an already prepared environment\n\nRun './bashistrano COMMAND --help' for more information on a command\n```\n\n# Configuration\n\nThe following parameters can be set in `config.sh` or any stage specific configuration file like `config/uat.sh`.\n\nStage specific configuration takes precedence over the default defined in `config.sh`.\n\n| Parameter | Description\n|-|-|\n| `application` | application name |\n| `deploy_to` | remote directory for deployments |\n| `keep_releases` | number of releases to keep on remote servers |\n| `servers` | array of remote servers in `user@host:port` format (default port: 22) |\n| `images` | array of dependent Docker images (see more below) |\n\n## Stages\n\nIn Bashistrano terminology different deployment environments are called **stages**. The required folder structure is the following for a project with `uat` and `prod` stages.\n\n```\nproject/\n├── config/           \u003c-- stage specific configuration\n│   ├── uat.sh\n│   └── prod.sh\n├── stages/           \u003c-- stage specific code\n│   ├── uat/\n|   │   └── ...\n│   └── prod/\n|       └── ...\n├── bashistrano       \u003c-- bashistrano script\n└── config.sh         \u003c-- main configuration\n```\n\n## SSH authentication\n\nIt's recommended to use public key authentication on your servers. If it's not possible for some reason, you can supply your SSH password when running Bashinstrano.\n\n```\nSSH_PASS=secret ./bashistrano deploy uat v1.0.0\n```\n\nWhen the `SSH_PASS` variable is set Bashistrano is using the [sshpass](https://linux.die.net/man/1/sshpass) utility under the hood.\n\n\u003e *NOTE:* this method is **not recommended** since a simple `ps` command can expose your SSH password to all users on the same host.\n\n## Using Docker images\n\nBashistrano allows you to specify a list of Docker images which need to be downloaded and packaged together with the deployment code. This way remote servers don't need to have access to any private Docker registries.\n\nThe `images` parameter is an array with pairs of Docker tags with the following structure.\n\n```\nimages=(\n  \u003cfirst image remote\u003e \u003cfirst image local\u003e\n  \u003csecond image remote\u003e \u003csecond image local\u003e\n)\n```\n\nThe first value is the remote Docker image which need to be downloaded (possibly from a private registry). The second value is the desired tag which will be used on the remote servers.\n\nBashistrano is matchint local and remote Docker image IDs and performs uploading only if necessary.\n\n## Example configuration\n\nFor a typical multi-stage use-case the configuration will look like the following:\n\nDefault configuration in `config.sh`\n\n```bash\n#!/bin/bash -e\n\napplication=\"myapp\"\ndeploy_to=\"~/apps/$application/$stage\"\nkeep_releases=5\n\nimages=(\n  \"registry.example.com/myapp:1.0.0\" \"local/myapp:1.0.0\"\n  \"registry.example.com/dep:1.2.1\" \"local/dep:1.2.1\"\n)\n```\n\nStage-specific configuration in `config/uat.sh`\n\n```bash\n#!/bin/bash -e\n\nservers=( \"user@uat-1.server\" \"user@uat-2.server:2022\" )\n```\n\n# Phases and Steps\n\nThe deployment process consists of multiple **steps** grouped into two **phases**. The two phases together make up the deploy process.\n\n```\nSTEP                   PHASE\n                                  ──┐\n                   ──┐              │\nclean_local          │ prepare      │\npull_images          │              │\n                   ──┤              │\nclean_remote         │              │\npush_images          │              │ deploy\npush_code            │              │\npublish_release      │ deliver      │\ncleanup_releases     │              │\nlog_revision         │              │\n                   ──┘              │\n                                  ──┘\n```\n\n## Step descriptions\n\n| Step | Description |\n|-|-|\n| `clean_local` | Clean up local workspace |\n| `pull_images` | Download specified Docker images and save them locally |\n| `clean_remote` | Clean workspace on remote servers |\n| `push_images` | Upload locally stored Docker images to remote servers |\n| `push_code` | Upload current version of stage specific code |\n| `publish_release` | Switch out previous release to the newly uploaded one |\n| `cleanup_releases` | Keep only the last N release specified by `keep_releases` parameter |\n| `log_revision` | Add new entry to revision log file |\n\n# Hooks\n\nThe deployment process can be customized using **hooks**. Hooks are triggered before or after _phases_ and _steps_.\n\nThe hooks are executed in the following order.\n\n```\nstart\n├── before:deploy\n│   ├── before:prepare\n│   │   ├── before:clean_local\n│   │   ├── ...\n│   │   ├── ...\n│   │   └── after:pull_images\n│   ├── after:prepare\n│   ├── before:deliver\n│   │   ├── before:clean_remote\n│   │   ├── ...\n│   │   ├── ...\n│   │   └── after:log_revision\n│   └── after:deliver\n└── after:deploy\n```\n\nYou can simply add your custom hook by implementing a method named after the given hook in any of the configuration files.\n\n\n```bash\n#!/bin/bash -e\n\napplication=\"myapp\"\nkeep_releases=5\n\n# ...\n\nafter:deliver() {\n  run_locally 'echo Yaay'\n}\n```\n\n\u003e *NOTE:* if you implement a hook function you must specify a body, otherwise the process will fail\n\n## Stage specific hooks\n\nIf you want to have custom behaviour only on a specific stage, you have two options.\n\nLet's assume you want to add an `uat` specific `after:deliver` hook.\n\nThe hook is already in use in `config.sh`:\n\n```bash\n#!/bin/bash -e\n\nafter:deliver() {\n  run_locally 'echo Hello'\n}\n```\n\nYou can add stage-specific behaviour in `config/uat.sh` using a hook function postfixed with the stage name. It will run **after** the global hook:\n\n```bash\n#!/bin/bash -e\n\nafter:deliver:uat() {\n  run_locally 'echo World!'\n}\n```\n\n## Variables\n\nIn addition to the parameters you've explicitly set in the configuration the following Bash variables are accessible in hooks:\n\n| Variable name | Description |\n|-|-|\n| `$stage` | name of currently running stage |\n| `$version` | VERSION parameter passed on the command line |\n| `$release_id` | unique identifier of current run (date+time) |\n| `$release_path` | **remote path** for the release being uploaded |\n| `$current_path` | **remote path** for the currently active release |\n| `$tmp_path` | **remote path** for temporary files (cleaned on `clean_remote` step)\n| `$local_tmp_path` | **local path** for temporary files (cleaned on `clean_local` step)\n| `$local_port` | random **local port** opened after calling the `open_tunnel` function |\n| `$output` | captured standard output of the last invoked function (see [Functions](#functions)) |\n\n## Functions\n\nWhen writing your hooks you can you can leverage the utility functions listed below.\n\n`run_locally \u003ccommand\u003e` -- Run command on the local machine. The command being executed is displayed properly on the output.\n\n`run_remotely \u003ccommand\u003e` -- Run command on **every** remote machine specified in the `servers` array.\n\n`copy_to_remote \u003clocal_path\u003e \u003cremote_path\u003e` -- Use `scp` to recursively copy files to **every** remote machine.\n\n## SSH tunnels\n\nThe `open_tunnel` function can be used to [open-close SSH tunnels in a safe way](https://gist.github.com/scy/6781836).\n\n`open_tunnel \u003cserver\u003e \u003cremote_addr\u003e` -- Open an SSH tunnel for a random local port which can be accessed through the `$local_port` variable. You script has 10 seconds to open a connection to `$local_port` and after disconnection the SSH tunnel will be automatically terminated.\n\nLet's take the following example: you would like to create a tunnel to access Postgres DB running on `192.168.100.100` port `5432` which is only reachable through `appserver.com`.\n\n```bash\nopen_tunnel \"appserver.com\" \"192.168.100.100:5432\"\nrun_locally \"PGPASSWORD=pw psql -h localhost -p $local_port -U user -d db \u003c script.sql\"\n```\n\n# Roadmap\n\nBashistrano is not yet and (as almost all open-source projects) probably never will be _complete_. The following features can provide significant improvements and are planned to be implemented in the future.\n\nIf you consider to lend a helping hand visit the [Contributing](#contributing) section.\n\n**Planned features:**\n\n- parse and handle command line flags\n- user input validation\n- error handling\n- rollback functionality\n- check code integrity\n- check for new versions\n- generate initial folder structure\n- generate additional stages\n\n# Contributing\n\nBashistrano is an open-source project, contributions and feedbacks are welcome as always!\n\n1. Fork it ( http://github.com/team-supercharge/bashistrano/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n# Author\n\n[exoszajzbuk](https://github.com/exoszajzbuk) @ [![Supercharge](https://s18.postimg.org/hmcb95l8p/logo_with_text.png)](http://supercharge.io/)\n\n# License\n\n[MIT](LICENSE.md)\n\n```\nCopyright (c) 2018 Supercharge\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteam-supercharge%2Fbashistrano","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteam-supercharge%2Fbashistrano","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteam-supercharge%2Fbashistrano/lists"}