Как ускорить сборку sbt scala в докере? - PullRequest
0 голосов

У меня есть файл докера с:

FROM amazonlinux:2017.03

ENV SCALA_VERSION 2.11.8
ENV SBT_VERSION 0.13.13

# Install Java8 
RUN yum install -y java-1.8.0-openjdk-devel

# Install Scala and SBT
RUN yum install -y https://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.rpm
RUN yum install -y https://dl.bintray.com/sbt/rpm/sbt-0.13.13.rpm
RUN sbt sbtVersion

COPY . /root  
WORKDIR /root  

# Exposing port 80
EXPOSE 80

RUN sbt compile
CMD sbt run

И файл конфигурации sbt с:

name := "hello"

version := "1.0"

scalaVersion := "2.11.8"

libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.5"
libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.11" % "2.9.5"

Каждый раз, когда я собираю docker container sbt, заново загружаю библиотеку Джексона. Как я могу ускорить этот процесс, может выполнить часть файла sbt перед компиляцией.

До того, как я добавлю RUN sbt sbtVersion в Dockerfile, sbt полностью загрузился, а после того, как я добавил эту команду, кэшировался и не запускался каждый раз при сборке контейнера Docker.

Может быть, есть такие же трюки с кэшированием в загрузке докеров библиотек в sbt?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Вы можете обратиться к решению travis:

.travis.yaml:

# These directories are cached to S3 at the end of the build
cache:
  directories:
    - $HOME/.ivy2/cache
    - $HOME/.sbt/boot/

Travis создаст резервную копию двух вышеуказанных папок на s3, а затем каждый раз перед перестройкой пользователя будет извлекать две папки из кэша.

Итак, мы можем знать, как можно не загружать jackson library снова, можно отделить папку .ivy2 & .sbt и поместить их в нечто вроде кэша.

В вашей ситуации, я думаю, лучшее решение - это сохранить их в базовом изображении, базовое изображение Dockerfile может просто совпадать с тем, которое вы используете сейчас (конечно, вы можете упростить его, просто добавив определение библиотеки Джексона в build.sbt цель просто хочет, чтобы у .ivy2 была библиотека Джексона), затем, например, пометить его как mybaseimage: v1

Тогда Dockerfile вашего нового проекта может использовать base mybaseimage:v1, поскольку mybaseimage уже имеет библиотеку в .ivy2 & .sbt, поэтому нет необходимости загружать jackson снова каждый раз, когда вы создаете Dockerfile вашего проекта.

Решение может быть уродливым, но я думаю, что это могло бы стать обходным путем, просто к вашему сведению.

0 голосов
/ 17 января 2019

Во-первых, вам не нужно устанавливать RPM-версию scala, поскольку SBT сам загружает Scala для вас (какая бы версия не была настроена в вашей сборке).

Во-вторых, каждая команда RUN создает новый слой, которого вы обычно избегаете. Объедините их:

RUN cmd1 \
  && cmd2 \
  && cmd3

Почему вы хотите создать образ для каждой из ваших сборок? Это кажется расточительным. Обычно вы создаете свои вещи вне образа Docker и только упаковываете результаты.

Мой совет - использовать плагин sbt-native-packager SBT с Docker интеграцией , чтобы просто создать образ из ваших артефактов после того, как вы их построите. Таким образом, вам понадобится только JRE в вашем изображении, а не JDK, не SBT. Кроме того, вам не нужно ждать инициализации SBT при запуске образа.

Вы можете использовать многоэтапные сборки , если у вас установлена ​​новая версия Docker.

...