> Markdown version of [Build a Project](https://vaadin.com/docs/v24/getting-started/build). Section index: [llms.txt](https://vaadin.com/docs/v24/getting-started/llms.txt)

# Build a Project

Up to this point, the walking skeleton has been [running in development mode](https://vaadin.com/docs/v24/getting-started/run.md). Once you’ve added meaningful features, you can deploy your application to production. To do that, you have to make a production build. The build gathers necessary frontend resources and dependencies. It then transpiles, minimizes and bundles them to make the application load faster.

## <a id="make-a-production-build"></a>Make a Production Build

In the walking skeleton, you use the Vaadin Maven plugin to make a production build. You do this by activating the `production` profile, like this:

**macOS / Linux**

```bash
./mvnw clean package -Pproduction
```

**Windows**

```powershell
mvnw clean package -Pproduction
```

Once the build has finished, check the `target` directory. If your skeleton was named `my-application`, you should find a file called `my-application-1.0-SNAPSHOT.jar`.

The `production` profile not only builds the frontend, but also excludes the development server bundle since it contains features that aren’t used in production.

## <a id="build-a-docker-image"></a>Build a Docker Image

The walking skeleton includes a `Dockerfile` that allows you to package your application as a Docker image.

> **Important: Install Docker**
>
> You must install Docker on your system before you can build an image.

Run the following command from your project root to build the image:

```terminal
docker build -t my-application:latest .
```

This command builds your application in production mode and produces a Docker image tagged `my-application:latest`.

### <a id="building-with-commercial-components"></a>Building with Commercial Components

If your application uses commercial components, you need a [licence key](https://vaadin.com/docs/v24/flow/configuration/licenses.md).

When building locally with Maven, the Vaadin Maven plugin detects the license automatically. For Docker builds, you must pass the key explicitly as a secret:

**macOS / Linux**

```bash
docker build -t my-application:latest --secret id=proKey,src=$HOME/.vaadin/proKey .
```

**Windows**

```powershell
docker build -t my-application:latest --secret "id=proKey,src=$($env:USERPROFILE)\.vaadin\proKey" .
```

If you need to use an offline key, you can pass it like this:

**macOS / Linux**

```bash
docker build -t my-application:latest --secret id=offlineKey,src=$HOME/.vaadin/offlineKey .
```

**Windows**

```powershell
docker build -t my-application:latest --secret "id=offlineKey,src=$($env:USERPROFILE)\.vaadin\offlineKey" .
```

> **Note: A Peek Under the Hood**
>
> The `--secret` option works because the provided `Dockerfile` in the walking skeleton mounts the files, parses them and passes them on to Maven:
>
> ```docker
> # (Previous build steps omitted for brevity)
> # ...
>
> RUN --mount=type=cache,target=/root/.m2 \
>     --mount=type=secret,id=proKey \
>     --mount=type=secret,id=offlineKey \
>     sh -c 'PRO_KEY=$(jq -r ".proKey // empty" /run/secrets/proKey 2>/dev/null || echo "") && \
>     OFFLINE_KEY=$(cat /run/secrets/offlineKey 2>/dev/null || echo "") && \
>     ./mvnw clean package -Pproduction -DskipTests -Dvaadin.proKey=${PRO_KEY} -Dvaadin.offlineKey=${OFFLINE_KEY}'
> ```
>
> For more information about build secrets in Docker, see the [Docker documentation](https://docs.docker.com/build/building/secrets/).
