Deploy Bash is a lightweight, ultra fast, interactive, and extensible Bash script designed to automate code deployments across multiple servers. It is built for Debian-based systems and maintained by Buffer Punk.
deploy.sh simplifies deployment workflows by handling tasks like:
- Packaging and deploying your project to multiple remote servers
- Running remote setup commands (on first deploy or updates)
- Managing symlinks for version control (via
current→ latest version) - Supporting both domain and IP-based deployments
- Handling rollbacks to previous versions
- Restarting specified systemd services
- Interactive countdowns and safety prompts
The goal: make deployment effortless, safe, and repeatable — without requiring heavy CI/CD tooling.
✅ Deploy to one or multiple servers at once
✅ Supports both IPs and domain names
✅ Optional pre-deploy and setup commands
✅ Built-in rollback mechanism
✅ NPM install support for node projects
✅ apt update support (so you don't manually run it)
✅ Keeps only a specified number of releases (--keep)
✅ Validates configuration and inputs
✅ Interactive countdown before deploy
✅ Optionally adds itself to $PATH for one-line use (deploy [options])
✅ Uses human-readable color-coded outputs
- Debian-based OS (Ubuntu, Debian, etc.)
sshaccess to target serversbash,sudo, andscpavailablednsutils(for domain validation)- Remote servers must support
systemctl
git clone https://github.com/bufferpunk/deploy-bash.git
cd deploy-bash
chmod +x deploy.sh
./deploy.shThe first run will ask if you want to add it to your $PATH:
Do you want to add it to your $PATH? (y/n)If you choose “y”, it’ll create a symlink at /usr/local/bin/deploy, so you can run it globally:
deploy [options]You can deploy with flags or a configuration file.
deploy \
--project=myapp \
--type=ip \
--servers=[192.168.1.2,192.168.1.3] \
--services=[nginx,myapp.service] \
--deploy-dir=/var/www \
--setup=full
--apt-updateCreate a config file (e.g. prod.conf):
SERVERS=[192.168.1.2,192.168.1.3]
SERVICES=[nginx,myapp.service]
TYPE="ip"
PROJECT_NAME="myapp"
DEPLOY_DIR="/var/www"
SSH_USER="ubuntu"
SSH_KEY="~/.ssh/id_rsa"
NODE_HOME="." # use relative paths
SETUP_COMMAND="echo something"
# etc ...Then deploy with:
deploy --config=deployment/prod.confIf something goes wrong, rollback to an earlier version:
deploy --rollback=2 --config=prod.confThis restores the second-most recent version and restarts your services.
The --setup flag allows running arbitrary setup commands on remote servers.
--setup=full: deploys and then runs setup--setup=only: runs setup without deploying
You’ll be asked interactively how many setup commands you want to add, for example:
How many commands do you want to run on the remote server(s)?: 2
Enter command 1: apt update -y
Enter command 2: systemctl restart nginx
The script automatically archives deployed versions and keeps a maximum number of them (default 5).
Use --keep=<number> to change that limit.
deploy --config=deployment/deploy.conf --npmOutput (simplified):
myapp/
├── deployment/
| ├── awesome.conf
| ├── prod.conf
| └── your.other.scripts
├── versions/
│ ├── myapp20251020142300/
│ ├── myapp20251019115022/
│ └── ...
└── your_other_code
| Flag | Description | |
|---|---|---|
--config=<file> |
Load configuration from a file | |
--project=<name> |
Name of the project folder | |
--servers=[a,b,...] |
Comma-separated server list | |
--services=[a,b,...] |
Comma-separated systemd service names | |
--type=<domain / ip> |
Type of server list provided | |
--deploy-dir=<path> |
Remote directory for deployment | |
--apt-update |
Run apt update on server |
|
--npm |
Run npm install on server |
after deploying |
--setup=<full / only> |
Setup and deploy, or setup only | |
--rollback=<number> |
Roll back to a previous version | |
--keep=<number> |
Number of old versions to retain | |
--help / -h |
Show usage |
MIT License © 2025 Buffer Punk
Pull requests are welcome! Please open an issue first to discuss proposed changes.