How-To Guide · GitLab CI/CD

How to Set Up a GitLab CI/CD Pipeline — Step by Step

A GitLab pipeline is defined by a single file called `.gitlab-ci.yml` in the root of your repository. Commit that file and GitLab starts running pipelines on every push — there is no separate service to enable. This guide takes you from an empty repository to a working build-test-deploy pipeline with caching, artefacts and a manual production gate, then covers the two things that decide whether the pipeline stays useful: keeping it under ten minutes, and keeping compute-minute consumption off your invoice.

Steps

Frequently Asked Questions

Do I need to enable anything to use GitLab CI/CD?

No. CI/CD is built into GitLab on every tier including Free — committing a `.gitlab-ci.yml` file to the repository root is the entire activation step. The only prerequisite is a runner to execute jobs on. GitLab.com provides shared hosted runners immediately, metered as compute minutes. A Self-Managed instance ships with no shared runners, so you register your own with `gitlab-runner register` before the first pipeline can run.

Why is my pipeline stuck as "pending"?

Almost always no runner is available that matches the job. Check Settings → CI/CD → Runners: either no runner is assigned to the project, or the job carries `tags:` that no available runner has. On GitLab.com Free, also check whether you have exhausted your 400 monthly compute minutes — jobs queue rather than fail when the allowance runs out. On Self-Managed, confirm the runner service is actually running on its host.

How do I keep compute minutes under control?

Three things, in order of impact. Register self-hosted runners — they consume zero compute minutes on every tier, so a small always-on VM often costs less than the metered equivalent. Use `rules:` so jobs only run when they are relevant, rather than everything on every push. And cache dependencies properly so each job is not spending minutes re-downloading a package tree. Top-ups are 0 per 1,000 minutes if you still need them.

What is the difference between cache and artifacts?

Cache is for things you could rebuild but would rather not — dependency directories like `node_modules` — persisted between pipeline runs to save time. Artifacts are for output you need to keep or pass forward: compiled binaries, packages, test reports. Artifacts move between stages within a pipeline and are downloadable afterwards; cache is a speed optimisation and should never be relied on for correctness. Mixing them up is the most common `.gitlab-ci.yml` mistake.

Can I run security scanning in a GitLab pipeline for free?

Partly. Static Application Security Testing and secret detection are available on GitLab Free — include the relevant templates with `include: template:` and they run as ordinary jobs. What is not on Free is the rest of the suite: DAST, fuzz testing, Software Composition Analysis and IaC scanning are Ultimate features, as are the vulnerability management workflow and security dashboards that turn scan output into something an auditor will accept.

Should the production deploy be automatic?

For most teams, no — at least not at first. `when: manual` on the production job gives you the full benefit of continuous delivery (everything is built, tested and ready to ship) while keeping a human decision on release timing, which matters if you have customer communications, maintenance windows, or compliance sign-off. Automatic production deploys make sense once you have strong test coverage, feature flags, and monitoring that will catch a bad release quickly.