What is CI/CD?
CI/CD is the practice of letting a machine do the boring, risky parts of shipping software: building your code, running your tests, and deploying it to a server. Instead of a human running commands by hand every time, a tool watches your git repository and runs an automated recipe the moment you push a change. The payoff is fast, honest feedback (you learn within minutes whether your change is broken) and the confidence to deploy many times a day instead of once a quarter. This page is your anchor for the whole CI/CD section, so we will define every term carefully and show you exactly what a pipeline does.
The manual-deploy pain CI/CD removes
Before CI/CD, deploying looked like this. An engineer SSHs (connects over a secure shell) into the server, pulls the latest code, runs the build, copies files around, restarts the service, and crosses their fingers. Here is the kind of thing they typed by hand, every single release:
ssh [email protected]
cd /var/www/myapp
git pull origin main
npm ci
npm run build
sudo systemctl restart myapp
This works until it doesn’t. Someone forgets the npm ci step. Someone deploys from their laptop with uncommitted changes. Someone skips the tests “just this once” because it’s Friday. The result is the classic line “but it works on my machine” — the code behaves differently on the server because the steps were not identical every time.
CI stands for Continuous Integration: every time anyone pushes code, a server automatically merges it with everyone else’s work, builds it, and runs the tests. CD stands for Continuous Delivery (the build is always kept ready to ship at the press of a button) or Continuous Deployment (every passing build ships to production with no button at all). Together, CI/CD replaces that fragile manual ritual with one automated, repeatable recipe that runs the same way for everyone, every time.
What is a pipeline?
A pipeline is that automated recipe. It is a series of ordered stages (groups of steps) that your code flows through, like an assembly line in a factory. Each stage must pass before the next one starts. A typical pipeline looks like this:
push code → [ Build ] → [ Test ] → [ Package ] → [ Deploy ]
│ │ │ │
compile run unit build a push to
the code and lint Docker image the server
If the Test stage fails, the pipeline stops and nobody can deploy a broken build. That single guarantee is what makes teams comfortable shipping ten times a day.
The pipeline is defined as a file in your repository — usually YAML (a simple text format for configuration, short for “YAML Ain’t Markup Language”). Because the pipeline lives in git next to your code, it is versioned, reviewed in pull requests, and identical for every developer. There is no secret deploy knowledge living only in one senior engineer’s head.
Gotcha: A pipeline is only as honest as its tests. If your CI runs no tests, it is just an automated way to ship bugs faster. Always make a failing test fail the pipeline, never let it print a warning and continue.
The fast-feedback payoff
The real prize of CI/CD is fast feedback. The longer you wait to find a bug, the more expensive it is to fix, because you have forgotten the context and built more code on top of it. CI runs within minutes of your push and tells you immediately if you broke something.
| Without CI/CD | With CI/CD |
|---|---|
| Bugs found days later in manual QA | Bugs found minutes after the push |
| Deploys are scary, rare events | Deploys are boring and frequent |
| ”Works on my machine” arguments | Identical environment for everyone |
| One person knows the deploy steps | Steps are code, anyone can read them |
| Tests skipped under pressure | Tests are mandatory and automatic |
When to use CI/CD (and when not)
Use it for basically every project with more than one developer or more than one deploy. Even a solo side project benefits from automated tests catching mistakes before they reach users.
When it is overkill: a one-off script you run once on your laptop, or a throwaway prototype that will never be deployed. Setting up a pipeline for a 20-line experiment is wasted effort. The moment that experiment becomes something real that other people depend on, add CI/CD.
The tools this section covers
There are many CI/CD tools, but they all share the same pipeline idea. We focus on the three you are most likely to meet on a real Ubuntu server in 2026:
| Tool | What it is | When to reach for it |
|---|---|---|
| GitHub Actions | CI/CD built into GitHub, pipelines as YAML in .github/workflows/ | Your code is already on GitHub — the easiest, most popular starting point |
| GitLab CI | CI/CD built into GitLab, defined in .gitlab-ci.yml | You host on GitLab, or want a single platform for git + CI + registry |
| Jenkins | A self-hosted CI server you install on your own machine | Full control, on-premise networks, or complex legacy pipelines |
GitHub Actions and GitLab CI are hosted: the provider runs the build machines for you. Jenkins is self-hosted: you install it on your own Ubuntu server with apt, and you manage and update it yourself. Self-hosting means more control and no per-minute billing, but you become responsible for keeping that server patched and online.
Across this section you will build real pipelines: running tests in CI, building Docker images, storing the results as artifacts (the files a build produces, like a .jar or a Docker image), managing secrets safely, and deploying to a live server — first with GitHub Actions, then Jenkins and GitLab.
Best Practices
- Define your pipeline as a file committed to git, never as clicks in a web UI that no one can review.
- Make tests mandatory — a failing test must stop the pipeline and block the merge, not just warn.
- Keep pipelines fast (under about 10 minutes) so feedback stays useful; slow pipelines get ignored or bypassed.
- Never hardcode passwords or API keys in pipeline files; use the tool’s encrypted secrets store.
- Build your artifact once and promote that exact same artifact through staging to production — never rebuild per environment.
- Start simple with one Build and one Test stage, then add Deploy once the basics are green and trusted.