Deploy dockerized spring boot web on App Engine - spring-boot

I have a Spring Boot web application which is currently deployed Google App Engine. Now I am shifted to Docker and want to deploy the docker image of this application on to App Engine.
So far, I could not find any document related to this. Most of the documents explain how to deploy a docker image of Spring boot on Tomcat. Is there any way to achieve this?

First you need App Engine using the flexible environment , if you want deploy by docker image.
Here is the document Building Custom Runtimes.
A custom runtime allows you to use an alternate implementation of any supported App Engine flexible environment language, or to customize a Google-provided one. It also allows you to write code in any other language that can handle incoming HTTP requests (example). With a custom runtime, the App Engine flexible environment provides and manages your scaling, monitoring, and load balancing infrastructure for you, so you can focus on building your application.
In official case they have their sample DockeFile by jetty. But you can ignore the jetty part, just make your spring boot application executable ,and run it.
FROM gcr.io/google-appengine/jetty
ADD test-webapp-1.0-SNAPSHOT.war $JETTY_BASE/webapps/root.war
WORKDIR $JETTY_BASE
RUN java -jar $JETTY_HOME/start.jar --approve-all-licenses --add-to-startd=jmx,stats,hawtio
&& chown -R jetty:jetty $JETTY_BASE

Hopefully this helps:
https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/helloworld-springboot
One compelling benefit with Docker containers is that, when the containers works on one runtime (e.g. Tomcat), it should be relatively straighttforward to swap in a different runtime (e.g. App Engine).
NB App Engine Flexible is the specific service that you want. It is similar to App Engine Standard but it schedules containers for you.
The primarily requirement for a container (image) to work with App Engine Flexible is that the container expose an HTTP endpoint on port 8080. As long as your container meets this obligation, you can run anything within it.

Related

Can you use Testcontainers to manage service dependencies, like a database, during local development?

Testcontainers can manage dockerized service dependencies, like a database, Kafka, Elasticsearch, and so on for integration testing.
Can I configure my Spring Boot application to manage these service dependencies during local development?
For example, my Spring Boot application needs a MySQL database.
I would like to integrate it with Testcontainers to provide a Docker container with MySQL not only during the tests execution, but at application startup during local development too.
Testcontainers provides an API to manage applications and services in Docker containers. It's incredibly useful for integration testing, where having a programmatically configured, isolated, repeatable environments is an essential requirement for trustworthy tests.
Because of that Testcontainers has integrations with the frameworks like Spring and Quarkus, and tes frameworks like JUnit, Spock, etc to automatically tie the lifecycle of your containerized dependencies to the lifecycle of the tests.
However, Testcontainers API is generic and doesn't have to run during the tests. For example, Quarkus has a feature called Dev Services which automatically creates a container for your database (or other service dependencies, for example Kafka, Redis, etc) when your application tries to access the database, but the configuration is not present.
You can think about it like this, if you have the data access repository classes initialized and wired, but no datasource.url in the config -- it'll spin up the database using testcontainers and configure the app to use it (just like it would happen during tests, but instead used for local development).
Spring Boot doesn't have an automated feature like that currently, there's an open issue to investigate these local development setups with Testcontainers.
If you're open to manually add a feature for your particular application, you can look at the prototype linked from that issue here: https://github.com/joshlong/testcontainers-auto-services-prototype
It's a bit more involved because it integrates with the Spring DevTools, but here are the essential parts that need to be taken care of:
Check that you need to use the database (in your application it can be a given).
Verify the configuration to use the database is absent (if the database is already configured you don't need to spin up a new one)
Create a container using Testcontainers API, either using an appropriate module or the GenericContainer with any Docker image.
Provide the configuration back to the application. For the database that would be the jdbcUrl, username, password, database name, r2dbcUrl and any other relevant properties.
You can take a look at the video with Josh Long where this concept was tried: https://www.youtube.com/watch?v=1PUshxvTbAc&t=2450s
It would also work in the production environments, but the usefulness of the ephemeral Databases, might be limited.

Update for JavaEE application

Our application are built on Spring boot, the app will be packaged to a war file and ran with java -jar xx.war -Dspring.profile=xxx. Generally the latest war package will served by a static web server like nginx.
Now we want to know if we can add auto-update for the application.
I have googled, and people suggested to use the Application server which support hot deployment, however we use spring boot as shown above.
I have thought to start a new thread once my application started, then check update and download the latest package. But I have to terminate the current application to start the new one since they use the same port, and if close the current app, the update thread will be terminated too.
So how to you handle this problem?
In my opinion that should be managed by some higher order dev-ops level orchestration system not by either the app nor its container. The decision to replace an app should not be at the dev-ops level and not the app level
One major advantage of spring-boot is the inversion of the traditional application-web-container to web-app model. As such the web container is usually (and best practice with Spring boot) built within the app itself. Hence it is fully self contained and crucially immutable. It therefore should not be the role of the app-web-container/web-app to replace either part-of or all-of itself.
Of course you can do whatever you like but you might find that the solution is not easy because it is not convention to do it in this way.

I have two microservice, should it have its independent embedded tomcat or one common tomcat

Which is good in production environment? Individual embedded tomcat for each app or one tomcat for many apps?
The idea of making micro services is mainly to build services that are developed/ deployed/scaled independently. When you try to deploy multiple microservices inside a same container/jvm then you may not be able to leverage all these benefits. Also you CI/CD/integration testing may be hard. Try using embedded containers or container technologies like Docker which ensures complete isolation of the microservices.
The decision also depends on what is the deployment environment of yours. If its cloud going for Docker would be a good idea

When do we need to run a Java application in a container?

Lately I started to learn Java EE and related technologies and there are some concepts which confuse me. Somewhere I read that whenever one is building a Java EE application then it is sort of mandatory to use a container.
Currently, I am learning Spring framework and trying to build a small application with it to get hands-on. Now in that I am not sure if it is mandatory for me to use a container (say Tomcat) or it depends application which I am building that I need a container or not.
If it depends on the application that one is building, then what are the factors which help to decide whether a container should be used or not?
Puuhhh, this is a very big question and there is no simple answer. But I will do my best to explain my own opinion at least:
What are containers?
Containers provide functionality to you. Such a functionality can be to handle web request and dispatch them to servlets - in this case we call them servlet containers (e.g. Tomcat or Jetty).
But containers can also provide other things, e.g. they can provide user authentication, logging or the connection to a database. Most containers (e.g. Tomcat) do multiple of those things (e.g. Tomcat does all I mentioned). Some containers do more then others, e.g. JBoss can do much more than Tomcat.
Trade Off
However, there is a trade off: If you use a simple container (like Tomcat), you need to do a lot of things on you own or by using other Frameworks (like Spring). But if you use a powerful container, you must know the container very well and the chance is high that your application will depend on this concrete container sooner or later.
The point, that using a container is not mandatory. It is a decision. Some people will argue for it, others against it. But depending on the books you read, this decision is already made (e.g. J2EE needs a J2EE container, that's how it works).
The trend (IMHO)
Years ago the trend was to use big and powerful (J2EE) containers which provide as much as possible. IMHO the trend today is to use smaller and light-way solutions. Most developers would prefer to use a Tomcat server instead of a JBoss server today.
Frameworks without containers
While J2EE needs a container, there are other frameworks/technologies which supports the development of web applications without any external container. Such frameworks are Play! or Spark Java.
Note
If you are not familiar with containers and Spring, take care to don't get confused. Most applications you will develop with Spring are web applications which will be deployed to a servlet container. This is very common. But Spring doesn't relay on that. You can also use Spring without such a container, e.g. to develop a desktop application. But if you want to develop a web application, the Java-way is to use a servlet container.
If your application is using servlets, you'll need a container to handle the requests. Tomcat is a very popular choice.
I'll anticipate your next topic to cover with this discussion of "application server" versus "container."
There are two containers. One is Web Container (IIS, Apache) to run Web Applications and another is "Application Container" to run Enterprise Applications.
Web Applications = Apps developed using HTML, XML, CSS and JSPs
Enterprise Applications = Apps developed used JAVA, J2E and Serverlets in addition to HTML and XML.

Spring YARN: How to create a Tracking UI and correctly wire a proxy to it?

I want to deploy an application with a web interface. I want to use Spring YARN for this because that eases all the basic setup, and I can start the application with java -jar.
What steps do I have to do to:
have my application expose a web interface
have the tracking URI I get when submitting it proxy to that web interface
Unfortunately, I cannot find anything about this on the net, there is npthing on that particular issue in the Spring documentation and Google searches do not get me the correct results either.
Easiest way to do this is simply use Spring YARN Boot application model and framework is then trying to do the heavy lifting on your behalf. I actually showed a demo of this during my session at SpringOne 2GX 2014. You can find my session recording from youtube https://www.youtube.com/watch?v=qlvX7_r9aUA.
Interesting stuff for this particular feature is at the end (starting from 1:16:22) and you can see how web server address is registered into YARN resource manager and how I query it using a Spring YARN Boot CLI (around 1:32:13). Spring YARN will actually see that there is an embedded servlet context and registers it automatically. In this demo property "server.port=0" makes tomcat to choose random port which is then registered.
Code for this particular UI demo can be found from github https://github.com/SpringOne2GX-2014/JanneValkealahti-SpringYarn/tree/master/gs-yarn-rabbit. Demo was around RabbitMQ just to have some real UI functionality and not just a dummy hello world page.
There's also more up-to-date sample in https://github.com/spring-projects/spring-hadoop-samples/tree/master/boot/yarn-store-groups which doesn't have a real UI(just Boot management endpoints). Thought it's relatively easy to add Spring MVC magic there just by following normal Boot functionality(i.e. following https://spring.io/guides/gs/rest-service).
Lemmy know if this helps!

Resources