Reg Mem
Reg Mem

Reputation: 621

Adding custom folder to Docker using sbt-native-packager in Play JPA project

I'm working on a JPA + Playframework 2.5.x project which I package it as Docker image.

I want to forcibly add all the files except one file (META-INF/persistence.xml) under conf folder to docker output

Currently I have done the following:

mappings in Docker += file("conf/base/application.conf") -> "opt/docker/conf/base/application.conf"
mappings in Docker += file("conf/base/default-client.conf") -> "opt/docker/conf/base/default-client.conf"
mappings in Docker += file("conf/prod/application.conf") -> "opt/docker/conf/prod/application.conf"
mappings in Docker += file("conf/prod/logback.xml") -> "opt/docker/conf/prod/logback.xml"
mappings in Docker += file("conf/stage/application.conf") -> "opt/docker/conf/stage/application.conf"
mappings in Docker += file("conf/stage/logback.xml") -> "opt/docker/conf/stage/logback.xml"
mappings in Docker += file("conf/local/application.conf") -> "opt/docker/conf/local/application.conf"
mappings in Docker += file("conf/local/logback.xml") -> "opt/docker/conf/local/logback.xml"
mappings in Docker += file("conf/routes") -> "opt/docker/conf/routes"
mappings in Docker += file("conf/ValidationMessages.properties") -> "opt/docker/conf/ValidationMessages.properties"

I am sure this is not the best way to achieve this. Can anybody suggest better option to customize the Docker output the way I need it ?

My build.sbt file:

PlayKeys.externalizeResources := false
name := """wp-pw-ng"""

version := "1.0.0-SNAPSHOT"

lazy val `wp-pw-ng` = (project in file(".")).enablePlugins(PlayJava, JavaAppPackaging)

val playVer = "2.5.9"

scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  javaJpa,
  "org.hibernate" % "hibernate-core" % "5.2.3.Final" exclude("dom4j", "dom4j"),
  "mysql" % "mysql-connector-java" % "6.0.5",
  cache,
  javaWs,
  filters,
  "dom4j" % "dom4j" % "1.6",
  "com.google.guava" % "guava" % "20.0-rc1",
  "com.amazonaws" % "aws-java-sdk" % "1.11.34"
)

val docDeps = Seq(
  "io.swagger" %% "swagger-play2" % "1.5.3.2"
)

libraryDependencies ++= docDeps

fork in Test := true
javaOptions in Test ++= Seq(
  "-Xms512M",
  "-Xmx1536M",
  "-Xss1M",
  "-XX:MaxPermSize=384M"
)

fork in run := false

unmanagedResourceDirectories in Compile <+= (sourceDirectory in Compile) (_ / "resources")

mappings in Docker += file("conf/base/application.conf") -> "opt/docker/conf/base/application.conf"
mappings in Docker += file("conf/base/default-client.conf") -> "opt/docker/conf/base/default-client.conf"
mappings in Docker += file("conf/base/pw.conf") -> "opt/docker/conf/base/paywall.conf"
mappings in Docker += file("conf/prod/application.conf") -> "opt/docker/conf/prod/application.conf"
mappings in Docker += file("conf/prod/logback.xml") -> "opt/docker/conf/prod/logback.xml"
mappings in Docker += file("conf/stage/application.conf") -> "opt/docker/conf/stage/application.conf"
mappings in Docker += file("conf/stage/logback.xml") -> "opt/docker/conf/stage/logback.xml"
mappings in Docker += file("conf/local/application.conf") -> "opt/docker/conf/local/application.conf"
mappings in Docker += file("conf/local/logback.xml") -> "opt/docker/conf/local/logback.xml"
mappings in Docker += file("conf/routes") -> "opt/docker/conf/routes"
mappings in Docker += file("conf/ValidationMessages.properties") -> "opt/docker/conf/ValidationMessages.properties"

//************************************************
// Custom Docker Build,
// use command 'activator docker:publishLocal'
// to publish image locally to computer.
//************************************************
import com.typesafe.sbt.packager.docker._

val playUser = "play"
val grp = "idud"
dockerRepository := Some("quay.io/we")

version in Docker := "latest"

val buildEnv: String = System.getProperty("build.env")

dockerCommands := Seq(
  Cmd("FROM", "anapsix/alpine-java:8_jdk_unlimited"),
  Cmd("RUN", "apk", "-Uuv add", "--no-cache", "su-exec", "groff", "less", "python", "py-pip", "&& pip install awscli ", "&&  apk --purge -v del py-pip ", " &&  rm /var/cache/apk/* "),
  Cmd("RUN", s"addgroup $grp"),
  Cmd("RUN", s"adduser -s /bin/bash -D -G $grp $playUser"),
  Cmd("RUN", "echo", s"'$playUser ALL=(ALL) NOPASSWD:ALL'", ">> /etc/sudoers"),
  Cmd("WORKDIR", "/opt/docker"),
  Cmd("ADD", "opt /opt"),
  Cmd("RUN", "chown", "-R", s"$playUser:$grp", "."),
  Cmd("USER", s"$playUser"),
  Cmd("ENTRYPOINT", "[\"bin/wp-pw-ng\", \"-Dconfig.file=conf/" + buildEnv + "/application.conf\", \"-Dhttp.port=7000\" , \"-Dpidfile.path=/dev/null\"  ,\"-Dlogger.file=conf/" + buildEnv + "/logback.xml\"]"),
  Cmd("EXPOSE", "9877")
)

Additional Info I had to resort to this work-around due to issue in build stage mode issue with Playframework, Issue 4590 and I had to use PlayKeys.externalizeResources := false flag in my build.sbt file. This would remove all files from conf folder in Docker.

Upvotes: 2

Views: 1698

Answers (2)

Mayman
Mayman

Reputation: 11

Simply add the files that you want to be mapped inside a universal/conf directory. As a result of this, when you're creating the docker image the files get added to the /opt/docker/conf directory.

Upvotes: 0

Muki
Muki

Reputation: 3641

The playExternalizeResources:= false setting just prevents sbtfrom adding the playExternalizedResources to your mappings in Universal, which are the mappings available for all target package formats including docker.

Your build sbt can be lightenend with the MappingsHelper ( ScalaDocs )

import NativePackagerHelper._
mappings in Universal ++= contentOf("conf")

You can also filter the mappings to remove the unwanted files, e.g

import NativePackagerHelper._
mappings in Universal ++= contentOf("conf").filter(_.2.contains("persistence.xml")

Hope that helps, Muki

Upvotes: 2

Related Questions