2

I'm currently experimenting with docker with the potential of using it in future professional projects and am a bit confused about best practices.

In my experimental setup I have three docker containers, all currently running on the same server, though that might change in future projects: - Git server (Gitea) - Jenkins server - Web app (Tomcat)

Pulling the source code from git and building the war is no problem. Now I'm running into difficulties actually deploying it.

My current solution: I've modified the tomcat docker so I can deploy the resulting war to the tomcat docker and restart it inside the docker. I've read that this is bad practice and I understand the reasoning, so I need another solution.

Building the docker container from another docker container is also said to be bad practice and I also understand the reasoning for that, so that's a no-go, too.

An idea is to ssh to the host system and then either deploy the webapp to a folder shared with the tomcat container or rebuild the container. That would probably work and be future-proof if the tomcat docker moves to a different host, but it doesn't feel docker-like from my limited docker understanding.

The last idea is to make it so the tomcat docker container builds the webapp itself, i.e. does the git clone, mvn package and so on itself. That still needs to be triggered, possibly by an ssh connection to the host.

In both those cases I'd need to expose a docker-capable user to remote login, which I don't really want to do.

I can only find information on bad practice, not on how to actually solve this specific problem in a good way. What is the actual correct way to do this?

1

Where you say:

Building the docker container from another docker container is also said to be bad practice and I also understand the reasoning for that, so that's a no-go, too.

Perhaps there are bad ways of doing that but it can be a solid pattern. By way of example if you use openshift Kubernetes it runs s2i as builder images on your cluster. s2i checks out your code from git, compiles it, and pushes it to a new layer in your docker repo. It has an incremental flag where it will tar up your library deps folders at the end of a build and store as a docker layer. Then the next time you build it does a clean checkout then untars the libraries from the last build. That speeds up the next build a lot as it has the local maven cache from the last build. It also means the s2i build container can be launched on a different host in the cluster at each execution and it just connects to git and the central container registry and does a fast repeatable build.

s2i is a stand alone tool that can use your local docker demon. So it acts as a single commandline ”compile my stuff into an updated docker image”. There are community supported s2i images for php7, node.js, Java etc. I recall that the java s2i will run a maven build with the “openshift” profile and expects your to copy the built WAR to “./deployment”. When you run the image that s2i writes out to your container registry it launches wildfly that is in the base layers and it deploys whatever finds in the deployment folder (but double check its been a while since I looked at it).

In your case If you are using Jenkins I suggest you take advantage that it supports building docker images. Append a docker pipeline step to create your image and push it to your chosen container registry. Enterprises that use Jenkins to build and Nexus for storing JARs and WARs are now using Nexus as their container registry. They can stick with Jenkins and Nexus and simply reconfiguration things to move into the world of containers.

I should also point out that you can be more “microservice-like” by skipping installing tomcat. You can use maven jetty plugin or maven tomcat plugin to just run the code with “mvn jetty:run” or “mvn tomcat7:run”. You can set a full blown config file for the servlet container via the plugins. Maven let's your set whatever jvm options you want. (note: after Tomcat 7 there doesn't seem to be support for this modern approach see the next paragraph where the mainstream now uses Jetty for this).

If you like spring you can use spring boot to build an excutable JAR that runs your webapp. The JAR will be large as it has everything to run the webapp including the servlet container packed into a single JAR. You can run it as “java -jar” and it runs your webapp in an embedded servlet container. Better yet configure it's maven plugin to make an executable jar you can simply run as “./my-app-1.0.0.jar” and it will lunch. That makes building a docker image trivial. You don’t have to install tomcat you only need a container with Java on it and copy in your spring boot executable JAR and run it as the CMD. Spring Boot is very mainstream for Java microservices and it runs Jetty under the bonnet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.