Nexus & GitLab CI Integration | A How-To Guide | Sonatype

How to Use GitLab-CI With Sonatype Nexus Repository

August 14, 2019
By Sudipt Sharma

7 minute read time

Recently, I was asked to set up a continuous integration (CI) pipeline for a Spring-based application.

I said "piece of cake," as I have already worked on Jenkins Pipeline and knew about Maven, so that won't be a problem. But there was a hitch: " pipeline of GitLab CI". I said " no problem, I'll learn about it" with a Ninja Spirit.

So, for starters what is GitLab-CI pipeline?

For those who have already worked on Jenkins and Maven, they know about the CI workflow of building code, testing the code, packaging, and deploying it using Maven. You can add other goals too, depending upon the requirement.

The CI process in GitLab CI is defined within a file in the code repository itself using a YAML configuration syntax.

The work is then dispatched to machines called runners, which are easy to set up and can be provisioned on many operating systems. When configuring runners, you can choose between different executors like Docker shell, VirtualBox, or Kubernetes to determine how the tasks are carried out.

What Are We Going to Do?

We will be establishing a CI/CD pipeline using gitlab-ci and deploying artifacts to Sonatype Nexus Repository.

Resources used:

  1. Gitlab server - I'm using GitLab to host my code.
  2. Runner server - It could be vagrant or an ec2 instance.
  3. Sonatype Nexus Server - It could be vagrant or an ec2 instance.

Before going further, here are a few terminologies:

Strategy to Setup Pipeline

Step 1: Setting Up GitLab Repository

I'm using a Spring-based code Spring3Hibernate, with a directory structure like below.

$ cd spring3hibernateapp
$ ls
pom.xml pom.xml~ src

Now let's start pushing this code to GitLab

$ git remote -v
origin git@gitlab.com:<your_gitlab_id>/spring3hibernateapp.git (fetch)
origin git@gitlab.com:<your_gitlab_id>/spring3hibernateapp.git (push)

Adding the code to the working directory

$ git add -A

Committing the code

$ git commit -m "[Master][Add] Adding the code "

Pushing it to gitlab

$ git push origin master

Step 2: Install GitLab Runner Manually on GNU/Linux

Simply download one of the binaries for your system:

$ sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-386

Give it permissions to execute:

$ sudo chmod +x /usr/local/bin/gitlab-runner

Optionally, if you want to use Docker, install Docker with:

$ curl -sSL https://get.docker.com/ | sh

Create a GitLab CI user:

$ sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash

Install and run as service:

$ sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
$ sudo gitlab-runner start

Step 3: Registering a Runner

To get the runner configuration, you need to move to gitlab > spring3hibernateapp > CI/CD setting > Runners

And get the registration token for runners.

Run the following command:

$ sudo gitlab-runner register
   Runtime platform arch=amd64 os=linux pid=1742 revision=3afdaba6 version=11.5.0
   Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/)::)

https://gitlab.com/

Please enter the gitlab-ci token for this runner:

****8kmMfx_RMr****

Please enter the gitlab-ci description for this runner:

[gitlab-runner]: spring3hibernate

Please enter the gitlab-ci tags for this runner (comma separated):

build

Registering runner... succeeded runner=ZP3TrPCd

Please enter the executor:

docker, docker-ssh, shell, ssh, virtualbox, docker+machine, parallels, docker-ssh+machine, kubernetes:docker

Please enter the default Docker image (e.g. ruby:2.1):

maven

Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

You can also create systemd service in /etc/systemd/system/gitlab-runner.service.

[Unit]
Description=GitLab Runner
After=syslog.target network.target
ConditionFileIsExecutable=/usr/local/bin/gitlab-runner
[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/usr/local/bin/gitlab-runner "run" "--working-directory" "/home/gitlab-runner" "--config" "/etc/gitlab-runner/config.toml" "--service" "gitlab-runner" "--syslog" "--user" "gitlab-runner"
Restart=always
RestartSec=120

[Install]
WantedBy=multi-user.target

Step 4: Setting Up Sonatype Nexus Repository

You can setup a repository installing the open source version of Nexus. You need to visit Nexus OSS and download the TGZ version or the ZIP version.

But to keep it simple, I used docker container for that.

Install docker

$ curl -sSL https://get.docker.com/ | sh

Launch a Nexus container and bind the port

$ docker run -d -p 8081:8081 --name nexus sonatype/nexus:oss
You can access your nexus now on http://<public-ip>:8081/nexus.
And login as admin with password admin123.

Editor's Note: Sonatype Nexus Repository uses a one-time password the first time you boot it. Once the user interface has told you where to find the one-time password file, use the 'docker cp' command to extract it from your docker container.

Step 5: Configure the Sonatype Nexus Repository Deployment

Clone your code and enter the repository

$ cd spring3hibernateapp/

Create a folder called .m2 in the root of your repository

$ mkdir .m2

Create a file called settings.xml in the .m2 folder

$    touch .m2/settings.xml

Copy the following content in settings.xml

<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"
    xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <servers>
    <server>
      <id>central</id>
      <username>${env.Nexus_REPO_USER}</username>
      <password>${env.Nexus_REPO_PASS}</password>
    </server>
    <server>
      <id>snapshots</id>
      <username>${env.Nexus_REPO_USER}</username>
      <password>${env.Nexus_REPO_PASS}</password>
    </server>
  </servers>
</settings>

Username and password will be replaced by the correct values using variables.

Updating Repository path in pom.xml

<repository>
     <id>central</id>
     <name>Central</name>
     <url>${env.Nexus_REPO_URL}central/</url>
   </repository>
 <snapshotRepository>
          <id>snapshots</id>
          <name>Snapshots</name>
          <url>${env.Nexus_REPO_URL}snapshots/</url>
        </snapshotRepository>

Step 6: Configure GitLab CI/CD for Simple Maven Deployment

GitLab CI/CD uses a file in the root of the repo, named, .gitlab-ci.yml, to read the definitions for jobs that will be executed by the configured GitLab Runners.

First of all, remember to set up variables for your deployment. Navigate to your project's Settings > CI/CD > Variables page and add the following ones (replace them with your current values, of course):

Now it's time to define jobs in .gitlab-ci.yml and push it to the repo:

image: maven

variables:
   MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
   MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
   - .m2/repository/
   - target/

stages:
   - build
   - test
   - package
   - deploy
codebuild:
tags:
   - build
stage: build
script:
   - mvn compile
codetest:
tags:
   - build
stage: test
script:
   - mvn $MAVEN_CLI_OPTS test
   - echo "The code has been tested"
Codepackage:
tags:
   - build
stage: package
script:
   - mvn $MAVEN_CLI_OPTS package -Dmaven.test.skip=true
   - echo "Packaging the code"
artifacts:
   paths:
      - target/*.war
only:
   - master
Codedeploy:
tags:
   - build
stage: deploy
script:
   - mvn $MAVEN_CLI_OPTS deploy -Dmaven.test.skip=true
   - echo "installing the package in local repository"
only:
   - master

Now add the changes, commit them and push them to the remote repository on GitLab. A pipeline will be triggered with respect to your commit. And if everything goes well our mission will be accomplished.

Note: You might get some issues with Maven plugins, which will need to be managed in pom.xml, depending upon the environment.

Written by Sudipt Sharma

Devops Engineer at OpsTree Solutions

Tags

ProductGuest PostGitLabSonatype Nexus RepositorySonatype Nexus Repository OSS