如何使用unmanagementBase对添加外部库的Scala项目进行dockerize?

问题描述 投票:0回答:1

我正在使用 opencv_480 查找图像模糊,因为我已使用 unmanagementBase 添加 opencv-480.jar 作为 build.sbt 中的外部库,添加 jar 文件后我能够导入其库并在我的 sbt-shell 中成功使用它们。

但现在我想对我的项目进行 dockerize,因为我使用 sbt-native-packager 创建了我的 scala 项目的镜像,并为其编写了一个 docker compose,当我通过错误执行 docker-compose up 时。

scala-service_1  | Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java480 in java.library.path: [/usr/java/packages/lib, /usr/lib64, /lib64, /lib, /usr/lib]
scala-service_1  |  at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2673)
scala-service_1  |  at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:830)
scala-service_1  |  at java.base/java.lang.System.loadLibrary(System.java:1873)
scala-service_1  |  at blurriness.CheckBlurry$.isImageBlurry(CheckBlurry.scala:11)

这是我的build.sbt

import com.typesafe.sbt.packager.docker._

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.4"

lazy val root = (project in file("."))
  .settings(
    name := "document-verification"
  )

enablePlugins(JavaAppPackaging, DockerPlugin)

Docker / packageName := "document-identification-test"

Docker / version := "0.0.1"
dockerExposedPorts := Seq(8085)

dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")

fork := true

    val openCVNativeLibPath = file("/opencv_lib/native_libs")
unmanagedBase := baseDirectory.value / "opencv_lib"

run / javaOptions += s"-Djava.library.path=${openCVNativeLibPath.getAbsolutePath}"

Docker / daemonUserUid := None
Docker / daemonUser := "root"

dockerBaseImage := "openjdk:11"

我已在 opencv_lib 目录中添加了我的 native-libsopencv-480.jar(在根级别创建的 opencv_lib)。

这是我的主课CheckBlurry.scala

import logfactory.LogFactory.logger
import org.opencv.core.{Core, CvType, Mat, MatOfDouble}
import org.opencv.imgcodecs.Imgcodecs
import org.opencv.imgproc.Imgproc

object CheckBlurry extends App {
  def isImageBlurry(imagePath: String): Boolean = {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME)
    val image = Imgcodecs.imread(imagePath)
    val gray = new Mat()
    Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY)
    val laplacian = new Mat()
    Imgproc.Laplacian(gray, laplacian, CvType.CV_64F)
    val variance = new MatOfDouble()
    Core.meanStdDev(laplacian, new MatOfDouble(), variance)
    println("variance: {}", variance.get(0, 0)(0))
    val threshold = 35
    variance.get(0, 0)(0) < threshold
  }

  val isBlurry = isImageBlurry("src/main/resources/blurImage.png")
  
  if (isBlurry) {
    logger.info("Image is blurry")
  } else {
    logger.info("Image is not blurry")
  }
} 

我的项目图像是(使用 sbt-native-packager 创建)

document-identification-test                   0.0.1           eb7f17b525d1   3 hours ago     736MB

我的docker-compose

version: '3'
services:
  scala-service:
    image: document-identification-test:0.0.1
    ports:
      - "8085:8085"
    volumes:
      - ./opencv_lib:/opencv_lib

我对我的项目进行 docker 化的原因是正确的还是犯了一些错误? 为什么我的项目在 sbt-shell 中运行,但在 docker 容器中抛出错误?

docker scala opencv sbt
1个回答
0
投票

为了在 docker 容器中使用 OpenCV - 您必须首先在其中安装 OpenCV。您可以使用 build.sbt 中的命令来完成此操作。

首先在根目录下创建一个目录opencv4,然后将两个文件粘贴到其中libopencv_java480.soopencv-480.jar(这些文件将位于/usr/local/share/java/opencv4) .

这是更新后的build.sbt:

import com.typesafe.sbt.packager.docker._

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.4"

lazy val root = (project in file("."))
  .settings(
    name := "document-verification"
  )

enablePlugins(JavaAppPackaging, DockerPlugin)

Docker / packageName := "document-identification-test"

Docker / version := "0.0.1"
dockerExposedPorts := Seq(8085)

dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")

fork := true

Universal / javaOptions += "-Djava.library.path=/opencv4"

Docker / daemonUserUid := None
Docker / daemonUser := "root"

dockerBaseImage := "amazoncorretto:11-alpine3.18-jdk"

dockerCommands ++= Seq(
  Cmd("RUN", "apk", "add", "--no-cache", "bash make cmake g++ wget unzip"),
  Cmd("RUN", "apk", "add", "--no-cache", "linux-headers"),
  Cmd("RUN", "wget", "-O", "opencv.zip", "https://github.com/opencv/opencv/archive/4.8.0.zip"),
  Cmd("RUN", "unzip", "opencv.zip && rm opencv.zip"),
  Cmd("RUN", "mkdir", "-p", "build && cd build && cmake ../opencv-4.8.0 && make -j4 && make install")
)

这是 docker compose:

version: "3"

services:
  testservice:
    image: document-identification-test:0.0.1
    container_name: document-verification
    volumes:
      - ./src/main/resources:/src/main/resources
      - ./opencv4:/opencv4
    ports:
      - "8085:8085"
    networks:
      - verification-network

networks:
  verification-network:
    driver: bridge
© www.soinside.com 2019 - 2024. All rights reserved.