All work
2026Learning build · open-source baseDevOps

Wanderlust DevSecOps

A self-hosted CI/CD pipeline with code-quality gates, vulnerability scans and Docker deploys for a three-tier MERN app, all on one Ubuntu host.

Started from an open-source reference pipeline. Everything below is what I set up, broke and fixed.

pipeline stages
failures fixed
services, one host

The pipeline

  1. Checkout
  2. Install
  3. Code qualitySonarQube
  4. Filesystem scanTrivy
  5. BuildDocker
  6. Image scanTrivy
  7. PushDocker Hub
  8. DeploySSH + Compose

The problem

Reading about CI/CD is easy; running one is where it breaks. The goal was a pipeline where a change reaches a running container with no manual step, and fails on its own if quality or image security regresses.

What I built

Brought up Jenkins (master and SSH agent), SonarQube and PostgreSQL on one host, wired every secret through the Jenkins credentials store, set up a SonarQube quality gate, and verified the whole loop from commit to running containers.

What broke, and how I fixed it

  1. Deploys worked once, then failed: the SSH key lived inside an ephemeral agent container. I moved it to the Jenkins credentials store and inject it per build, so the agent stays stateless.
  2. SonarQube broke after every restart because of hard-coded container IPs. I switched to service names on a user-defined Docker network.
  3. Jenkins couldn't reach the Docker daemon. Socket access fixes it for a lab, and I documented why it isn't production-safe (rootless Docker or Kaniko instead).

Result

Images land on Docker Hub with build tags, analysis shows up in SonarQube, Trivy reports are archived on each build, and the app runs on the host.

Trade-offs

Polling instead of webhooks: Jenkins runs on a local machine that GitHub can't reach, so it checks for new commits on a timer. Slower, but it works without exposing the machine to the internet.

Stack
JenkinsDockerSonarQubeTrivyPostgreSQLNode.jsReactMongoDB