Dockerfile не может создать приложение с помощью Maven — для этой сборки не указаны цели

#spring #spring-boot #docker #maven #docker-compose

#spring #spring-boot #docker #maven #docker-compose

Вопрос:

Я разрабатываю приложение Spring Boot с несколькими службами передачи данных, но я изо всех сил пытаюсь заставить его работать как контейнерное приложение. Это структура папок проекта:

 myapp/
├── src/
│   └── ...
├── docker-compose.yml
├── Dockerfile
├── init-mongo.js
└── pom.xml
  

И это содержимое Dockerfile, которое я придумал после прочтения руководств и официальной документации:

 #
# Build stage
#
FROM maven:3.5-jdk-8 AS build
COPY init-mongo.js /docker-entrypoint-initdb.d/
COPY src /app/src/
COPY pom.xml /app/
RUN mvn -f /app/pom.xml clean package

#
# Package stage
#
FROM openjdk:8-alpine
COPY --from=build /app/target/*.jar /usr/app/app.jar
ENTRYPOINT ["java","-jar","/usr/app/app.jar"]
  

И это мой docker-compose.yml:

 version: '3'
services:
  app-mongodb:
    container_name: app-mongodb
    image: mongo
    environment:
      MONGO_INITDB_DATABASE: appdb
      MONGO_INITDB_ROOT_USERNAME: mongodbusr
      MONGO_INITDB_ROOT_PASSWORD: mongodbpwd
    volumes:
      - mongodata:/usr/share/mongodb/data
    ports:
      - "27017:27017"
    hostname: app-mongodb

  app-mariadb:
    container_name: app-mariadb
    image: mariadb
    environment:
      MYSQL_DATABASE: appdb
      MYSQL_ROOT_PASSWORD: mariadbpwd
      MYSQL_ROOT_HOST: '%'
    ports:
      - "3306:3306"
    restart: always

  app-elasticsearch:
    container_name: app-elasticsearch
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.6
    volumes:
      - esdata:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    hostname: app-elasticsearch

  app:
    build: .
    ports:
      - 8080:8080
    depends_on:
      - app-mariadb
      - app-mongodb
      - app-elasticsearch

volumes:
  mongodata:
  esdata:
  

Дело в том, что это должно работать, но я продолжаю получать ошибку Maven при каждом запуске docker-compose up команды:

 myapp_1            | [INFO] Scanning for projects...
myapp_1            | [INFO] ------------------------------------------------------------------------
myapp_1            | [INFO] BUILD FAILURE
myapp_1            | [INFO] ------------------------------------------------------------------------
myapp_1            | [INFO] Total time: 0.216 s
myapp_1            | [INFO] Finished at: 2020-10-24T19:25:15Z
myapp_1            | [INFO] ------------------------------------------------------------------------
myapp_1            | [ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal>
 or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate
-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, pr
ocess-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clea
n, pre-site, site, post-site, site-deploy. -> [Help 1]
myapp_1            | [ERROR]
myapp_1            | [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
myapp_1            | [ERROR] Re-run Maven using the -X switch to enable full debug logging.
myapp_1            | [ERROR]
myapp_1            | [ERROR] For more information about the errors and possible solutions, please read the following articles:
myapp_1            | [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoGoalSpecifiedException
  

Чего мне не хватает?

РЕДАКТИРОВАТЬ: я попытался явно упаковать файл JAR, а затем просто скопировать его в конечный контейнер, отредактировав содержимое файла Dockerfile, как это было предложено @BeppeC:

 FROM openjdk:8-alpine
COPY target/*.jar /usr/app/app.jar
ENTRYPOINT ["java","-jar","/usr/app/app.jar"]
  

Он по-прежнему выдает ту же ошибку, поэтому кажется, что что-то запускает сборку mvn, о которой я не знаю.

EDIT2: я подозреваю, что причиной ошибки «нет целей» может быть что-то не так с моим 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.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>it.clsoft</groupId>
    <artifactId>myapp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>myapp</name>
    <description>My web app</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.2.10.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.bitbucket.b_c</groupId>
            <artifactId>jose4j</artifactId>
            <version>0.7.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.19</version>
        </dependency>

        <dependency>
            <groupId>org.tukaani</groupId>
            <artifactId>xz</artifactId>
            <version>1.8</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

        <dependency>
            <groupId>com.github.sisyphsu</groupId>
            <artifactId>dateparser</artifactId>
            <version>1.0.4</version>
        </dependency>

        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
            <version>2.4.1</version>
        </dependency>

        <dependency>
            <groupId>com.github.darrachequesne</groupId>
            <artifactId>spring-data-jpa-datatables</artifactId>
            <version>5.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.github.darrachequesne</groupId>
            <artifactId>spring-data-mongodb-datatables</artifactId>
            <version>1.0.3</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>2.4.4</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.12.4</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.owasp.esapi</groupId>
            <artifactId>esapi</artifactId>
            <version>2.2.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.7</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.7</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </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.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

Мне кажется, что все в порядке, но я снова работаю над учебниками, поэтому, возможно, я пропустил что-то важное.

Комментарии:

1. Выглядит нормально, я бы попытался использовать другой базовый образ (maven: 3.6.0-jdk-11-slim). Я лично предпочитаю создавать Jar с помощью моей IDE (или конвейера), а затем создавать образ Docker, который включает в себя uber-jar

2. @BeppeC Я должен быть в состоянии пропустить дополнительный шаг сборки, по крайней мере, многие учебные пособия, похоже, указывают на это. А также я предпочитаю просто вводить docker-compose up и, возможно, просто переключать контекст для развертывания на другой хост. К сожалению, я уже пытался изменить базовый образ mvn, но выдает тот же точный результат.

3. Я бы определенно рассмотрел возможность тестирования / сборки приложения в IDE, когда у вас есть jar, затем создайте образ Docker

4. @BeppeC безуспешно пытался, см. Мое РЕДАКТИРОВАНИЕ

5. Чувак, это странно. Когда возникает ошибка? При создании образа Docker? Пожалуйста, поделитесь всем файлом Dockerfile и стеком ошибок.

Ответ №1:

Работает для меня, если я перейду с:

 #
# Build stage
#
FROM maven:3.5-jdk-8 AS build
COPY init-mongo.js /docker-entrypoint-initdb.d/
COPY src /app/src/
COPY pom.xml /app/
RUN mvn -f /app/pom.xml clean package
  

Для:

 #
# Build stage
#
FROM maven:3.5-jdk-8 AS build
COPY init-mongo.js /docker-entrypoint-initdb.d/
COPY src /app/src/
COPY pom.xml /app/
WORKDIR /app
RUN mvn clean package
  

Основная проблема, которую я видел, заключалась в том, что в текущем рабочем каталоге не было pom.. / (корневой каталог).. однако установка значения WORKDIR на /app отлично сработала.

Комментарии:

1. Я попытался изменить раздел этапа сборки в моем Dockerfile, как вы предложили, к сожалению, безуспешно: ошибка все та же. Думаю, я, возможно, пропустил что-то важное в моем pom.xml файл, см. Мою ПРАВКУ 2.