Deploying Using Docker
A Docker container is a standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries, and settings. Building a Docker image requires creating a Dockerfile, a text document containing all the commands needed to assemble and run that image.
Creating a Dockerfile for New Vaadin Applications
For a new Vaadin application, you can easily generate a Dockerfile by selecting the
Docker option in Vaadin Start.
This approach makes building and running your container as simple as running the following two commands:
To build your container (assuming your project name is
docker build . -t myapp:latest
To run your container on localhost
docker run -p 8080:8080 myapp:latest
|You need to install Docker Desktop or Docker Server on your machine first, before you can run the above commands.|
Adding a Dockerfile to Existing Vaadin Applications
If your Vaadin project was not generated with a Dockerfile, you can copy and paste the Dockerfile from a fresh Vaadin Start project into your project.
Although we will not cover all of the commands you can use in a Dockerfile here, let us quickly inspect the Dockerfile generated by Vaadin Start to help you customize it in your application.
A typical Dockerfile from Vaadin Start should look similar to the following content.
# (1) FROM maven:3-openjdk-17-slim as build # (2) RUN useradd -m myuser # (3) WORKDIR /usr/src/app/ # (4) RUN chown myuser:myuser /usr/src/app/ # (5) USER myuser # (6) COPY pom.xml ./ # (7) RUN mvn dependency:go-offline -Pproduction # (8) COPY src src COPY frontend frontend COPY package.json ./ COPY package-lock.json* pnpm-lock.yaml* webpack.config.js* ./ # (9) RUN mvn clean package -DskipTests -Pproduction # (10) FROM openjdk:17-jdk-slim # (11) COPY /usr/src/app/target/*.jar /usr/app/app.jar # (12) RUN useradd -m myuser # (13) USER myuser # (14) EXPOSE 8080 # (15) CMD java -jar /usr/app/app.jar
Use the official Maven image as the base image. The variant used is the slim version as specified by the
Add a new user called
myuser, which will be used to execute the container. We do this to prevent the container from running as
root(the default), which could lead to security issues.
Change the current working directory using the
Give the user
myuserthe ownership of the directory
/usr/src/app/in the container volume.
Switch to the
Copy the pom.xml file with the optional
Ensure that all Maven dependencies are installed locally in the container, so that the app build can occur fully offline if needed.
Copy project files.
mvnto build the production package.
Set the image for running the application. In this case, the Dockerfile specifies the
Copy the generated
Highlight that the application should be accessed at port 8080. Note that exposing ports using the
EXPOSEinstruction in a Dockerfile is a way of documenting which ports are used, but does not actually map or open any ports. You need to explicitly expose the port when running the container, for example by using the
-pflag in the
Runs the packaged
Once you have a Dockerfile in the project directory, you can build and run your container using the
docker build and
docker run commands given earlier.
You can find more information on Dockerfile and its available instructions at https://docs.docker.com/engine/reference/builder/.
Building a Docker Image With Restricted Internet Access
In the Dockerfile example provided earlier, creating a production build of the application involves an implicit step by which Vaadin automatically downloads and installs a suitable Node.js distribution. In restricted environments with no (or limited) internet access, this automatic Node installation might fail. In such environments, make sure to install Node from a secured server as a separate step inside the Dockerfile. For example (and depending on your setup), the first few lines of your Dockerfile could look something like the following:
FROM maven:3-openjdk-17-slim as build curl https//my-internal-url/nodejs/custom_setup_16.x RUN apt-get update -qq && apt-get install -qq --no-install-recommends nodejs