Файл Docker рассматривается и обрабатывается полностью до того, как будут рассмотрены большинство других параметров в файле docker-compose.yml
. В частности, сборка образа никогда не видит volumes:
из Docker Compose setup (он также не может видеть environment:
переменные или любые сетевые настройки, включая default
network).
Это означает, что во время сборки (потому что это директива RUN
), вы пытаетесь запустить sbt run
на пустом анонимном томе. Это приводит к ошибке «no main class», которую вы получаете.
Для языков на основе JVM типичной настройкой является компиляция приложения на хосте, а затем COPY
(переносимый) .jar
файл в ваше изображение. Плагин sbt-native-packager
может на самом деле сделать все это за вас ; если вы предпочитаете делать это вручную, плагин sbt-assembly
может создать «толстый» .jar
, содержащий все зависимости приложения. Затем вы получаете типичный минимальный Dockerfile JVM
FROM openjdk:8
COPY target/scala-2.13/my-app-*.jar /my-app.jar
CMD ["java", "-jar", "/my-app.jar"]
Если вы хотите скомпилировать приложение в Dockerfile, вам нужно COPY
приложение в нем и установить CMD
для запуска приложения, когда контейнер запускается (не во время сборки).
FROM hseeberger/scala-sbt:8u222_1.3.5_2.13.1
WORKDIR /www/app
# Copy the application source in.
COPY ./ ./
# Build it.
RUN sbt compile
# Set the command to run and other metadata when the container starts.
EXPOSE 8000 8080
CMD sbt run
(Вы также можете использовать многоступенчатую сборку , чтобы объединить эти два файла Docker: первый COPY
исходное дерево и sbt compile
это, затем на втором этапе COPY --from=build
только файл jar в образе JRE-only.)
Из-за инструкции COPY
необходимо установить контекст сборки равным root исходного дерева. (Возможно, было бы легче переместить Dockerfile
и docker-compose.yml
в хранилище root рядом с файлом build.sbt
.)
version: "3.3"
services:
app:
build:
context: ..
dockerfile: docker/Dockerfile
ports:
- "8080:8080"
- "8000:8000"
# No need for volumes:, source code is already in the image
В принципе, вы можете привязать код приложения к вашему компьютеру. как у вас было в вопросе, и команда sbt run
перекомпилирует его. Вам не нужна директива VOLUME
в вашем Dockerfile. Вероятно, вам будет проще выполнять повседневную разработку в среде JDK / sbt хоста.