I´m trying to get more familiar with Docker because everyone talks about it and everyone loves it. I know how Docker works in general, but I don´t understand how to used it in practice.
In my case, I have several web applications running on Tomcat. As far as I understand, it´s common to have one Docker container per application. But what does that mean in my case?
Should I have several containers each running Tomcat which in turn runs one web application? Or would I have only one container with Tomcat where all web applications are deployed on?
Understand why you will dockerise all your applications which are running in single tomcat instances ?
Lets say if your tomcat goes down then all your application will go down. So
Docker with microservices is the trend which tells a docker container should not have mutiple applications running i.e single resposibilty model.Avoid one container being responsible for multiple aspects of your overall application.
What will happen if you put all your applications in single docker ?
Availability : if container goes down all application will go down. Example : If you have ecommerce application and if offers service goes down then you should be able to do other stuff other that checking offers.
Deployment : If you need to deploy an application then all application will go down. for example : if you want to deploy offers update would it be correct to stop all running users which may be doing payments or other stuff?
Application Load and scaling :Lets say you have the modules, Payment, offers and shipping. I would expect the offer module will have more load than all others. So we can horizotal scale the offers service. But if we would have all application in single container then all application will be scaled which waste of resources.
Refer a nicely written nginx tech blog : https://www.nginx.com/blog/introduction-to-microservices/
Let me know if you have any questions more to ask. feel free to add comment.
Generally, it is better to run a Tomcat Docker Container for each .war app with filebeat or any other log shipping program in conjunction with single or fewer frontend containers. So 2 Frontend Web Containers for High Availability with 4 Tomcat Containers each serving a Tomcat app.
Related
I have made a small .NET Core REST API which I would like to be able to easily put on a Linux server running a Java app on Tomcat. Can one use Docker to ease the deployment of the .NET tool, and if so, how is it done? I was told by someone that Docker would (more or less) allow me to bundle the API as a single app/file without having to bother too much about deployment policies at the place I am working (which by default only allows for Java apps to Bd deployed).
You can use a docker image like e.g. microsoft/dotnet to run your app in a docker container. Please read the documentation on the linked page on how to run your app inside the container.
If you then map an exposed port (443, 80, 8080... depends on you app) using the -p option on container startup you can then access the REST endpoints from any software you like because it is basically behaving like an other REST server running on that host. Since you want to run tomcat in parallel you should avoid to map the port from the container to 8080 on you host, thought! Other than that this setup is totally independent from the application server running on the host itself.
I have 5 Spring Boot web applications but have only one Server (low-end).
What is the best way to deploy all 5 in one Server? Having only one web container (Tomcat) and deploy all of them as separate war files on the same Tomcat or run all 5 on different Tomcat containers (Spring Boot default behavior)?
What is your recommendation by considering performance and maintenanability?
IMHO, if you're running a resource-constrained server, your best bet is to deploy all of your applications as war files under a single tomcat instance. Running multiple servers would just add un-needed overhead.
If you have little resources on your server, you don't have much choice. Each Java virtual machine has a significant overhead, so running separate containers will make you reach the limits of your low-end server earlier.
You will have to deploy your wars in the same tomcat server, with different servlet contexts.
However, if you have sufficient RAM, the cleanest way in my opinion is creating docker images and running the standalone spring-boot jars in each container.
My recommendations are:
If these WARs are independent of each other, deploy them in a different Web server, not only Tomcat or whatever container you're using, but also in either different virtual server, dedicated server or Cloud instances.
Deploying in different "virtual server" you can scale horizontally, so this is good for future workloads.
Deploy a load balancer from your hosting provider, or you can use Nginx for doing that.
Hope this helps!
From my experience, using container such as docker is the easiest way to maintenance multiple spring-boot applications. When you have a new server, it can be migrated easily, and the application can be updated without interrupting other applications. But you may need to spend extra time to learn how to use the container.
If using Tomcat, it is recommended to separate the tomcat instances. One tomcat for each WAR file. Putting multiple WAR files in one tomcat can make the maintenance difficult. Tomcat hot deployment / auto deploy tends to have some errors which require you to restart the whole tomcat
I'm complete able to configure spring boot in both cases, the question here is which of them are more robust and is the more recommended, because I didn't find in the spring boot documentation the recommended way to deploy it in a production environment, my concerns about use the embedded container are:
If I want to set it as a Windows or Linux service, is the jar file the best option?
If I use the jar file I'm not going to have access to restart the server.
Maybe in the future I need more applications in the same container.
If I restart the machine I have to execute again the java -jar.
The question in general is which is better use the jar file and execute it as java -jar jarname.jar in production or change the packaging to war set the tomcat as provided and set the generated war in an empty tomcat.
I hope you can help me.
---EDIT---
Many times the answer is depends, this is for a normal web application or REST web service.
jar packaging is perfectly suitable for production and you should rather fallback to war only if you really have to - which is often the case when you cannot control your deployment environment (which is often the case in large enterprises).
There is a chapter in Spring Boot Reference about setting up Spring Boot based application as a Unix/Linux/Windows service: Installing Spring Boot applications.
Regarding your concern:
Maybe in the future I need more applications in the same container.
With embedded containers if you need more applications running on the same machine, you should start two applications separately, each running on different port and effectively you will end up with two containers running - which is good, applications are better isolated from each other.
About a month ago I had the question like yours.
Let me share my conclusion:
1) JAR:
You can run independently every appliction with different ports (in linux, java -jar ... > app_logs.log &) and you can route it (e.g. nginx). Note that, restarting is not problem. You can write custom bash script (like this: ps aux | grep appname and kill by PID)
But there are some problems with configuring production app. Property files will archived into jar.
2) WAR
You can deploy into container and just run it. Easy managing at the server. If you want to re-configure app, open properties file from unarchived folder inside container, change it as need and restart container. So, managing and configuring will be easy.
But, if you want to run another app in this server with another port, then you must install another copy of container and config it.
So, in my practice, using war app easier than jar to manage and re-configure.
I don't know that much about Windows services but on Linux you can add the execution of a jar to a RC-Scripts (and thus make the application start at a certain run-level). For a spring boot app you just have to symlink to the jar and you can start/stop/etc like any other service, see: Spring Boot application as a Service
restart the machine or the JVM? A shutdown mechanism is built into spring boot, you just have to activate it (and you should enable security machanism so that not anybody can do that), see: How to shutdown a Spring Boot Application in a correct way?
Spring-Boot enables microservices - so the idea is to have one embedded webapp-container for each webapp/microservice. This reduces the risk of losing all services when only one is going down.
Yes. and you have to execute catalina.sh|bat start after every restart. Or you add an appropriate startup script (see 1.)
I sense that you'd rather do it the old-fashioned way. Despite the 'matter of taste' answer, there is one argument pro-jar: the only dependency is the JVM! The rest (the web-app-container, db-drivers, other libraries) is all part of the package you deliver. And if you decide to change the container for the next release, so will it be.
One more reason to use "war" file in production.
Springboot masked an error Jetty threw whereas WAR deployed in Jetty correctly caught it ( though issue below is still under review )
https://github.com/spring-projects/spring-boot/issues/8917#issuecomment-294673487
I don't know much about server kind of things, But my recommendation is
If you are using Monolithic application, better to use war with
external tomcat.
If you are using for Micro Service applications, use embedded
tomcat with different port. And each micro service applications are
independent from each other.
I do understand that using the same tomcat instance for a number of web applications has some risks (e.g. if one web application crashes tomcat it will terminate the other web applications as well.). The benefit is of course cost effectiveness since one server is enough and having all the web applications in one place makes it very easy to administrate.
Are there any industry guidelines on how a good setup with multiple web applications on tomcat should look like?
Pros
One JVM to monitor
Common libraries can be shared (sometimes risky)
Cons
Common HTTP thread pool all applications are using (you can, however, configure several connectors with different thread pools)
One malfunctioning application can take down the whole server
Restarting one application requires restarting all of them (if not using hot-deployment)
You are right that hosting of multiple we applications on one application server / web container (either Tomcat or other) has benefits.
You mentioned the robustness issue when one application may cause failure of another. But let's simplify this: even if you have only one application you still want 24*7 availability. To achieve this goal people typically run more than one instance of application server with identical application on each one and load balancer in the enterence to the site. The same is relevant for several web applications. Just run N (2 as minimum) application servers with identical set of web applications deployed and load balancer. You will probably need a kind of watchdog that restarts server if it failed or if it stopped responding etc.
In some cases kind of clustering is required. But it is other story.
I am working at a startup, we are just about to roll out our first beta. Knowing that we will be having a good number of users, we want to have seamlessly deployment when we are adding new features.
I have worked with windows azure before, and I know they support seamless deployment, so I did some googling and cloudbees was the first result.
So the question is, with what we have now (geronimo server, rackspace hosting), is it possible to seamlessly redeploy a java web application? If so, how?
Are there other alternative solution, such as using another hosting provider or use a different web server? (Because it is a startup, it would be beneficial if the answer keeps scalability in mind)
If with a seamless redeploy, you mean an upgrade of your application without any downtime or restarting of your server, LiveRebel might be something to look at.
See http://zeroturnaround.com/liverebel
There are a lot of methods for doing this in the java world. If you don't use sessions (or use shared sessions between app servers) you can do a rolling stop/deploy/start of your appservers, taking 1 offline at a time and using a load balancer to ensure that traffic goes to the other servers.
I have heard Glassfish has such feature, the reference probably ment this (Glassfish 3.x redeploy command) : http://docs.oracle.com/cd/E19798-01/821-1758/6nmnj7q1h/index.html