Automatic update spring boot docker app using ansible - spring-boot

We plan to release spring boot application to customer. In corrent process, every time we release a new version, we have to uninstall the rpm and re install using rpm.
We want to move towards auto update of our application whenever there is a new version available. Essentially customer does not have to deal with updating the applications.
Instead of rpm, we are thinking about docker image, packaged with all dependencies.
. How do achieve this functionality?
Based on what I have read so far, if we package we use ansible + docker to deploy the application, , ansible (using watch tower or custom code) will ping an IP and when discovers a new version, will stop the application, pull the application from destination and then deploy and start.
Is my understanding correct?

Steps to automate deployment
Docker
Create application and dockerise it with any JDK docker image. We have maven package to dockerise application.
Add Plugin to pom.xml
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.10</version>
<configuration>
<imageName>job-demand-service-analytics-processor</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
OR
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>${jib-maven-plugin.version}</version>
<configuration>
<from>
<image>adoptopenjdk:11-jre-hotspot</image>
</from>
<to>
<image>websockethandler:latest</image>
</to>
<container>
<entrypoint>
<shell>sh</shell>
<option>-c</option>
<arg>chmod +x /entrypoint.sh && sync && /entrypoint.sh</arg>
</entrypoint>
<ports>
<port>8090</port>
</ports>
<environment>
<SPRING_OUTPUT_ANSI_ENABLED>ALWAYS</SPRING_OUTPUT_ANSI_ENABLED>
<APP_SLEEP>0</APP_SLEEP>
<JWT_SECRET_KEY_BASE64>""</JWT_SECRET_KEY_BASE64>
..........
</environment>
<useCurrentTimestamp>true</useCurrentTimestamp>
</container>
</configuration>
</plugin>
</plugins>
There are many options to dockerise your Spring application
Git
Push your code to git server like Bitbucket, Gitlabs, Github and so on.
Create a master branch for production releases and develop branch for development.
Jenkins
Trigger a jenkins job to create a docker image when you commit or merge changes from develop to master when feature is commited to develop.This is based on the hooks we add at git server.
If the docker image created successfully trigger the job which deploys.
Reverse Proxy or Load Balancer
To achive zero downtime, use load balnacer(reverse proxy like NGINX with upstream) running your container in multiple replicas of the container.
This applies for any application. If you have special requirement, update your question with the basic example code and will update the answer with Dockerising and automation steps.

Related

How to build the docker image using jib-maven-plugin, but not push by default?

I have a simple SpringBoot application and I want to build docker image using Jib Maven plugin.
Following is my plugin configuration:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>2.1.0</version>
<configuration>
<from>
<image>openjdk:11-jdk-slim</image>
</from>
<to>
<image>username/appname</image>
<tags>
<tag>latest</tag>
<tag>${project.version}</tag>
</tags>
</to>
<container>
<mainClass>demo.Application</mainClass>
<ports>
<port>8080</port>
<port>8787</port>
</ports>
</container>
</configuration>
</plugin>
I just want to build the image locally and run it. I don't want to build and push to docker registry in one go.
When I run the command mvn jib:build it is automatically getting pushed to DockerHub using my credentials from Docker config (/Users/username/.docker/config.json).
Is there a way I can disable push and another goal just to push the image to registry?
Since you said jib:dockerBuild is not an option, the closest workaround is jib:buildTar; the goal creates a local tarball at target/jib-image.tar (path configurable with <outputPaths><tar>). Running jib:buildTar (or any jib:... goals) for the first time will build and cache everything necessary to build an image. Therefore, subsequent jib:build runs will be no-op in terms of building layers. It will only need to send layers missing in a remote registry.
Of course, one downside of the workaround is that it creates an unnecessary tarball, which may be large.
Unrelated to you question, you don't need to set <tag>latest</tag>, because the target image reference <image>username/appname<image> already implies <image>username/appname:latest<image>. The <tags> configuration is for pushing additional tags on top of <to><iamge>.
From JIB documentation Jib Maven Plugin, you can run
mvn jib:dockerBuild
This will push an image to a Docker daemon after building.
If you are using podman in mac or windows (with wsl2)...
specify path where podman command can be found
mvn jib:dockerBuild -Djib.dockerClient.executable=$(which podman)
I just checked and it is possible to have the image built by Jib locally. First make sure that your Docker daemon is running locally. And then do it like this:
<to>
<image><your-local-image-name></image>
</to>
I guess yours might not have worked because your Docker daemon wasn't running or your image name started with your username, which made Jib think that you actually want to push the image to Docker Hub.

How to automatic deploy spring boot in jenkin and put images to docker

I using jenkins spring boot and docker in my app. I want deploy spring boot in jenkin and put jar when deploy into docker and start it automatic. I reference to here :
https://denisdbell.wordpress.com/2017/08/26/automated-deployment-jenkins-docker-spring-boot/
But i have a problem. It deploy success but don't run jar in docker. When i type docker - ps it show me jar and i must run it manually. I want when jenkin deploy it automatic put images into docker and run it automatic.
I have two question:
- In my project spring boot, i need put docker in root project ?
- How to jenkin deploy and put images to docker and run automatic jar when jenkin deploy
- When i have mutiple modules, how to i specific copy only jar modules i need deploy and copy to docker and run it.
Thanks you so much help me
Question 1:- Yes you need to add it to the root folder.
Question 2:- You have to use the dockerfile-maven-plugin to push/pull images and use the shell commands from Jenkins to run the same.
Add the SCM GIT, Stash, Hg as this
<scm>
<connection>scm:git:ssh://git#guthub.com/yourproject.git</connection>
<developerConnection>scm:git:ssh://git#guthub.com/yourproject.git[push=]scm:git:ssh://git#guthub.com/yourproject.git</developerConnection>
<tag>HEAD</tag>
</scm>
Add the plugin as
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.3</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.image.prefix}/yourproject-${project.artifactId}
</repository>
<tag>${project.version}</tag>
</configuration>
In this while building your jar pass the arguments
mvn clean install -DskiptTests -Ddocker.image.prefix=<your docker repo url>
This command would automatically push the latest project version docker image to the repository.
Use the Shell commands to fetch this image and start the docker from the shell.

Is it possible to "clean" deploy Oracle service bus project to OSB using maven?

I need to be sure in clean maven deployment of a project.
I mean not 'mvn clean deploy', but to remove existing project from OSB before deploying (overwriting).
If you overwrite project on OSB, you can't be sure that all of its resources will be updated. I've seen a lot of cases when some resources in project are overwritten and some are not. It's quite unpredictable behavior.
So the question is: is it some maven (maven service bus plugin or maybe some other one like maven weblogic) task or parameter to force update project before deploying?
Well, I found the solution. It is not straightforward. Actually I dont like it, but it works.
The only solution I have found is to delete service (project in OSB terms) from OSB console using WLST.
The working script I found in the Martien van den Akker's blog here: http://blog.darwin-it.nl/2014/03/osb-remove-artefacts-with-wlst.html
It is ready to use script. But this works only for OSB 11 and doesnt work for OSB 12.
So you can use this workaround: http://soamagic.blogspot.com/2016/05/osb-12c-java.html
In my CI server (Hudson-based) I added Maven build step to launch sh-script, which executes wlst.sh with py-script as a parameter (actually there are 4+ parameters - weblogic admin username, password, url and others - project names to delete). This build step executes before every service deploy.
This guarantees that the newest version of the service will be deployed to the OSB-server.
Edit: Not sure if it worth posting, but I hope someone can find something useful in my code. So here it is:
Maven build:
<profile>
<id>undeployService</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<id>wlst-undeploy-service</id>
<phase>process-resources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>
${project.basedir}/../conf/WLST/undeployProject.sh
</executable>
<arguments>
<argument>
${weblogic.username}
</argument>
<argument>
${weblogic.password}
</argument>
<argument>
${weblogic.url}
</argument>
<argument>
${project.artifactId}
</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
undeployProject.sh script:
. ${MW_HOME}/osb/tools/configjar/setenv.sh
${MW_HOME}/osb/tools/configjar/wlst.sh ../conf/WLST/undeployProject.py $*

Automatically publish JavaDoc as a functioning website on remote machine

Is there a way of automatically publishing as live website javadocs after uploading it to Nexus Maven repository? I have some packages, which are under constant development and I'd like to have the docs for them available for browsing by other team members straight after uploading updated code to our remote repository.
Is there any ready solution for doing that or would I have to write say a shell script (executed by Maven after successfull deployment of the code to the remote repo), which would copy the docs to a remote location on a web server?
I know that Nexus Professional allows to view javadocs out of the box, but even for 10 users it is a bit pricey, so I'd appreciate a different solution :-)
I'm using Eclipse#Windows + Maven 2.
Thanks!
If your project is open-source and is released to Maven Central then your javadoc will be available at javadoc.io automatically.
The url is of the form: http://www.javadoc.io/doc/[groupId]/[artifactId]. For example, I have my javadoc for my project at www.javadoc.io/doc/me.ramswaroop.jbot/jbot
Nexus Open Source as well as Nexus Professional support the site repository format, which allows you to host Maven produced sites. If you set up publishing a Maven site that includes Javadoc as part of your build you can have them accessible there.
The other thing you can do is just publish javadoc and source artifacts as part of you build and then Eclipse will be able to automatically download them from Nexus and you therefore wont even need a website with the javadoc on it for you developers.
Of course other people might want the site though.
Documentation on all that is available in the Nexus book as usual.
A bit late for reply, but someone else might need it in future. I didn't try the solution you proposed instead using one utilizing Maven Wagon plugin. Basically I first upload the jar with javadoc to webserver using sftp protocol and then unzip it using ssh command.
So parts of my parent POM, which configure the plugin look as follows:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<executions>
<execution>
<id>upload-javadoc</id>
<phase>deploy</phase>
<goals>
<goal>upload</goal>
</goals>
<configuration>
<serverId>my_id</serverId>
<fromDir>${local.dir}</fromDir>
<includes>${javaDoc.file}</includes>
<excludes>pom.xml</excludes>
<url>${remote.url}</url>
<toDir>${remote.dir}</toDir>
</configuration>
</execution>
<execution>
<id>execute-test-commands</id>
<phase>deploy</phase>
<goals>
<goal>sshexec</goal>
</goals>
<configuration>
<serverId>my_id</serverId>
<url>${remote.url}</url>
<commands>
<command>mkdir -p ${www.dir}</command>
<command>unzip -o ${remote.dir}/${javaDoc.file} -d ${www.dir} > latest_unzip_log.txt</command>
</commands>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
And then just call the plugin in child pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
So that's my solution, but I guess Manfred's is much simpler.
Ps.
Having the Javadoc available only in Ecplise (which I do anyways) was not the goal as the purpose was for the Javadoc to be available for other project members through a website.
Another option to host javadocs is https://docshoster.org/. It can automatically pickup from maven. There is an api to upload directly as well.

maven cargo plugin configuration for Jboss as 7.1.0

I am trying to configure the maven cargo plugin for deployment on existing jboss 7.1.0 on my local machine. I am able to start the server by
mvn cargo :run command. It is using the jboss-modules.jar to start the server. I want to configure it in such a way that it executes the standalone.bat inside the bin to start the server. I have my datasource configured in standalone.conf.bat and hence I need to execute the standalone.bat to start and deploy the war.. My configuration looks like this..
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.1.2</version>
<configuration>
<wait>true</wait>
<container>
<containerId>jboss7x</containerId>
<home>C:/jboss-as-7.1.0.Final/</home>
</container>
<configuration>
<type>existing</type>
<home>C:/jboss-as-7.1.0.Final/standalone</home>
</configuration>
</configuration>
Is there any property in cargo configuration to set to call the standalone.bat to start the server?
Thanks,
The question is a bit outdated, however with the current release of JBoss Maven plugin it is actually possible to start and stop the application server using mvn jboss-as:start and mvn jboss-as:shutdown commands. I have added a Maven JBoss tutorial time ago describing exactly this.

Resources