Automate spring boot deployment using gitlab CI

gitlab-ci

Hi there,

Let’s talk about deployment of our java app. I’ve previously talked about how you can deploy your java app in the cloud.

But it’s not the best idea to leave our app running like this. If somehow it got killed or server is restarted, we will need to manually start our server. And that’s not the way to go.

So let’s create a service that will automatically start our app is it’s stopped for some reason.

Oh wait!! We’ve another big problem that we need to resolve. Let’s talk about the problem of manually doing things to deploy our app in the cloud.

To deploy our app we generally do it by few steps.

  1. Package our app
  2. Copy .jar deployment file in our server using scp or some other method.
  3. Run using nohup java -jar app.jar &(here nohup and & for running on the background)

Let’s automate the process using Gitlab CI. Our strategy is, if a commit is merged on masterbranch, we’ll automatically run CI tests and deploy it in our server. We’ll do it in few steps.

  1. Install gitlab runner in our server
  2. Register gitlab runner for our repository
  3. Configure our project for gitlab runner gitlab-ci.yml
  4. Create a service to manage our app

Let’s deploy a project together. I’ve a spring boot skeleton project that has tons of features included out of the box. We’ll clone it and deploy it using gitlab.

1. Install Gitlab Runner in our server

We need to install gitlab runner in our server. Gitlab CI will use this runner to build our project.

Download gitlab runner

sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

Give it permission to execute

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

Create a directory where gitlab runner will keep it’s files

mkdir ~/gitlab-runner

Install and start the service

sudo gitlab-runner install --user=your_username --working-directory=~/gitlab-runner
sudo gitlab-runner start

 

Now your gitlab runner is running. We need to register it for our repository.

 

2. Register gitlab runner for our repository

Go to your Repository > Settings > CI/CD. Expand Runner section and you’ll see Set up a specific Runner manually

Here there’s an url and a token is provided for the runner registration.

Register your runner by executing the following commad.

sudo gitlab-runner register

You’ll be asked for url and token. Provide it accordingly.

You’ll be asked to choose an executor. Choose shell. Wait for a while and you’ll see a gitlab runner is registered in your repository.

!Important: Click Disable Shared Runners from the right panel when you expanded Runners section.

3. Configure your project (gitlab-ci.yml)

Create .gitlab-ci.yml file at the root of project directory.

stages:
    - deploy
    
variables:
  # MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode --errors --fail-at-end --show-version"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
    
before_script:
    - apt update && apt install -y maven
    
deploy:
    stage: deploy
    script:
        - mvn clean
        - mvn package -DskipTests
        - cp target/app.jar ~/projectname/app.jar
        - systemctl restart appservice
    
    only:
        - master

cache:
  paths:
    - .m2/repository/

In this yml file above, we executed 4 commands on deploy stage. mvn clean And mvn package -DskipTests to build and package our app that we’re gonna run. With cp target/app.jar ~/projectname/app.jar we copied the app file in our desired location on the filesystem (on pur project folder if we wish). Then we restarted our service that manages our application by executing the command systemctl restart appservice

Now the burning question is, what is appservice here? Where did it come from?

Okay calm down. We haven’t created this service yet, we’re gonna create this service now. It’ll execute a script that runs our java app.

4. Create a service to manage our app

Let’s create that script in our project folder (The folder where we copied app.jar file). In our case it’s projectname. This script will kill the process on the port where our app is running and then run our app on that port.

nano ~/projectname/deploy.sh

Paste those commands below and save it using ctrl+x

#!/bin/sh
fuser -k 8080/tcp
java -Dserver.port=8080 -jar app.jar

 

Create the service named appservice.service to autostart our app in case it’s stopped.

nano /etc/systemd/system/appservice.service

And pase code below

[Unit]
Description=App Backend Service
After=network.target
[Service]
User=root
# The configuration file application.properties should be here:
#change this to your workspace
WorkingDirectory=~/projectname
#path to executable. 
#executable is a bash script which calls jar file
ExecStart=~/projectname/deploy.sh

SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

Press ctrl+x then enter to save it.

Now reload system daemon and start our service.

systemctl daemon-reload
systemctl start appservice
systemctl status appservice

It should show a green light in case our service is running successfully.

Wholla!! See? we’re done!

Leave a Reply

Your email address will not be published. Required fields are marked *