Detect
Reads package.json and lockfiles to infer Express, NestJS, Next.js, Astro, React, Vue, Svelte, npm, yarn, pnpm, or bun.
shipnode init Bash deployment CLI
ShipNode deploys backends and static frontends over SSH, builds releases, flips the
current symlink atomically, reloads PM2, verifies health, and rolls back when a release misbehaves.
$ shipnode init framework Express package manager pnpm app type backend config shipnode.config.ts created $ shipnode deploy rsync ./ -> /var/www/api/releases/20260428194612 install pnpm install --frozen-lockfile build pnpm run build symlink current -> releases/20260428194612 pm2 reload api --update-env health GET /health 200 OK 47ms deployed https://api.example.com Release path
ShipNode stays intentionally boring on the server: timestamped folders, a shared env file, an atomic symlink, PM2 for processes, and Caddy for HTTPS.
Reads package.json and lockfiles to infer Express, NestJS, Next.js, Astro, React, Vue, Svelte, npm, yarn, pnpm, or bun.
shipnode init Installs Node.js, PM2, Caddy, jq, and the matching package manager on Ubuntu or Debian. This is the one-time server pass.
shipnode setup Builds, syncs, creates a timestamped release, switches the current symlink, reloads PM2, and checks health before declaring victory.
shipnode deploy current -> releases/20260428194612
releases/
20260428180603/
20260428194612/
shared/
.env
ecosystem.config.cjs
.shipnode/
releases.json
deploy.lock Why it exists
ShipNode is for developers who want a real server without rebuilding a deploy platform from shell history. It keeps the moving parts plain: SSH, rsync, releases, PM2, Caddy, health checks, and rollback.
Great at scale, heavy when you just need a VPS release path.
Fast to start, but pricing and platform rules become part of your architecture.
Transparent, but easy to forget a step under pressure.
Keeps the server visible and turns repeatable release hygiene into commands.
import { shipnode } from '@devalade/shipnode';
export default shipnode
.backend()
.ssh({ host: '203.0.113.10', user: 'deploy' })
.deployTo('/var/www/api')
.pm2('api', { instances: 2 })
.port(3000)
.domain('api.example.com')
.healthCheck('/health')
.nodeVersion('22')
.pkgManager('pnpm')
.build(); Library surface
The CLI is split into focused modules for validation, prompts, package managers, templates, database setup, users, releases, and commands. That keeps the tool small enough to inspect.
Timestamped directories and atomic symlink switching keep active traffic on the previous build until the new one is verified.
Configurable endpoint checks decide whether the release survives or rolls back automatically.
Generated configs can be ejected, edited, and kept across future deploys.
SSH, firewall, fail2ban, app users, and sudo policies can be managed from the same CLI surface.
Deploy production, staging, or a custom config, then generate GitHub Actions workflows when you are ready.
Optional PostgreSQL, MySQL, SQLite, and Redis provisioning prepares services on the target server.
Command map
ShipNode does not hide the server. It gives you memorable commands for the tasks that normally scatter across SSH sessions, copied snippets, and half-finished notes.
shipnode init Create shipnode.config.ts with framework-aware defaults shipnode setup Install Node.js, PM2, Caddy, and package managers shipnode doctor Run local and remote pre-flight diagnostics shipnode deploy Build, sync, release, health-check shipnode deploy --config shipnode.staging.config.ts Deploy a non-default environment shipnode rollback --steps 2 Move current back two releases shipnode unlock Clear a stale deploy lock shipnode status Inspect PM2 and release state shipnode logs Stream process logs shipnode metrics Open the PM2 monitoring dashboard shipnode restart Restart the application shipnode stop Stop the application shipnode run "<cmd>" Run a one-off command on the server shipnode env Upload local .env to the server shipnode config show Print the resolved configuration shipnode config validate Validate the configuration file shipnode eject Eject PM2/Caddy templates for customization shipnode harden Apply SSH, firewall, and fail2ban hardening shipnode doctor --security Run a security audit on the server shipnode user sync Sync .shipnode/users.yml to the server shipnode user list List non-system users on the server shipnode backup setup Install backup script and systemd timer shipnode backup run Run a backup immediately to S3 shipnode cloudflare init Provision a Cloudflare Tunnel for the app shipnode cloudflare status Show cloudflared and tunnel status shipnode ci github Generate a GitHub Actions deploy workflow shipnode ci env-sync Sync .env into GitHub repository secrets shipnode upgrade Upgrade shipnode to the latest version Detection matrix
ShipNode reads the local project, picks the right install/build/start commands, and lets config override the rare case where auto-detection is not enough.
Start shipping