A Simple GitLab CI Example
Tags: gitlab, docker
Published: 2017-12-12 15:12:32

---
title: "A Simple GitLab CI Example"
published: true
description: "Using Docker image in GitLab CI pipeline."
tags: [GitLab, Docker]
---

Originally posted on [Boatswain Blog](https://blog.boatswain.io/post/a-simple-gitlab-ci-example/).

---

![A Simple GitLab CI Example](https://thepracticaldev.s3.amazonaws.com/i/qwwlp4a5dpas0083qrp1.png)


In the past, we have tried different tools for managing our projects in order to keep them in good conditions. What we need are:

- Version control
- Issue tracker
- Documentation
- Continuous integration
- Continuous delivery
- Repository (artifacts/docker images)

Tools like [Jenkins][jenkins] which is good for continuous integration and delivery, [Mantis][mantis] could help tracking issues. But to improve the project efficiency and quality, it is good to bring those tools together. For example, we would like to have the git commit hook up with the issues, or to trigger an automated test after pushing commits to the master branch. Usually, most tools have already provided integration with other services but still it is trouble to configure them. Moreover, the workflow would be broken if any one of the service goes down. So it would be great if there is a single platform which could fulfil all these desires and that's why we pick [GitLab][gitlab.com].

## GitLab CI

[GitLab.com][gitlab.com] is a SAAS service where you could host your Git repository, track the issues and write the wiki in markdown. They are intuitive features so just register an account and you could try them out. On the other hand, [GitLab CI][gitlab-ci] allows us to setup continuous integration and we could even utilize any **Docker image** available on [Docker Hub][docker-hub] to implement them. Let's take a look in the following example.

### The .gitlab-ci.yml

This yml contains the definition all the stages after a CI/CD pipeline is triggered in response to a git push/merge. In this example, we have a simple nodejs project and we would like to make sure the code is good by linting and unit-test. Fork this [repository][gitlab-ci-demo] and check it out.

```yaml
stages:
  - lint-css
  - lint-js
  - unit-test

image: node:6.11.2


lint css:
  stage: lint-css
  before_script:
    - npm install
  cache:
    untracked: true
  only:
    - master
  script:
    - ./node_modules/gulp/bin/gulp.js lint-css

lint js:
  stage: lint-js
  cache:
    untracked: true
    policy: pull
  only:
    - master
  script:
    - ./node_modules/gulp/bin/gulp.js lint-js

run unit test:
  stage: unit-test
  cache:
    untracked: true
    policy: pull
  only:
    - master
  script:
    - ./node_modules/gulp/bin/gulp.js test
```

We defined 3 stages, each stage actually is just a gulp task defined in the _gulpfile.js_. Anyone could run the task locally as long as the have a proper nodejs installed. But in [GitLab CI][gitlab-ci], we only need to tell which **Docker image** is needed. In our case, that is _node:6.11.2_. Furthermore, this image attribute could be defined within the stage definition such that you could use different tool for each stage.

#### More details on the stage definition

Let's take a deeper look in the stage definition.

```yaml
lint css:
  stage: lint-css     # <- Should map to the value defined in the 'stages'
  before_script:      # <- Pre-script
    - npm install
  cache:              # <- Enable caching on files so they are available in the next stage
    untracked: true   # <- Cache the git untracked files (ex. node_modules)
  only:
    - master          # <- This stage run only on master branch update
  script:             # <- The actually script of this stage
    - ./node_modules/gulp/bin/gulp.js lint-css
```

Both the values of *before_script* and _script_ could be multiple (array in .yml). And if the _script_ execution has error, this stage will be classified as failed.

### Trigger the pipeline

Just make some changes on the master branch and could find the pipeline running on the **CI / CD -> Pipeline page**.

![The pipeline history](https://thepracticaldev.s3.amazonaws.com/i/o8m5x67wzkra899h42gx.jpg)

#### View the stage in detail

Click the pipeline and you could read the console output of each stage. Useful when the stage/job fails.

![The stage output](https://thepracticaldev.s3.amazonaws.com/i/5k52m2sry9j2kgmgcutp.jpg)

## The benefits of using GitLab CI with Docker

Different projects needs different tools such as nodejs, ant, maven... etc and in the past when using tool like [Jenkins][jenkins] i have to make sure all of them are installed on the server. By using [Docker][docker], the developers could pick whatever tools available on [Docker Hub][docker-hub] without asking the server admin to setup such tools on the server. Actually Jenkins also has a pipeline plugin and it could work with Docker to serve exactly the same purpose. But extra effort on integrating Jenkins with the version control is needed and as i mentioned before.

Although i prefer using [GitLab CI][gitlab-ci], it doesn't mean it could completely replace [Jenkins][jenkins]. [Jenkins][jenkins] offers configurable user interface which is convenient for non-developers such as QA to execute certain tasks like deployments and integration test.

## Pick the suitable one but not the perfect one

The key is not about the tool itself, instead it is more about the people who use it. So before start searching for a new tool, try to identify the problem which you would like to solve first.





[jenkins]: https://jenkins.io/
[mantis]: https://www.mantisbt.org/
[gitlab.com]: https://gitlab.com
[docker-hub]: https://hub.docker.com/
[gitlab-ci]: https://about.gitlab.com/features/gitlab-ci-cd/
[gitlab-ci-demo]: https://gitlab.com/ykyuen/gitlab-ci-demo
[docker]: https://www.docker.com/