Continuous integration for Spring Boot app using Codeship + Openshift
I have already talked about CI using pair Codeship + Openshift and I like such combination. Recently, I have started a new project based on spring boot and faced an issue, that Openshift does not provide an out-of-box pattern to run Spring Boot application.
Spring boot application could be built in two ways: with embedded tomcat and without it. After reading some tutorials, how to build an application without tomcat, I decided not to go this way - it requires some code changes + some kind of settings tuning on Openshift side. The solution with embedded tomcat looks more consistent and reliable in this case for me.
To setup spring boot app you need DIY gear with maven and Java 8. I was lucky and found a repo on github with sample spring boot application on DYI openshift gear. So I use this code as the start of my application. The main magic are located in file .openshift/action_hooks/deploy
. It downloads Maven
and setups all needed environment variables.
As next step, you should build and test your Spring Boot project on Codeship. All technical details about setup Codeship can be found here. I will notice that in this tutorial the build was created for Grails project, so test and deploy steps for Spring Boot project will be slightly different.
First of all, we need to use Java 8 on codeship server for tests instead of default Java 7. To enable Java 8 in setup section of Project settings -> Test
include this:
jdk_switcher home oraclejdk8
jdk_switcher use oraclejdk8
Test script has nothing special except Spring profile for CI execution:
mvn clean initialize
mvn clean test -Dspring.profiles.active=ci
mvn package -Dmaven.test.skip=true
Deployment script is the most interesting part here. Usually, when you use standard Tomcat Openshift gear, all you need is place WAR
file in a correct directory and it will be automatically deployed. I want to use embedded tomcat, so I get packed JAR
which should be started manually. Such case was not what I desire (take into account that before starting I should stop old running version of the application). Performing all these operations from deployment script located on Codeship
was also not possible due to insufficient access rights to start and stop processes. All I can do remotely - file operations and controlling Openshift
gear lifecycle. It gives me a way to resolve deployment problem:
- Stop running gear.
- Delete old
JAR
. - Copy freshly built
JAR
fromCodeship
toOpenshift
. - Start gear.
Openshift
action hook that triggers by a start of gear will start the application from newJAR
.
The first 4 steps of plan are located in Codeship
deploy script:
ssh <some_hash>@project_name-acc_name.rhcloud.com 'gear stop'
scp -rp /home/rof/src/<codeship_account>/<codeship_project>/target/*.jar <some_hash>@project_name-acc_name.rhcloud.com:~/app-root/runtime/repo/target/
ssh <some_hash>@project_name-acc_name.rhcloud.com 'gear start'
wget --retry-connrefused --no-check-certificate -T 60 https://project_name-acc_name.rhcloud.com/somepath/to/ping
Actually, there is no need to remove an old JAR
, because it always has the same name, so the new file will overwrite the old one. I add the ping action as the last command to be sure the application is up and running once I see that build is passed.
Now let's take a look at the 5th step of the plan - starting the application by action hook. All Openshift
hook are placed at .openshift/action_hooks
in git repository of your Openshift
project. As I started with the sample of Spring boot layout for Openshift
I already have a script for action hook for gear starting: .openshift/action_hooks/start
. The main part of this script is this line:
nohup java -Xms384m -Xmx412m -jar target/*.jar --server.address=${OPENSHIFT_DIY_IP} --spring.profiles.active=openshift &
So all I need here is to be sure that I have correct path and Spring profile.