
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
bare-deploy
Advanced tools
Atomic zero-downtime deployments to bare VPS servers over SSH. No containers required.
██████ █████ ██████ ███████
██ ██ ██ ██ ██ ██ ██
██████ ███████ ██████ █████
██ ██ ██ ██ ██ ██ ██
██████ ██ ██ ██ ██ ███████
Deploy tool by Abtz Labs
Atomic zero-downtime deployments to bare VPS (Virtual Private Server) over SSH.
Just disciplined releases.
Bare Deploy is built for developers who:
Inspired by the simplicity of Kamal, but designed for host-native deployments.
distDirs for different servers).gitignore (except the build output directory)npm install -g bare-deploy
In your project root, run the following command to generate the bare.config.json configuration file:
bare init
The files it creates looks like this 👇
{
"servers": [
{
"host": "your-server.com",
"user": "deploy",
"port": 22,
"identityFile": "~/.ssh/id_rsa",
"distDir": "./dist",
"deployTo": "/var/www/app",
"webroot": "",
"include": [],
"ignore": [".git/*"],
"preScripts": [],
"postScripts": [],
"startScript": "pm2 restart --env production --update-env"
}
],
"keepReleases": 5,
"include": [],
"ignore": [".git/*"],
"healthCheck": {
"url": "http://localhost:3000/health",
"timeout": 15
}
}
[!NOTE] Server-specific options (
distDir,deployTo,webroot,include,ignore,preScripts,postScripts,startScript) allow deploying different parts of your project to different servers.
[!NOTE] When running
bare init:
- If
package.jsondoesn't exist, it's created with version0.1.0- If
.gitignoredoesn't exist, it's created withbare.config.json- If
.gitignoreexists but doesn't containbare.config.json, the entry is added automatically
Each server in the servers array can have its own configuration:
{
"servers": [
{
"host": "server.com",
"user": "deploy",
"port": 22,
"identityFile": "~/.ssh/id_rsa",
"distDir": "./dist",
"deployTo": "/var/www/app",
"webroot": "/var/www/app/public_html",
"preScripts": [],
"postScripts": [],
"startScript": "pm2 restart --env production --update-env"
}
// ...
]
}
| Option | Required | Default | Description |
|---|---|---|---|
servers[].distDir | Yes | "./dist" | Directory where the content to package for deployment lives. |
servers[].deployTo | Yes | Base path on the server where deployments are stored. Bare Deploy creates a releases/ subfolder with timestamped versions. | |
servers[].webroot | No | Empty | Path to the web server's document root. On first deploy, backs up existing webroot to {webroot}.bak and creates a symlink. Automatically copies .well-known/ (Let's Encrypt) from the previous deployment. |
servers[].preScripts | No | [] | Array of commands to run locally before building the deployment package. |
servers[].postScripts | No | [] | Array of commands to run on the server after deployment but before switching the symlink. |
servers[].startScript | No | Empty | Command to run after symlink switch. Useful for process managers like PM2. |
servers[].include | No | Empty | Array of glob patterns to include in the deployment package. When specified, only matching files are packaged. Falls back to global include if not set. Add ".*" to include hidden files like .env.production. |
servers[].ignore | No | [] | Array of glob patterns to exclude from the deployment package. Applied after include patterns. Falls back to global ignore if not set. |
| Option | Required | Default | Description |
|---|---|---|---|
include | No | [] | Array of glob patterns to include in the deployment package. Used as fallback when not defined per-server. |
ignore | No | [".git/*"] | Array of glob patterns to exclude from the deployment package. Used as fallback when not defined per-server. |
keepReleases | No | 5 | Number of releases to keep on the server as history. |
healthCheck | No | {} | Runs after all deploy steps to validate the deployment. If it fails, the deploy is automatically rolled back. Accepts url (URL to check) and timeout (seconds to wait, default 15). |
healthCheck.url | Empty | The URL to check after deployment. | |
healthCheck.timeout | 15 | Seconds to wait for the health check to succeed. |
bare deploy [options]
--dry-run Simulate execution
--json JSON logging
--verbose Show detailed operation info
--sequential Deploy server-by-server
--patch Bump patch version (default)
--minor Bump minor version
--major Bump major version
package.json version.Re-points the current release to the given deploy ID. Also updates the previous symlink to point to the version before the rollback target.
bare rollback [id]
Bare Deploy manages three symlinks in your releases directory:
current - Points to the active releaseprevious - Points to the previous release (one version before current)After each deploy:
current → new releaseprevious → previous release (what current was before)After each rollback:
current → rolled back releaseprevious → version before the rolled back release, if anyLists all the existing deploy artifacts in the server.
bare list
Purges historical deploy artifacts from the server while preserving the last X number of deploys, defined by keepReleases option.
bare cleanup
Containers are powerful, but for many SaaS teams running on VPS, they introduce:
Bare Deploy keeps the deployment model aligned with the host filesystem and process manager.
Bare Deploy is built and supported by Abtz Labs, the same people behind Abtz Analytics, KiwiCart, and others. It's opinionated, FREE, and open-source. Distributed under MIT license.
MIT © Abtz Labs
FAQs
Atomic zero-downtime deployments to bare VPS servers over SSH. No containers required.
We found that bare-deploy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.