Last updated by Sascha Brockel 08 October 2023

In the era of microservices, Docker is considered the non plus ultra. Even front-end applications like Angular or back-end applications like Spring Boot (Java) can be easily used in Docker containers. When presenting an application to a larger group, this can come in handy.

When using your own server, the applications can be easily deployed and made available to everyone. This way, everyone can already familiarize themselves with the application during a presentation.

For the following example some programs and services are needed:

  • Gradle
  • Java 8 (JDK)
  • MySQL 8
  • Node.js (version 10.13 or newer)
  • Docker

You have to make sure in Angular that you can still set the connections between the Docker containers for deployment. The Docker containers communicate with each other on an internal network and thus have different IPs.

This is made possible in Docker by environment variables, but you can't use them as easily as, say, Spring Boot by using a @Value annotation can set.

So to make the whole thing possible a new script must be created in the folder /assets to be created and included. You name the file env.js with the following content:

The value specified here for apiUrl represents the default value if the variable is not set directly by Docker. Here I would like to point out again that all the code in the below in the Conclusion linked GitHub repositories.

Now, in order for the newly created JavaScript to be executed when Angular is launched, you must add it to the index.html add

Now you need to modify the actual environment files of Angular to enable setting by Docker with them. To do this, in the folder /environments the environment.ts be supplemented as follows. The same should also apply to the be done for productive operation. However, you must of course ensure that production: true is.

Due to this change, the values now come from our previously created script env.js. Currently, however, there is still no possibility these apiUrl but also dynamically for deployment.

Docker needs a way to access a predefined variable name. To enable this, you also need to create a new variable name in the folder /assets another file named env.template.js create. From the basic principle the file looks like the env.js only with the difference that we now specify the variable name (here API_URL).

With the command envsubst you can then add the variables that are set in the template to the env.js insert. So for example with a specification of API_URL: http://localhost:8080. The end result will look like this:

At user.service.ts environment must be imported as a variable and can then be used as a normal declaration. Thus it is possible to access the apiUrl and the stored path or address will be used.

For this you need a Dockerfile. You can also find this in the GitHub repository in the folder docker.

First of all node is used as a basis. Then all dependencies of the project are installed and the whole is built directly. The configuration is set to productive mode. Generally, building in advance allows less load for the person who downloads the Docker image and wants to start it. Because nothing has to be built anymore. Above all, this ensures significantly smaller image sizes.

So I used libraries like Angular Material or FontAwesome, but still only achieved an image size of 10 MB (see Otherwise the entire node_modules folders are packed into the image. Thus, sizes of 400-700 MB would be reached quickly.

To make the built Angular application now also callable you have to create nginx as a web server still configure accordingly. For this purpose the nginx-custom.conf (can be found in the frontend folder).

The requests to the URL's are always forwarded, unless the URL does not exist. Then the user is always redirected to the home page.

Since you usually want to run a web application via a direct URL without specifying a port, enter the port EXPOSE 80 on. Finally, the environment variables are overwritten as described above.

With this, all arrangements are now made to connect the Angular frontend to any backend for deployment.

In Spring Boot, the whole thing is a bit less complicated, since all the prerequisites for dynamically setting variables already exist out of the box.

REST requests take place via the controller and therefore it must also contain our variable. The whole thing is enabled in the UserController by the @Value Annotation.

This serves only as a small digression, since this is not used in this sample project. However, it has the same function as setting in Angular. Thus, another Spring Boot Server could possibly be addressed.

So that the variable can now also be set, the value specified in the @Value annotation now also appears in the properties file. can be declared with a default value.

All itself in can be overwritten in Docker by specifying the corresponding environment variable. Thus also the later in section Docker necessary declaration of the database connection.

The last part to consider is the tiresome topic of CORS. Basically, CORS is important for security, but often not so trivial to set up. It determines which web applications from another domain should be able to access the server.

According to my current knowledge, it is unfortunately not possible to set the CORS configuration for deployment as well. This has to be done before building the image. We can find the configuration in the WebSecurityConfig.

Important for our project is the point config.setAllowedOrigins(). Hereby we define which domains are now allowed to send a request to the server. In our case actually only localhost:4200 for the development, then localhost for use in Docker on Windows. As an example then also the specification from which inquiries could then be sent.

Of course, CORS settings can still be made at controller level with the @CrossOrigin annotation can be taken. It is important that there is a CorsFilter is, since with a CorsConfigurationSource the settings do not work for this sample project.

Last but not least, we get to linking and running the whole thing in Docker. I will skip the Dockerfile of the backend in the explanation, because there are no special features there.

The Angular section is very trivial. The container runs as long as it is not stopped. The port is as already described in the Frontend section mentions 80 in order to not need to specify the port in the browser. Now the environment variable comes into play. API_URL is defined and points to the address of the Spring Boot container. The network is used for the exchange between the containers.

Spring Boot looks very similar. Here we then set in the environment mainly the variables that set the database connection. It is important that the variables match those used to create the database.

How to vote spring.datasource.username and MYSQL_USER so that the connection can be established in the first place. It becomes special again with the exact declaration of the database. MYSQL_DATABASE: dockerSpringAngular specifies the name of the database. But to use it then we have to specify the corresponding spring.datasource.url adjust. Here is a comparison of the line in and in the docker-compose.yml.

Instead of localhost we now enter the name of the database container (db) to establish the connection. In addition, the other Docker-level attributes are dropped.

There is to note that with the current docker-compose.yml, no data is stored as no volumes have been specified.

Now you have learned how to deploy Angular to Docker using Spring Boot. Here how to define each API endpoint when defining Docker services and what customizations need to be made for this.

Once the prerequisites are in place, it is easy to make adjustments to the deployment such as changing the server. Feel free to try it out for yourself.

The whole thing should then look like this in the browser. In the individual project folders of the GitHub repository you will find README's with documentation and DeepL access to individual files.
Source for setting the Angular variables:

You can find the complete source code on GitHub.
The Docker images are available in the DockerHub.


Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.