Husky vs Jenkins vs Ansible: When to Use Which for CI/CD?

In this guide, we will cover everything you need to know about choosing between Husky, Jenkins and Ansible for a Laravel CI/CD pipeline — and why the real answer is a layered setup, not a single winner.
I recently built the full pipeline for a production Laravel 12 + React (Inertia) multi-tenant SaaS running on a single Ubuntu VPS. This series documents that build step by step, including everything that broke along the way. But before touching a terminal, we had to answer the question every team hits: which tool?
The trap: these are not competing tools
The comparison is a category error, and understanding why is the whole decision:
| Tool | Where it runs | What it's for | When it fires |
|---|---|---|---|
| Husky | Developer's machine | Git-hook checks (lint, quick tests) | Before commit / push |
| Jenkins | Your server | Pipelines: test → build → deploy | After push |
| Ansible | Your machine → many servers | Server configuration management | When you provision servers |
Husky cannot deploy. Jenkins cannot stop a bad commit from being created. Ansible does neither — it makes servers identical.
The layered architecture we chose
Developer Mac
├─ pre-commit (Husky): Laravel Pint on staged files only → ~1s
├─ pre-push (Husky): JS test suite + pint --test → ~5s
▼ git push
Jenkins on the VPS
├─ Lint → PHP tests (full suite) → Vite build → JS tests
├─ Package artifact → deploy to STAGING → smoke test
├─ Manual approval gate
└─ Deploy to PRODUCTION → health check → auto-rollback on failure
Two principles drive this:
- Fast checks live locally, slow checks live on the server. A pre-commit hook that takes 30 seconds gets bypassed with
--no-verifywithin a week — I've watched it happen on every team. Pint on staged files takes about a second; the full PHPUnit suite (340+ tests against MySQL) belongs in Jenkins where nobody is waiting with their fingers on the keyboard. - The server is the source of truth. Husky is a courtesy that keeps embarrassing commits out of history. Jenkins is the enforcement layer — it runs the suite you can't skip.
Why Jenkins over GitHub Actions?
Fair question, and for many teams Actions is the right call. We picked Jenkins because:
- The VPS had spare capacity (31 GB RAM) — self-hosted CI costs nothing extra, and there are no per-minute charges for a 340-test suite that runs on every push.
- The deploy target is the CI machine. No SSH-from-cloud-runner complexity, no secrets leaving the box.
- Existing Jenkins experience on the team. The best tool is frequently the one you already know how to debug at 1 a.m.
Why we skipped Ansible
One VPS. Ansible's payoff is "make 10 servers identical" — with a single server, a version-controlled runbook (every command we ran, committed to the repo in docs/) gives the reproducibility without the abstraction tax. If we grow to multiple app servers, that runbook becomes the Ansible playbook spec.
Decision rule you can steal: Husky always (it's a 10-minute setup, post #2). Jenkins or Actions for CI — Jenkins if you own idle hardware, Actions if you don't. Ansible only at 3+ servers.
What's next in the series
Post #2 sets up Husky properly for a Laravel + React repo — including the trick that runs Pint only on staged files and re-stages the fixes automatically, and why the full PHP suite deliberately stays out of the hooks.
This series documents a real production build. The domains and IPs are anonymised; the mistakes are not.
Frequently Asked Questions
Is Husky a replacement for Jenkins?
Do I need Ansible for a single VPS?
Senior Full Stack Developer · Building SaaS products & teaching Laravel/React · 10+ years experience · Founder of Orion360 · Based in Dubai, UAE.
Was this post helpful?



