iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 15
0
DevOps

用30天來介紹和使用 Docker系列 第 15

Day15:實作簡單的 service 程式打包成 Docker Image(一)

昨天和前天是介紹如何使用 Docker 提供的 Restful API,操作啟動 Docker Container,這樣可以透過程式方便建立測試環境,對撰寫測試程式建構環境方面有幫助。

今天要介紹的部份是在開發完程式之後會 Build 成一個檔案, 然後把這個程式包在 Docker Image 內,這樣使用者要使用此程式時,也就可以不用安裝或佈署此檔案,只要執行 docker run 指令就可以把程式執行起來。

今天就來寫個簡單的 Akka HTTP 程式,並且透過使用 SBT Build Tool 來打包 Docker Image。

在執行 sbt build 的指令時就把撰寫的 Akka Http 程式打包到成 Docker Image,之後再使用 docker run 指令把 Container 啟動起來。

一. 我把此程式放在 GitHub 上,如果有興趣的話可以直接 clone 到 local 測試,指令如下:

$ git clone https://github.com/jackyoh/akkahttp-docker-example.git

二. Akka HTTP 程式和說明如下:

import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.stream.ActorMaterializer
import scala.io.StdIn

object AkkaHTTPExample {
  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    implicit val executionContext = system.dispatcher

    val route =
      path("hello") {
        get {
          complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to Akka</h1>"))
        }
      }
    Http().bindAndHandle(route, "0.0.0.0", 8080)
  }
}

以上的程式主要是啟動一個 Akka HTTP Web Server,並且程式裡有實作一個方法,只要使用者輸入 /hello 的 URL 就會印出 Say hello to Akka 字串。

設定 SBT 的方式如下:

  1. project/plugins.sbt
addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "1.4.1")

加入 sbt-docker 的 plugin

  1. build.sbt 的程式內容如下:
name := "akkahttp-docker-example"

version := "0.1-SNAPSHOT"

scalaVersion := "2.11.11"

val akkaVersion = "2.4.16"
val akkaHttpVersion = "10.0.3"
val slf4jVersion = "1.7.25"
val sprayJsonVersion = "1.3.3"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
  "com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
  "com.typesafe.akka" %% "akka-stream" % akkaVersion,
  "com.typesafe.akka" %% "akka-actor" % akkaVersion,
  "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % "test",
  "io.spray" %% "spray-json" % sprayJsonVersion,
  "org.slf4j" % "slf4j-simple" % slf4jVersion
)

enablePlugins(DockerPlugin)
dockerfile in docker := {
  val appPath = "/app"
  val jarFile: File = sbt.Keys.`package`.in(Compile, packageBin).value
  val classpath = (managedClasspath in Compile).value
  val mainclass = "idv.jack.example.AkkaHTTPExample"
  val jarTarget = s"${appPath}/${jarFile.getName}"
  val classpathString = classpath.files.map(s"${appPath}/" + _.getName)
    .mkString(":") + ":" + jarTarget + ":."

  new Dockerfile {
    from("java")
    add(classpath.files, s"${appPath}/")
    add(jarFile, jarTarget)
    entryPoint("java", "-cp", classpathString, mainclass)
  }
}

這裡主要的重點在 dockerfile in docker 這一段,主要是把程式使用的第三方 Jar 檔和 Project 的 Jar,複製進去 Docker Image 裡面,最後在用 Docker 的 entryPoint 設定 Docker run 裡執行啟動此 Project 的 Jar 檔。

四. 把程式打包成 Docker Image 的指令如下

$ sbt docker

輸入以上的指令就可以把程式打包成 Docker 的 Image,這裡要注意執行這個指令的使用者是否有執行 docker 指令的權限。

五. 使用 docker run 指令測試

$ docker run -d -p 9090:8080 --restart=always default/akkahttp-docker-example

執行結果如下
https://ithelp.ithome.com.tw/upload/images/20171218/20103456767on7OPNt.png

今天已經介紹了要如何把 Build 完成的 Jar,打包到 Docker Image 內,可以方便使用者使用,明天繼續介紹要如何的把此 Docker Image push 到 Docker Hub 上。


上一篇
Day14:使用 third party 的 Jar 呼叫 Docker Restful API
下一篇
Day16:實作簡單的 service 程式打包成 Docker Image(二)
系列文
用30天來介紹和使用 Docker30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言