Сборка режима производства Vaadin + Spring Boot с ошибкой во время выполнения: не удалось определить инструмент 'npm' - PullRequest
1 голос
/ 10 ноября 2019

ОБНОВЛЕНИЕ РЕШЕНИЯ Эта ошибка, по-видимому, и была причиной проблемы: https://github.com/vaadin/flow/issues/6657

Во время развертывания исправления отмеченный ответ можно использовать в качестве обходного пути

Фон

Я нахожусь в процессе создания докеризованного портала Spring Boot + Vaadin portal для моего IoT проекта .

Проблема

Портал хорошо работает с моей машины в режиме разработки Vaadin, с установленным npm, но я не могу получить правильную настройкудля создания облегченной банки развертывания, которая уже содержит все сгенерированные компоненты переднего плана.

Когда я запускаю службу в контейнере Docker, я получаю сообщение об ошибке, что он не может найти npm, но я предполагаю, что он не нужен для производственного развертывания

at com.vaadin.flow.server.startup.DevModeInitializer.initDevModeHandler(DevModeInitializer.java:327)
    at com.vaadin.flow.spring.VaadinServletContextInitializer$DevModeServletContextListener.contextInitialized(VaadinServletContextInitializer.java:323)
    ... 46 common frames omitted
Caused by: com.vaadin.flow.server.ExecutionFailedException: 

Failed to determine 'npm' tool.
Please install it either:
  - by following the https://nodejs.org/en/download/ guide to install it globally
  - or by running the frontend-maven-plugin goal to install it in this project:
  $ mvn com.github.eirslett:frontend-maven-plugin:1.7.6:install-node-and-npm -DnodeVersion="v12.13.0" 

Файл Docker без npm:

FROM openjdk:11-jre-slim

ARG PROJECT
ARG SERVICE_PORT
ARG JAR_FILE

EXPOSE ${SERVICE_PORT}

RUN mkdir /${PROJECT}
WORKDIR /${PROJECT}

ADD target/${JAR_FILE} ./app.jar

CMD ["java","-jar","app.jar"]

pom.xml (обновлено!)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.tlvlp</groupId>
    <artifactId>iot-portal</artifactId>
    <version>0.0.2</version>
    <name>iot-portal</name>
    <description>tlvlp IoT server portal</description>

    <properties>
        <java.version>11</java.version>
        <vaadin.version>14.0.12</vaadin.version>
        <dockerfile.maven.version>1.4.13</dockerfile.maven.version>
        <flow.server.prod.version>2.0.17</flow.server.prod.version>
        <!--    DOCKER IMAGE ARGS   -->
        <docker.project.repository>tlvlp/iot-portal</docker.project.repository>
        <service.port>8600</service.port>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>

    <profiles>
        <profile>
            <id>prod</id>
            <properties>
                <activatedProperties>prod</activatedProperties>
                <vaadin.productionMode>true</vaadin.productionMode>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <dependencies>
                <dependency>
                    <groupId>com.vaadin</groupId>
                    <artifactId>flow-server-production-mode</artifactId>
                    <version>${flow.server.prod.version}</version>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>flow-maven-plugin</artifactId>
                        <version>${flow.server.prod.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>build-frontend</goal>
                                    <goal>copy-production-files</goal>
                                    <goal>package-for-production</goal>
                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>com.spotify</groupId>
                        <artifactId>dockerfile-maven-plugin</artifactId>
                        <version>${dockerfile.maven.version}</version>
                        <executions>
                            <execution>
                                <id>prod</id>
                                <goals>
                                    <goal>build</goal>
                                    <goal>push</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <repository>${docker.project.repository}</repository>
                            <tag>${project.version}</tag>
                            <tag>latest</tag>
                            <buildArgs>
                                <PROJECT>${project.groupId}.${project.artifactId}</PROJECT>
                                <SERVICE_PORT>${service.port}</SERVICE_PORT>
                                <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
                            </buildArgs>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>dev</id>
            <properties>
                <activatedProperties>dev</activatedProperties>
                <vaadin.productionMode>false</vaadin.productionMode>
            </properties>
        </profile>
    </profiles>

</project>

application.properties

spring.profiles.active=@activatedProperties@

application-prod.properties

vaadin.compatibilityMode=false
vaadin.servlet.productionMode=true

Я ценю любые рекомендации:)

Весь код можно найти наглавный филиал публичного репозитория проекта: https://github.com/tlvlp/iot-portal

Ответы [ 2 ]

0 голосов
/ 16 ноября 2019

Мне наконец-то удалось найти решение проблемы. Это было правильное предположение, что npm не требуется для запуска производственного приложения. Что было неясно даже из официального руководства , что хотя добавление следующего свойства в профиль сборки prod заполняет файл встроенного jar, но

само по себе НЕ запускаетVaadin для запуска в производственном режиме (по крайней мере, не вместе с SpringBoot):

<vaadin.productionMode>true</vaadin.productionMode>

Решение:

В конечном итоге решение проблемы заключается в назначениизначение того же параметра в файле свойств SpringBoot. Затем он начал использовать ресурсы, созданные с помощью npm во время сборки.

Вот файл application.properties (общий для файлов свойств dev и prod).

spring.profiles.active=@spring.activatedProperties@
vaadin.productionMode=@vaadin.productionMode@
vaadin.compatibilityMode=false

Вот полный и обновленный и работающий pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.tlvlp</groupId>
    <artifactId>iot-portal</artifactId>
    <version>0.0.2</version>
    <name>iot-portal</name>
    <description>tlvlp IoT server portal</description>

    <properties>
        <java.version>11</java.version>
        <vaadin.version>14.0.12</vaadin.version>
        <dockerfile.maven.version>1.4.13</dockerfile.maven.version>
        <flow.server.prod.version>2.0.17</flow.server.prod.version>
        <!--    DOCKER IMAGE ARGS   -->
        <docker.project.repository>tlvlp/iot-portal</docker.project.repository>
        <service.port>8600</service.port>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>

    <profiles>
        <profile>
            <id>prod</id>
            <properties>
                <spring.activatedProperties>prod</spring.activatedProperties>
                <vaadin.productionMode>true</vaadin.productionMode>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <dependencies>
                <dependency>
                    <groupId>com.vaadin</groupId>
                    <artifactId>flow-server-production-mode</artifactId>
                    <version>${flow.server.prod.version}</version>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>flow-maven-plugin</artifactId>
                        <version>${flow.server.prod.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>prepare-frontend</goal>
                                    <goal>build-frontend</goal>

                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>com.spotify</groupId>
                        <artifactId>dockerfile-maven-plugin</artifactId>
                        <version>${dockerfile.maven.version}</version>
                        <executions>
                            <execution>
                                <id>prod</id>
                                <goals>
                                    <goal>build</goal>
                                    <goal>push</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <repository>${docker.project.repository}</repository>
                            <tag>${project.version}</tag>
                            <tag>latest</tag>
                            <buildArgs>
                                <PROJECT>${project.groupId}.${project.artifactId}</PROJECT>
                                <SERVICE_PORT>${service.port}</SERVICE_PORT>
                                <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
                            </buildArgs>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>dev</id>
            <properties>
                <spring.activatedProperties>dev</spring.activatedProperties>
                <vaadin.productionMode>false</vaadin.productionMode>
            </properties>
        </profile>
    </profiles>

</project>
0 голосов
/ 16 ноября 2019

Поскольку у меня недавно была такая же борьба, у меня есть следующее решение. Самый простой способ, которым я нашел Java и Nodejs / NPM - это установить его в базовый образ java. Это не будет маленькое изображение докера. mvn clean package -Pproduction корневой каталог vaadin. Затем отредактируйте Dockerfile, включив в него установку следующим образом: https://gitlab.com/snippets/1913782

Затем соберите и запустите образ. Время сборки и размер изображения значительно увеличатся. Я хотел бы увидеть некоторые предложения или дополнительный прогресс в этом процессе. Переход с Vaadin8 на 14 привел к многочисленным головным болям, связанным с необходимостью понять, почему не-Java-вещи ломаются.

...