GitShip is a lightweight alternative to n8n/Coolify focused only on GitHub-driven deployments.
Instead of configuring complex CI/CD platforms or UI tools, GitShip operates on a simple principle: Add a gitship.yml file, run gitship sync, and GitShip automatically configures webhooks, deployment targets, and deployment tracking.
This project targets Node.js v22. We use NVM (Node Version Manager) to easily manage and switch Node versions.
A .nvmrc file is provided in the project root. To get started:
- Install the correct Node version (if not already installed):
nvm install
- Switch to the project's Node version:
nvm use
- (Optional) Set Node 22 as your shell's default:
nvm alias default 22
You can also control the Node.js version used for executing deployment tasks per-project. Under the deploy block of your gitship.yml file, specify the optional node_version field:
deploy:
node_version: "20.11.0" # Target specific Node.js version for deployment commands
install: npm ci
build: npm run build
restart: pm2 restart allWhen node_version is specified:
- NVM Environment Wrapper: GitShip wraps
install,build, andrestartscripts to execute them under the specified Node.js version. - On-the-Fly Installation: If the specified version is not yet installed on the deployment runner (local machine or remote VPS target), GitShip runs
nvm install <version>automatically before execution. - NVM Discovery: GitShip detects NVM in common environment installations (including standard paths under
$HOME/.nvm,/usr/local/nvm, or Homebrew directories).
GitShip is designed as a modular Monorepo using NPM Workspaces:
graph TD
subgraph GitHub
GHRepo[GitHub Repository]
GHWebhook[GitHub Webhook]
end
subgraph Client Machine
CLI[GitShip CLI]
YML[gitship.yml]
end
subgraph Server Agent Host
Agent[gitship-agent]
Core[gitship-core]
DB[(gitship.json JSON)]
Builds[Build Folder]
Target[Deployment Target / SSH]
end
YML -->|Read/Parse| CLI
CLI -->|sync| GHWebhook
CLI -->|Sync Database & Projects| DB
GHRepo -->|Push Event| GHWebhook
GHWebhook -->|HMAC SHA256 POST /webhook/github| Agent
Agent -->|Verify Signature & Enqueue| Core
Core -->|Process Queue| Builds
Builds -->|Run install / build / restart| Target
Target -->|Update Steps & Log Stdout/Stderr| DB
CLI -->|Query runs & logs| DB
gitship-shared(packages/shared): Contains type definitions, schema validations via Zod, and YAML config reading/writing helper utilities.gitship-core(packages/core): The heart of the platform. Holds the JSON database repository operations, local storage configurations, GitHub webhook manager, execution engine (supporting local and remote SSH commands via Execa), and the FIFO deployment queue.gitship-agent(packages/server-agent): A standalone HTTP webhook server daemon (Express) that accepts push events from GitHub, verifies payload signatures using timing-safe HMAC SHA-256, and triggers core pipelines.gitship-cli(packages/cli): The command-line utility built with Commander.js, Inquirer, and Ora, offering an interactive initialization flow, stats tracker, real-time log tailing, and rollback utilities.
Yes, Webhook integration is fully supported and active!
When you run gitship sync:
- It reads your local
gitship.ymlfile and validates the schema. - It prompts you for your Server Agent's public URL if not already configured.
- It generates a secure, randomized signature secret (
sec_...) unique to the project. - Using the GitHub API via Octokit, it automatically registers (or updates) a webhook pointing to your Server Agent (
<agent_url>/webhook/github) subscribing only topushevents. - It saves the project settings and webhook credentials in the shared JSON database.
When GitHub fires a webhook:
- The Server Agent receives a
POSTrequest on/webhook/github. - It verifies the payload signature header (
x-hub-signature-256) against the project's secret using safe cryptographic comparisons (crypto.timingSafeEqual). - If valid, the agent extracts the branch, commit hash, author, and commit message, then schedules the deployment in the FIFO queue database.
The local configuration, authorization files, and JSON database file (gitship.json) are stored in ~/.gitship/ (which can be overridden for testing via GITSHIP_DIR environment variables).
projects: Configured repository detail metadata and webhook secrets.webhooks: GitHub webhook configuration identifiers and endpoints.deployments: Current status (QUEUED,RUNNING,SUCCESS,FAILED,CANCELLED), commit, and duration metrics.deployment_steps: Timings and status for individual steps (clone,install,build,restart).deployment_logs: Full stdout/stderr execution output of each deployment.
gitship auth github: Authenticate using a Browser OAuth Redirect or a Personal Access Token.gitship init: Detect project type (Node, Docker, Cloudflare, Vercel, PM2) and generate agitship.yml.gitship sync: Sync config with the database, generate signature secret, and register GitHub webhook.gitship check: Check if the local config, database registration, and remote GitHub webhook are active and valid.gitship runs: List recent deployment runs.gitship logs <id> [-f]: Print stdout/stderr logs of a run (with real-time tailing via--follow).gitship stats: Check totals, success rate, average times, and quickest/slowest builds.gitship rollback <id>: Queue a rollback deployment checking out the original commit.gitship queue: Inspect currently active or queued deployment pipelines.gitship cancel <id>: Cancel a queued run or terminate an active execa build process.gitship project inspect <name>: Inspect project details, webhook configurations, and recent run history.gitship repos: List all repositories in the connected GitHub account.
Isolated tests verify configurations, YAML validations, database repositories, and cascades.
npm testnpm run coverageCurrently, tests achieve 100% statement and line coverage on configuration paths and helper systems, and test the major database interactions.
When deploying GitShip onto a Virtual Private Server (VPS), consider the following guidelines:
- Server Agent (Webhooks): You can use a raw IP address (e.g.,
http://192.0.2.1:3000) for your Server Agent. GitHub webhooks work perfectly with IP addresses. - SSL/HTTPS: If you want secure, encrypted webhooks (using
https://), you should configure a domain name for your VPS (e.g.agent.mydomain.com) and configure an SSL certificate (e.g. via Let's Encrypt / Certbot with Nginx).
When running gitship auth github to authenticate the CLI:
- On Local Machine: Standard Browser Redirect OAuth is recommended, using
http://localhost:4567as the GitHub OAuth App callback. - Directly on the VPS (over SSH):
- Option A (Personal Access Token): Select the Personal Access Token (Manual) authentication choice. This is the simplest option when running directly on a remote server as it doesn't require browser redirections.
- Option B (SSH Port Forwarding): If you still want to use Browser OAuth, you can connect to your VPS with SSH port forwarding:
ssh -L 4567:localhost:4567 user@your-vps-ip Then, running `gitship auth github` on the VPS will forward the authentication code back to your local browser successfully.
To keep the webhook Server Agent running continuously in the background on your VPS, you can use PM2:
-
Option A: Running via the global CLI command If you have installed the CLI globally, you can start the agent directly (default port is 3000):
pm2 start "gitship agent" --name "gitship-agent" # Or running on a custom port (e.g. 8080) pm2 start "gitship agent --port 8080" --name "gitship-agent"
-
Option B: Running the package directly Alternatively, you can run the agent node process directly from the package directory:
pm2 start packages/server-agent/dist/server.js --name "gitship-agent" # Or running on a custom port (e.g. 8080) PORT=8080 pm2 start packages/server-agent/dist/server.js --name "gitship-agent"
To inspect logs, monitor status, or configure PM2 to start on system boot:
pm2 logs gitship-agent
pm2 status
pm2 startup
pm2 saveTo run security audits across all workspace packages and their dependencies:
npm run auditTo bump the version of all workspace packages at once (e.g. patch, minor, major):
npm run change patchTo build all packages and publish them to the public npm registry:
npm run publish