- :)
- :0
- :D
- ;)
- :]
- :º
Learn how to create a web application with Java and Springboot in a secure way, ready to be deployed to production
technical article
SpringBoot has become the most used Java framework in the world, surpassing J2EE standards. Below, we explain the reasons why it is the most used set of libraries and why it is advisable to use it when starting any web project.
Advantages of Using SpringBoot
SpringBoot is Free
SpringBoot is a module of the Spring project created to simplify the development of applications with the Spring Framework under the Apache 2.0 license. It provides us with an infrastructure for developing applications on an open-source Java language platform, making life much easier for programmers by saving time and costs without sacrificing control over the code or performance.
Although the Spring project was released in 2003, it wasn't until 2014 that the version 1.0 of the SpringBoot module was available, leading up to the current version 2.2.5 released with support for Java 13.
Spring Boot Runs on the JVM
One of the great advantages of working on the JVM is that it allows the development of new applications, migration, or reuse of code from any project already developed in Java, Kotlin, or Groovy. Moreover, it operates on one of the most widespread and powerful environments today, the JVM, with all the support it entails.
The virtual machine enables any Spring application, and Java applications in general, to run on major operating systems, including servers, virtual machines, or personal computers.
SpringBoot Enables Web and Microservices Development
There is a strong business trend to migrate applications to a microservices architecture, or for startups to use this architecture from the start due to its flexibility, thanks to the separation of responsibilities into independent microservices. This allows for easy migration and adaptation across different business models. The separation into microservices enables the creation of specialized and easily reusable applications, providing significant power and flexibility to information systems.
This great versatility of SpringBoot allows us to tackle virtually any professional programming challenge with its help.
Simultaneously, Spring Boot can be used to create traditional or multi-page web applications where the HTML is generated dynamically on the server side before being delivered to the user's web browser.
Spring Boot is Fast
Imagine not having to configure containers or Apache Tomcat web servers, having your application's structure and Spring framework auto-configured, managing all your dependencies in a readable format in a POM file for Maven management, and setting up your database connection, all in five minutes. This is no exaggeration; the automation offered by SpringBoot allows you to start developing almost immediately and deploy your application without complications, without sacrificing anything in return.
With Spring Boot, development is fast, and execution is fast. Supported by the entire Spring development framework, applications made with this technology are optimized for high workloads with minimal memory consumption, thanks to most entities being singletons and thus Java objects reused across threads. This approach keeps the RAM required per simultaneous client to a minimum, making it an optimal system for web environments with thousands of requests per second.
SpringBoot Has a Vast Ecosystem
Spring, born in 2003, became famous in the Java programming community partly due to its well-structured and comprehensive documentation, far above the general average we usually see in open-source projects, and still appreciated today.
In 2004, the developers formed their own company, and The Spring Forum emerged, the Spring developer community forum, which further popularized the framework. It continued to grow, becoming the most important source of information. Even in its early days, more than 300 programmers gathered at Spring conferences.
SpringBoot Has a Large Number of Developers
In 2017, a blog on the jRebel website published a chart of the usage index of different Java frameworks, based on services like LinkedIn, StackOverflow, GitHub, and searches for specific Spring questions on Google. Among the 17 frameworks analyzed, Spring MVC ranked first, followed by JSF with a notable difference: Java Web Frameworks index
Spring Boot Comes with Batteries Included
Spring is a complete framework for developing enterprise applications. It has everything needed to cover the functionalities expected of any professional application. From configuration management, security, SQL and noSQL data access layers, dependency injection, monitoring, testing, and more.
The project's documentation is one of the best in the Open Source world, and any user will find the information they need to use any of its modules, which are kept up-to-date with each version and every recommendation from the W3C for developing secure web applications.
Spring Boot is Polyglot
Thanks to the use of the JVM, the range of integration possibilities between different programming languages, databases, etc., expands, giving the opportunity to use the technology that best suits each business model.
SpringBoot has Support from Major Companies
Being based on the JVM platform, it enjoys the fame and support of all projects and major companies that use it, including those that specifically utilize Spring such as MIT, Intuit, PedidosYa, Trivago, MercadoLibre, and Google Cloud...
SpringBoot is Continuously Evolving
The idea of Spring is that as a programmer, you focus on developing your application and not waste time or resources on repetitive processes or configurations.
The Spring ecosystem is a set of modules that we can add to our application as needed to achieve this goal. We can mention by importance and functionality: Spring Data (simplified data access), Spring Security (authentication and security), and SpringBoot (autoconfiguration and deployment), which becomes one of the most essential modules.
Currently, we can see on the official Spring website that they have 25 projects in continuous evolution and 7 more projects for future development: Spring Projects.
How to Create an Application with SpringBoot Initializr
Here is a step-by-step guide on how to create a blank project, as a template to start any web development. In this tutorial, we use Java and Spring Boot to build a web application from scratch with simple steps using SpringBoot Initializr.
Spring developers provide an online web tool called Spring Initializr where, through configuration parameters, it automatically generates a Maven or Gradle project, depending on the choice, in a Zip file containing the folder with the application's structure to be imported directly from the programming editor such as Eclipse IDE, Netbeans IDE, or Intellij.
You can access it via the following link: https://start.spring.io/
The web assistant requests a series of necessary data to execute the template that builds the program's initial files. For all of them, it provides default settings that should be changed, such as the application name or the package that will be used in the generated classes.
Here is an explanation of the parameters and their purposes:
- Project: Allows you to choose the build tool for the application. In Java, the two most used tools are Maven and Gradle. We recommend Maven as it is the most widespread.
- Language: The programming language to be used in the application. All three types are supported by the JVM. Java is the most widely used option and has better support from programming editors.
- Spring Boot: Version of Spring Boot to use. Whenever possible, opt for the latest stable version, composed only of numbers.
- Project Metadata, Group: Refers to the Maven groupId descriptor, used to classify the project in binary repositories. Typically, a reference similar to that of the class packages is used. For example, com.arteco.web to place all web applications in the same directory.
- Project Metadata, Artifact: Refers to the other Maven descriptor artifactId, and therefore to indicate the name of the project and the resulting binary. The combination of groupId and artifactId (plus the version) uniquely identifies a binary within any organization.
- Packaging: Indicates what type of binary should be built. If the application will run on its own, select JAR, which contains all dependencies within it and can be executed with java -jar binary-version.jar. If, on the other hand, the application will run on an existing J2EE server or an already deployed Tomcat, choose WAR.
- Java: Select the version of Java to use. In this case, it is recommended to use the oldest version of Java to ensure compatibility with other libraries or projects you want to include, making it more likely to find existing documentation that is still valid. This reduces the risk of encountering immature features.
- Dependencies: Dependency search with the available Spring Boot starters. The most common dependencies are:
- Spring Web: Choose when you want to make a web application or microservices, whenever an HTTP communication is required and therefore the use of Spring MVC.
- Thymeleaf: Incorporates the template engine for dynamic HTML, successor to the previous JSP (Java Server Page).
- Spring Data JPA: Necessary to use the standard SQL database access layer called Java Persistence API.
- Spring Security: Allows incorporating access controls based on users and roles over the application's URLs. It also enables service method execution control based on roles according to J2EE standards.
- Lombok: Provides utilities that facilitate programming, such as automatically creating @Getters and @Setters for classes that are part of the message set.
- Flyway: A library that allows controlled application of database change scripts when the application starts. These scripts are called migrations and are subject to version control to ensure they are applied in the correct order.
- Mysql/Postgresql: Includes the JAR containing the JDBC driver needed to configure the JPA layer according to the database to be used.
- Others… The assistant allows selecting from more than 50 dependencies and open source tool integrations within projects made with Spring.
Once the desired parameters are selected, clicking on the «Generate-Ctrl+» button will download a zip file with the Artifact name that will contain the folder with the application structure ready to import from the IDE.
Resources Generated by SpringBoot Initializr
To perform the import, it will suffice to import or open the pom.xml file that comes within the compressed file. The editors will create and configure the classpath and libraries indicated in it so that they are available to the programmer.
The contents of the file will have the following structure:
.
├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── org
│ │ └── eadp
│ │ └── spring
│ │ └── SpringAppApplication.java
│ └── resources
│ ├── application.properties
│ ├── static
│ └── templates
└── test
└── java
└── org
└── eadp
└── spring
└── SpringAppApplicationTests.java
Among the included files, the most important one is MyWebAppApplication.java, which corresponds to the entry point for running the program. This is where the public static void main(String[] arg) method is located, which initializes the entire Spring Boot application.
During the framework startup, Spring scans the rest of the directories or packages hanging from the main method in search of classes marked with annotations that allow the registration of components such as: @Service, @Component, @Repository, and other Spring and Spring MVC annotations like @Controller or @RestController. Note that the package used is com.eadp.web, and this option can be specified in the Spring Initializr wizard.
The next most important file is application.properties, where all the configuration of Spring Boot components is stored, such as which encoding to use (utf-8), whether to use caching in templates, default username and password, etc. At the link common spring boot settings and properties, there is a reference to all existing properties and their initial values.
The next file is MyWebAppApplicationTests.java, where the first example test generated by Initializr is located. Here, the user should add the tests they consider appropriate to apply test-driven development or TDD as much as possible.
The other directories are static, where static resources that the application needs to serve without processing are located. For example, this folder includes CSS files, JavaScript, images, or fonts referenced from HTML.
If the file located in this directory is in a subfolder of static, such as static/css/main.css, Spring Boot will automatically publish it at the URL http://localhost:8080/css/main.css. Therefore, there should be no sensitive information hanging from the static directory because it will be openly accessible.
Finally, the templates folder stores files that allow generating HTML dynamically with a template engine supported by Spring such as Thymeleaf or Freemarker.
How to add functionality to the project
The created project is very simple. If we try to start the main method of the MyWebAppApplication class, we will see how Spring initializes the entire application and listens on port 8080. However, if we direct the browser to that URL, no content will appear. So let's see how we can print some data using dynamic HTML.
For the following lines to work, we must ensure that we have selected at least the dependencies of Spring Web and Thymeleaf, leaving the rest of the options as indicated in the lines above. Let's generate the project again if we haven't done so already, and we will create the first controller that will allow us to add Java code and a Thymeleaf template that will generate the first dynamic HTML documents.
With the project already imported into the editor, let's create a first controller that will be responsible for executing Java code given a URL. In this controller, we will create a variable that can be printed in the template by passing the data via the model.
// contenido del fichero: src/main/java/org/eadp/spring/controller/MyController.java
package org.eadp.spring;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.time.LocalDateTime;
@Controller
public class MyController {
@GetMapping("/")
public String index(Model model) {
model.addAttribute("tstamp", LocalDateTime.now());
return "index";
}
}
The controller registers a method at "/", the root of the site, so that when the application is up and ready to listen for HTTP requests, usually on port 8080, the index method will be executed when the root URL http://localhost:8080/ is requested. At that moment, the method will be executed, adding the current time to a variable named tstamp which is stored in the model, an object that is passed to the view so it can construct the HTML dynamically. In this case, it displays the time when that method was invoked.
Furthermore, as soon as the method of the controller is executed, Spring will pass control to the view with the name index, corresponding to the index.html file in the templates folder, as indicated by the return "index", where it is not necessary to specify the .html extension.
To complete the circle and see the results, we need to create the index.html view with the following content:
// contenido del fichero: src/main/resources/templates/index.html
<!DOCTYPE html>
<html lang="es" xmlns:th="http://www.thymeleaf.org">
<head>
<title>My First Spring Boot App</title>
<style>
html {
font-family: "DejaVu Sans", Arial, Helvetica, sans-serif;
color: #404040;
background-color: #d3d3d3;
}
body {
padding: 5em;
}
</style>
</head>
<body>
<h1>Hello from Spring Boot!</h1>
<p>This page is served at <span th:text="__$_{__tstamp}"></span></p>
</body>
</html>
And we're all set! Now we can start the application again and make the request to http://localhost:8080/. This will result in printing the timestamp when the controller was executed.
Securing a Spring Boot Application
Spring Security is the module of the Spring project used to incorporate access security into applications built with Spring Boot. It allows access control by URL among many other options and is more than sufficient to protect your program.
What is Spring Security?
Spring Security is a library that is part of the Spring project umbrella. Spring has more than 25 subprojects or modules that provide functionality that applications can use if they see fit. In this case, Spring Security aims to group all the functionalities related to user access control in Spring projects.
Access control allows limiting the actions that a specific set of users or roles can perform on the application. In this regard, Spring Security controls invocations to business logic or restricts access to HTTP requests to specific URLs.
To achieve this, the developer must configure the application, indicating to Spring Security how the security layer should behave. One of the great advantages of Spring Security is that it allows for a series of parameterizations and adjustments for a wide range of possibilities, enabling the module to adapt well to almost any scenario of applications developed with Spring IoC or Spring Boot.
If the default implementation of Spring Security is not sufficient, it still provides a series of Java interfaces that the developer can implement to change the behavior of a particular functionality, such as fetching users from a very specific data source.
Whenever possible, it is advisable to use the implementations provided in the Spring Security library, as it is mature code, extensively tested, and is also kept up-to-date by the community whenever a security advisory is released or when new standards are published, as was the case with the release of the HTTP 2 protocol.
In conclusion, Spring Security is the most convenient method for incorporating a security layer where only certain users are allowed access to methods and controllers of a Spring application based on user roles.
Furthermore, being a mature and widely used project, it is possible to find included implementations for the main user security systems deployed in the world of software development or IT systems administration, such as LDAP or Kerberos, among others.
How to Include Spring Security in a Web Application?
Adding Spring Security to any Java Spring project is straightforward, especially if you have used the Spring MVC and Spring IoC auto-configuration layer called Spring Boot. If you intend to incorporate Spring Security into a Java or Spring MVC application, it is advisable to consider migrating to Spring Boot before proceeding with the following steps, as the use of Spring Boot greatly simplifies the configuration actions that developers must undertake to launch any Spring application.
Assuming you have a Spring Boot application managed by Maven up and running, where the pom.xml file has the spring-boot-starter-parent artifact as its parent, the first step is to incorporate the set of dependencies from spring-boot-starter-security. This will transitively bring in the rest of the JAR libraries that Spring needs to apply the required security mechanisms.
By simply including the dependency, if the developer does not perform any additional configuration, Spring Boot by default will secure all access to the application, preventing any unidentified user from invoking any controller. This restrictive mechanism is usually sufficient for small applications where access needs to be restricted generally, but it falls short in applications where there are accessible sections and others protected, depending on whether the user is identified or has a specific role.
Like other configurable aspects of Spring Boot, in the application's configuration file, either application.properties or application.yml, there are several properties that can be adjusted to control the basic behavior of Spring Security.
The most important properties of Spring Security are:
spring.ldap.\* = ... # propiedades correspondientes a integración con LDAP
spring.security.oauth2.\* = ... # parámetros para OAuth2 y JWT
spring.session.\* = ... # configuraciones para la sesión HTTP, con persistencia SQL opcional
spring.security.user.name = user # usuario por defecto
spring.security.user.password = # password por defecto
spring.security.user.roles = # roles por defecto
In this way, just by including the dependency, in the application properties file, a default username and password can be indicated that can be used to access the controllers, and consequently, the different HTML screens of the application. When the user attempts to access any URL of the application, Spring Boot and the HTTP Security Filter will redirect the user to the authentication form, where they will be prompted to enter the username and password to proceed. In this form, the values set in spring.security.user.name and spring.security.user.password must be indicated. If the user has entered the correct values, they are considered authenticated, and regardless of the role, they will be allowed to continue with normal navigation.
It should be noted that the default configuration does not include automatic user registration. If you need users to be able to register automatically, for example with an email, you will need to implement the mechanism by which you trust the information provided by the user and proceed to create the user in the data table or reliable user source used by the application.
How to Protect Sections of the Spring Boot Application?
If global protection of the entire application does not meet your needs, it is probably because there are sections that you want to be accessible while others are protected for a certain number of users. If this is the case, along with the previous step of including the spring-boot-starter-security dependency, you must create a Spring configuration class annotated with @Configuration, where you can specify which sections will be enabled and which will not based on URL patterns. For convenience, it is advisable for this class to extend WebSecurityConfigurerAdapter as it simplifies the implementation.
For example, suppose the web application being developed has a public part consisting of HTML pages, another part protected and accessible to authenticated users (regardless of their role), and finally another section accessible only to the user or users with the administrator role. To carry out this configuration, the accesses must be segmented by URLs in such a way that it allows the following distribution:
- /admin/* URL pattern grouping administrator functionalities
- /user/* Group of functionalities for authenticated users
- /* Rest of public accesses to the application
To ensure that the URL-based access control mechanism works correctly, it is advisable to divide the accesses by URL spaces and include the most restrictive sections first, leaving the more general ones at the end. This simplifies the number of configurations required.
The Spring Security configuration necessary for this scenario would be as follows:
@Configuration
public class ArtecoCmsSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.regexMatchers("/admin/.\*").hasRole("ADMIN")
.regexMatchers("/user/.\*").authenticated()
.anyRequest()
.permitAll()
.and()
.formLogin();
}
}
With this simple configuration, the address space that can reach the web has been separated into three sets, those containing /admin which will require the user to be authenticated and also have at least the ADMIN role. The second section delimited by addresses starting with /user will only require the user to have successfully passed through the login form. And finally, the rest of the URLs will be open for any authenticated or non-authenticated user.
The last configuration line corresponding to formLogin enables the user login form, which will automatically prompt the user if they try to access any URL that requires authentication or a certain ROLE.
Managing Spring Security Users
Having only one user in the application can be useful on certain occasions, although it is certainly a somewhat limited scenario for applications open on the Internet. As a general rule, multiple users will be used, presumably with different access roles to limit the actions each type of user can perform.
To do this, we need to add a user source managed by the application and that will be used in the authentication process by Spring Security. This way, our application can incorporate a user registration mechanism that allows users to authenticate.
For Spring to be able to obtain a user's information during the login process, it will request it from the set of Java classes registered in the Spring context, one of which implements the UserDetailsService interface:
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
This interface has a single method that must be implemented, which is the one that returns the details of a user UserDetails given a username, the one trying to log in to the application. Therefore, it is mandatory to implement a bean with this interface providing an implementation for that method, for example, as follows:
@Component
public class MyUserDetails implements UserDetailsService {
private final UserRepository userRepository;
@Autowired
public ExtranetUserDetails(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<MyUser> userDb = userRepository.findByUsername(username);
if (userDb.isPresent()) {
MyUser user = userDb.get();
List<Permission> permissions = user.getPermissions();
Set<String> roles = new HashSet<>();
if (!CollectionUtils.isEmpty(permissions)) {
for (Permission p : permissions) {
roles.add(p.getRol().name());
}
}
return org.springframework.security.core.userdetails.User
.withUsername(username)
.roles(roles.toArray(new String\[0\]))
.password(user.getPassHash())
.build();
} else {
throw new UsernameNotFoundException("Usuario no encontrado!");
}
}
}
The implementation of this bean will depend on where we have registered the users. Typically, they will be in a database table, so whether it's with native SQL or using JPA with EntityManager or through Spring Data Repositories, we should query the associated row based on the username. Once located, we just need to convert or map that object to one expected by Spring, of type UserDetails.
Finally, in the Spring Security configuration class, we will register our newly created class:
@Configuration
public class ArtecoCmsSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// ... código omitido
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetails()).passwordEncoder(new BCryptPasswordEncoder());
}
@Autowired
public MyUserDetails myUserDetails(UserRepository userRepository) throws Exception {
return new MyUserDetails(userRepository);
}
}
And that's it! With this simple configuration, you have an application with user management capable of authenticating in Spring Security and therefore using all the mechanisms that this security layer offers.
It should be noted that in the example, we have chosen to use a PasswordEncoder which allows storing user passwords encrypted in the database. This approach is a great ally to prevent leaks of important information if any malicious user were to gain access to the user table, preventing them from obtaining user credentials.
When implementing it in your application, don't forget to provide a valid implementation like UserRepository so that the requested user can be obtained. Remember that this information can come from a database or also from a file, or even from a remote service for centralizing users such as LDAP.
Deploying a Spring Boot App with Docker
Deploying a dynamic HTML program made with Spring Boot and Java couldn't be easier with Docker. Below, we explain the steps to follow. Obviously, to be able to deploy a Java application that includes the Spring Boot framework, you will need to have the Java tools installed locally. Although it can also be done with Gradle, we recommend using Maven to package the web. And finally, you will need to have Docker installed.
If you don't have any application made, check the quick start with Spring Boot.
Prepare the Spring Boot application
The first step is to ensure that the application works correctly when packaged in a single jar file. This is easily achievable if we have used Maven as the Java project build tool, making sure we have included the following plugin in the pom.xml
file:
<project attr="...">
<!-- .... -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Specifying the version of the plugin is optional if our project has the spring-boot-starter-parent
umbrella project from Spring Boot as its parent
. If you don't have it, you can include the following fragment, usually at the beginning of the pom.xml file, after project:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/>
</parent>
Having made the aforementioned configuration, the next step is to invoke Maven to verify that the bundle is correct and contains both our compiled application and the jar dependencies contained within.
mvn clean package
java -jar target/app.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _\` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\\__, | / / / /
=========|\_|==============|___/=_/\_/\_/
:: Spring Boot :: (v2.2.4.RELEASE)
The application should start correctly, without displaying any error messages, and remain listening on the specified HTTP port, usually port 8080. Thus, when opening the browser at the URL http://localhost:8080, the content of our project should be displayed.
At this point, we can ensure that the application will run from within a container managed by Docker.
Building the Spring Boot image for Docker
Once it has been verified that the application is packaged as a fat-jar obtained through the Maven packaging process, the next step is to create an image of the application so that it can be used in a virtualized container. To do this, create the Dockerfile
with the necessary steps to provision the image. Fortunately, since we are using a fat-jar that contains all the required dependencies within it, provisioning is reduced to simply installing the Java virtual machine.
Again, the process is very simple as we will start from a base image that already contains the JDK we need. Base images are kept up to date with all active versions of the JDK.
Thus, the Dockerfile
becomes as simple as:
FROM openjdk:8-alpine
ADD target/my-fat.jar /usr/share/app.jar
ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/share/app.jar"]
The first line indicates that we want to use JDK-8 version on a minimal system like Alpine Linux to ensure that the size of the resulting file is as small as possible. The second line adds our application to the resulting package, and finally, the startup command that the container should use once initialized is specified.
Having written the provisioning file, it's time to build the image:
docker build -t my_docker_hub_username/my_image_name:my_image_version .
Important the dot (.) at the end, this indicates the current directory, where the Dockerfile is located. The argument -t user/image:tag
allows naming the image. This can be publicly distributed via Docker Hub, or privately through some Registry like Harbor private such as those available on Amazon Web Services or Google Compute Engine.
The build command will generate output similar to the following:
Sending build context to Docker daemon 86.11MB
Step 1/4 : FROM openjdk:8-alpine
8-alpine: Pulling from library/openjdk
e7c96db7181b: Pull complete
f910a506b6cb: Pull complete
c2274a1a0e27: Pull complete
Digest: sha256:94792824df2df33402f201713f932b58cb9de94a0cd524164a0f2283343547b3
Status: Downloaded newer image for openjdk:8-alpine
---> a3562aa0b991
fetch https://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
Executing busybox-1.29.3-r10.trigger
OK: 123 MiB in 62 packages
Removing intermediate container 8c14d7443332
---> 0c3f73a47bff
Step 3/4 : ENTRYPOINT \["/usr/bin/java", "-jar", "/usr/share/app.jar"\]
---> Running in 0392060d1087
Removing intermediate container 0392060d1087
---> 23655b67c59f
Step 4/4 : ADD target/my-fat.jar /usr/share/app.jar
---> df132592b5f8
Successfully built df132592b5f8
The new image is now available locally and can be confirmed with docker images
.
Starting a Container with Spring Boot
We now have everything we need to start our container running the image built in the previous step. It's important to know that with each new version of the application, we'll need to rebuild the image, as containers should generally be self-sufficient. Everything they need should be included or provisioned in the image to ensure that the environment is stable and reproducible even when using containers, which are highly volatile entities.
Although images are static, at the time of starting a container, we can pass parameters in the form of environment variables or Java system properties, using -Dargument=value
. This is very useful for specifying the Spring profile we want to activate in the container, for example, to use one or another database connection.
While there are many ways to do this, in our case, we'll use an environment variable to indicate the active profile in the application. This should be done by specifying the profile name to use in the SPRING_PROFILES_ACTIVE
environment variable, as indicated in the official Spring Boot documentation.
We also need to specify which port on the container should be open, so that HTTP requests reach the project. Therefore, we need to add an argument to configure that traffic arriving on a local port is redirected to port 8080 (the default for Spring) on the container.
With that said, we just need to launch a container using the previous image and specifying the profile to activate:
docker run -p 8080:8080 --env SPRING_PROFILES_ACTIVE=docker \
my_docker_hub_username/my_image_name:my_image_version
¡Y listos! This statement leaves a container running with our new million-dollar project running locally. This same configuration can be used to deploy the application in an open environment on the Internet, using the container orchestration platform Kubernetes from Google, Amazon, or Microsoft.
Conclusions
Spring Boot has revolutionized Java development, becoming the world's most popular framework. Its flexibility, efficiency, and wide range of tools make it ideal for any web project. Want to make the most of this powerful tool? Visit the website of Arteco Consulting SL and discover how we can help you master Spring Boot and take your development to the next level. Don't get left behind, join the Spring Boot revolution with Arteco Consulting, SL!
INDEX
RELATED
CATEGORIES
java
tutorial
spring boot
Stay Connected
Newsletter
Stay up to date with the latest in technology and business! Subscribe to our newsletter and receive exclusive updates directly to your inbox.
Online Meeting
Don't miss the opportunity to explore new possibilities. Schedule an online meeting with us today and let's start building the future of your business together!
- :D
- :)
- ;]
- :0
- :}
- ;)
- :>
Join the Team
We have a large portfolio of trainees who combine their academic training with experience at Arteco, learning firsthand from those on the front lines. We carry out an intensive training program aimed at rapid incorporation into real development teams.
- :)
- :0
- :D
- ;)
- :]
- :º