GitLab CI/CD. Create simple pipeline

2 minute read

Today I want to show you how to build and run a simple web application with pipelines. I wrote an example Java application to demonstrate a possibility of CI. The application code is placed here.

For using it in GitLab just clone and add as new project. create-new-project java-project-info

About project

This is a typical and simple web application that shows a web page with “Hello world” when a user gets http://localhost:8081/ from browser. Firstly you should compile a project with Maven. In the result of it you have got a file hello.war. For running the app copy this war file into a webapps folder and run Tomcat WebServer.

Runner host preparing

It supposes you have configured a shell Runner and have installed Docker.

After that for allowing to manage docker containers by Runner you should add a gitlab-runner user into docker group.

usermod -a -G docker gitlab-runner

In addition I setup gitlab-runner as sudo user to run protected linux commands without user passwords. Just add a next row into a file with a command sudo visudo -f /etc/sudoers.d/gitlab-runner

gitlab-runner ALL=(ALL) NOPASSWD: ALL

In the end, enable a specific Runner to this project if you didn’t do that yet.

configure-stand-runner

Writing pipeline

In this project I want to use two stages to build and deploy an application.

hello-pipeline

The stage deploy has two jobs to deploy the app into a stand and production servers. Runners on these servers have tags prod-shell and stand-shell. The deploy to the production server requires a manual action. To build an app are used a docker maven container. The app is deploying with tomcat container.

Thus the next code will configure the defined pipeline. It requires to be inputted in .gitlab-ci.yml:

stages:
  - build
  - deploy

build_app:
  stage: build
  dependencies: []
  tags:
  - stand-shell
  script:
  - docker run -i --rm --name hello-maven -v ${PWD}:/hello -w /hello maven
      mvn clean install
  - cp target/hello.war hello.war
  - docker run -i --rm --name hello-maven -v ${PWD}:/hello -w /hello maven
      mvn clean
  artifacts:
    paths:
    - hello.war
    expire_in: 1 week

deploy:stand:
  stage: deploy
  dependencies:
  - build_app
  tags:
  - stand-shell
  script:
  - docker run -d --rm --name hello-tomcat-${CI_COMMIT_SHA:0:8} -P
      -v ${PWD}/hello.war:/usr/local/tomcat/webapps/hello.war   
      tomcat:9.0-jre8-alpine
  - docker ps -f "name=hello-tomcat-${CI_COMMIT_SHA:0:8}" --format '{{.Ports}}'

deploy:prod:
  stage: deploy
  when: manual
  dependencies:
  - build_app
  tags:
  - prod-shell
  script:
  - docker run -d --rm --name hello-tomcat-${CI_COMMIT_SHA:0:8} -P
      -v ${PWD}/hello.war:/usr/local/tomcat/webapps/hello.war   
      tomcat:9.0-jre8-alpine
  - docker ps -f "name=hello-tomcat-${CI_COMMIT_SHA:0:8}" --format '{{.Ports}}'

In the result we have an automation process that builds and deploy the web app. The app is deployed to stand host for test purposes after every commit into a repo.

hello-gitlab-pipelines

The result pipeline is:

java-project-info hello-gitlab-pipeline

The app can be accessed by IP and PORT. The PORT are dynamically generated and are showed in the deploy:stand job result:

hello-deploy-job-result

In my job output port is 32768. And the web app can be accessed by:

hello-result

With this configuration you have tried to use CI/CD process with GitLab. Don’t forget this simple pipeline doesn’t provide jobs to stop stands. You should are stopping unused docker containers yourself.

Next you can change it to your complex configuration for own purposes.

In the future I will explain how to use Ansible for CI/CD in the script block. It useful if you have a complex pipeline and you want write readable scripts.