> Markdown version of [Docker Deployment](https://vaadin.com/docs/latest/flow/production/docker). Section index: [llms.txt](https://vaadin.com/docs/latest/flow/llms.txt)

# Deploying Using Docker

A [Docker container](https://docs.docker.com/get-started/docker-overview/) is a standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries, and settings. A `Dockerfile` contains the instructions for building the image that the container runs.

To build and run the image, you need [Docker Desktop](https://docs.docker.com/desktop/) or [Docker Engine](https://docs.docker.com/engine/install/).

## <a id="building-inside-docker"></a>Building Inside Docker

Projects downloaded from [Vaadin Start](https://start.vaadin.com) include a `Dockerfile` that runs the Maven build inside Docker. You don’t need to build the application before building the image, and the machine that builds the image doesn’t need Java.

To build the image and run it on port 8080 with a memory limit of 2 GB, run the following commands in the project directory:

```terminal
docker build -t my-app .
docker run -p 8080:8080 -m 2g my-app
```

The `Dockerfile` has three stages:

1. The first stage provides the `jq` tool, which the build stage uses to read a license key.

2. The build stage uses an Eclipse Temurin JDK image, and runs `./mvnw clean package -DskipTests`, so the tests don’t run. It keeps the downloaded Maven dependencies in a build cache between builds. It then splits the JAR into layers, so that the dependencies end up in their own image layer.

3. The runtime stage uses an Eclipse Temurin JRE image based on Alpine Linux. It copies the layers from the build stage, and runs the application as an unprivileged user, with the `prod` Spring profile active.

The images are for the Java version that you selected on Vaadin Start. The JVM may use 75% of the container’s memory for the heap, instead of its default of 25%. Always set a memory limit for the container, for example with the `-m` option of `docker run`. Without a limit, the JVM sizes its heap according to the memory of the whole host.

The project also contains a `.dockerignore` file, which keeps local build output, the `node_modules` directory, the Git repository, and IDE files out of the build context.

The project contains no configuration for the `prod` profile. To add production settings, put them in `src/main/resources/application-prod.properties`. When the profile is active, Spring Boot reads this file in addition to `application.properties`, and its values take precedence.

### <a id="passing-a-license-key"></a>Passing a License Key

If the build needs a license key, as described in [License Validation & Troubleshooting](https://vaadin.com/docs/latest/flow/configuration/licenses.md), pass the key file as a [build secret](https://docs.docker.com/build/building/secrets/). The secret is available only while the Maven build runs, and isn’t stored in the image. The `Dockerfile` reads an offline key from a secret with the ID `offlineKey`, and a pro key from a secret with the ID `proKey`:

```terminal
docker build --secret id=offlineKey,src=$HOME/.vaadin/offlineKey -t my-app .
```

## <a id="building-from-a-jar"></a>Building from a JAR

If you build the JAR outside Docker, for example on a CI server, a `Dockerfile` that copies the JAR into a Java runtime image is enough:

`Dockerfile`

```dockerfile
FROM eclipse-temurin:25-jre
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
```

This `Dockerfile` works for applications that are packaged as an executable JAR, such as Spring Boot applications. Use the image tag that matches the Java version of your project.

Make a [production build](https://vaadin.com/docs/latest/flow/production/production-build.md) of the JAR first, then build and run the image:

```terminal
mvn clean package
docker build -t my-app .
docker run -p 8080:8080 my-app
```

[Build a Container Image](https://vaadin.com/docs/latest/building-apps/production/container.md) extends this `Dockerfile` with image layers, an unprivileged user, and memory settings for the JVM, and explains why each of them matters.

For all instructions that a `Dockerfile` can contain, see the [Dockerfile reference](https://docs.docker.com/reference/dockerfile/).

`08DE0256-3D68-4F05-9092-F8ACB1A16C64`
