info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
comments: false
type: index, howto
---
# Migrating from Jenkins
A lot of GitLab users have successfully migrated to GitLab CI/CD from Jenkins. To make this
easier if you're just getting started, we've collected several resources here that you might find useful
before diving in. Think of this page as a "GitLab CI/CD for Jenkins Users" guide.
The following list of recommended steps was created after observing organizations
that were able to quickly complete this migration:
1. Start by reading the GitLab CI/CD [Quick Start Guide](../quick_start/README.md) and [important product differences](#important-product-differences).
1. Learn the importance of [managing the organizational transition](#managing-the-organizational-transition).
1. Educate and enable your developers to independently perform the following steps in their projects:
1. Review the [Quick Start Guide](../quick_start/README.md) and [Pipeline Configuration Reference](../yaml/README.md).
1. Use the [Jenkins Wrapper](#jenkinsfile-wrapper) to temporarily maintain fragile Jenkins jobs.
1. Migrate the build and CI jobs and configure them to show results directly in your merge requests. They can use [Auto DevOps](../../topics/autodevops/index.md) as a starting point, and [customize](../../topics/autodevops/customize.md) or [decompose](../../topics/autodevops/customize.md#using-components-of-auto-devops) the configuration as needed.
1. Add [Review Apps](../review_apps/index.md).
1. Migrate the deployment jobs using [cloud deployment templates](../cloud_deployment/index.md), adding [environments](../environments/index.md), and [deploy boards](../..//user/project/deploy_boards.md).
1. Work to unwrap any jobs still running with the use of the Jenkins wrapper.
1. Take stock of any common CI/CD job definitions then create and share [templates](#templates) for them.
For an example of how to convert a Jenkins pipeline into a GitLab CI/CD pipeline,
or how to use Auto DevOps to test your code automatically, watch the
[Migrating from Jenkins to GitLab](https://www.youtube.com/watch?v=RlEVGOpYF5Y) video.
Otherwise, read on for important information that will help you get the ball rolling. Welcome
to GitLab!
If you have questions that are not answered here, the [GitLab community forum](https://forum.gitlab.com/)
can be a great resource.
## Managing the organizational transition
An important part of transitioning from Jenkins to GitLab is the cultural and organizational
changes that comes with the move, and successfully managing them. There are a few
things we have found that helps this:
- Setting and communicating a clear vision of what your migration goals are helps
your users understand why the effort is worth it. The value will be clear when
the work is done, but people need to be aware while it's in progress too.
- Sponsorship and alignment from the relevant leadership team helps with the point above.
- Spending time educating your users on what's different, sharing this document with them,
and so on will help ensure you are successful.
- Finding ways to sequence or delay parts of the migration can help a lot, but you
don't want to leave things in a non-migrated (or partially-migrated) state for too
long. To gain all the benefits of GitLab, moving your existing Jenkins setup over
as-is, including any current problems, will not be enough. You need to take advantage
of the improvements that GitLab offers, and this requires (eventually) updating
your implementation as part of the transition.
## JenkinsFile Wrapper
We are building a [JenkinsFile Wrapper](https://gitlab.com/gitlab-org/jfr-container-builder/) which will allow
you to run a complete Jenkins instance inside of a GitLab job, including plugins. This can help ease the process
of transition, by letting you delay the migration of less urgent pipelines for a period of time.
If you are interested in helping GitLab test the wrapper, join our [public testing issue](https://gitlab.com/gitlab-org/gitlab/-/issues/215675) for instructions and to provide your feedback.
## Important product differences
There are some high level differences between the products worth mentioning:
- With GitLab you don't need a root `pipeline` keyword to wrap everything.
- The way pipelines are triggered and [trigger other pipelines](../yaml/README.md#trigger)
is different than Jenkins. GitLab pipelines can be triggered:
- on push
- on [schedule](../pipelines/schedules.md)
- from the [GitLab UI](../pipelines/index.md#run-a-pipeline-manually)
- by [API call](../triggers/README.md)
- by [webhook](../triggers/README.md#triggering-a-pipeline-from-a-webhook)
- by [ChatOps](../chatops/README.md)
- You can control which jobs run in which cases, depending on how they are triggered,
with the [`rules` syntax](../yaml/README.md#rules).
- GitLab [pipeline scheduling concepts](../pipelines/schedules.md) are also different than with Jenkins.
- You can reuse pipeline configurations using the [`include` keyword](../yaml/README.md#include)
and [templates](#templates). Your templates can be kept in a central repository (with different
permissions), and then any project can use them. This central project could also
contain scripts or other reusable code.
- You can also use the [`extends` keyword](../yaml/README.md#extends) to reuse configuration
within a single pipeline configuration.
- All jobs within a single stage always run in parallel, and all stages run in sequence. We are planning
to allow certain jobs to break this sequencing as needed with our [directed acyclic graph](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063)
feature.
- The [`parallel`](../yaml/README.md#parallel) keyword can automatically parallelize tasks,
like tests that support parallelization.
- Normally all jobs within a single stage run in parallel, and all stages run in sequence.
There are different [pipeline architectures](../pipelines/pipeline_architectures.md)
that allow you to change this behavior.
- The new [`rules` syntax](../yaml/README.md#rules) is the recommended method of
controlling when different jobs run. It is more powerful than the `only/except` syntax.
- One important difference is that jobs run independently of each other and have a
fresh environment in each job. Passing artifacts between jobs is controlled using the
[`artifacts`](../yaml/README.md#artifacts) and [`dependencies`](../yaml/README.md#dependencies)
keywords. When finished, the planned [Workspaces](https://gitlab.com/gitlab-org/gitlab/-/issues/29265)
feature will allow you to more easily persist a common workspace between serial jobs.
- The `.gitlab-ci.yml` file is checked in to the root of your repository, much like a Jenkinsfile, but
is in the YAML format (see [complete reference](../yaml/README.md)) instead of a Groovy DSL. It's most
analogous to the declarative Jenkinsfile format.
- Manual approvals or gates can be set up as [`when:manual` jobs](../yaml/README.md#whenmanual). These can
- GitLab comes with a [container registry](../../user/packages/container_registry/index.md), and we recommend using
container images to set up your build environment. For example, set up one pipeline that builds your build environment
itself and publish that to the container registry. Then, have your pipelines use this instead of each building their
own environment, which will be slower and may be less consistent. We have extensive docs on [how to use the Container Registry](../../user/packages/container_registry/index.md).
- A central utilities repository can be a great place to put assorted scheduled jobs
or other manual jobs that function like utilities. Jenkins installations tend to
- Runners can be set up as [shared across an instance, be added at the group level, or set up at the project level](../runners/README.md#types-of-runners).
They will self-select jobs from the scopes you've defined automatically.
- You can also [use tags](../runners/README.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) for finer control, and
associate runners with specific jobs. For example, you can use a tag for jobs that
require dedicated, more powerful, or specific hardware.
to provide this capability. You can configure your own runners in Kubernetes or on any host, or take advantage
of our shared runner fleet (note that the shared runner fleet is only available for GitLab.com users.) The link above will bring you to the documentation which will describe how to get
up and running quickly. We also support using [tags](../runners/README.md#use-tags-to-limit-the-number-of-jobs-using-the-runner) to direct different jobs