How to deploy to Docker

1,263 views
Skip to first unread message

sou...@mahkengine.com

unread,
Aug 18, 2015, 1:11:01 PM8/18/15
to play-framework
Hi Everyone,

I have a question about deployment.  I've google, purchased cookbooks, and have not found a solution.  

Background -   Developing Play (Java) using IntelliJ 14.1.4

Target - Deploy Play application (with no source code, etc) to Docker Container.  I want to work on developing the application and make continuous builds that will deploy to a base docker image that I use.  The docker image will be deployed to Amazon.

I have seen articles that suggest the below.  However, I don't see where in the built.sbt file does it include the additional dependency jars that I need to package in my deploy.  I understand from the documentation that Play2 does not use a WAR file.  What has the community done for deployment?

Thank you,

Southin

"Add these imports and changes to build.sbt:

import NativePackagerKeys._
import com.typesafe.sbt.SbtNativePackager._

And then docker config:

maintainer in Docker := "John Smith <john....@example.com>"
dockerExposedPorts in Docker := Seq(9000)

This allows sbt (play build tool) to generate a correct Dockerfile. The exposed port will be used by beanstalk to direct traffic to the app.

Once you have this, you can run:

activator docker:stage

This will produce a target/docker directory. Change into that directory - and run:

docker build -t myapp . 
docker run -p 9000:9000 myapp"

Sean McClelland

unread,
Aug 18, 2015, 2:39:26 PM8/18/15
to play-framework
Hi Southin,

I am currently deploying all my projects to Docker through a Docker Registry Server. I won't go into the specifics of the Docker Registry server, but here is the basic information on SBT with Docker: http://www.scala-sbt.org/sbt-native-packager/formats/docker.html

Now I will go into specifics on how to get Play working with all this: (This assumes you are using Play 2.4.x, if you are not please let me know as there are some minor changes)

1. Go into your project/plugins.sbt file and make sure to add the following line:

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.0.3")

Where 1.0.3 is whatever version of the Sbt native packager you are using. 

2. Open up your build.sbt file:

2.1 Make sure you have enablePlugins with SbtNativePackager and DockerPlugin enabled at minimum. Here is an example of my build.sbt

lazy val root = (project in file(".")).enablePlugins(PlayJava,SbtNativePackager,DockerPlugin,SbtWeb)

Note that you probably don't need all of these enabled, for instance SbtWeb is for a different sbt plugin. Just make sure you have SbtNativePackager and DockerPlugin. 

2.2

At minimum have the following fields filled out in your build.sbt:

//Docker.io setup
// setting a maintainer which is used for all packaging types
maintainer := "Southin"

// exposing the play ports (Change these to whatever you are using)
dockerExposedPorts in Docker := Seq(9000, 9443)

dockerBaseImage := "dockerfile/java:oracle-java8"

dockerRepository := Some("www.pathtoyour/dockerregistry")



Now to actually build and deploy your application you will need Linux since Docker support really isn't solid for Windows yet (AFAIK) Assuming on Linux, type the following commands:


./activator clean update compile docker:publish
alternatively, if you just want to publish locally and not deploy to your docker registry server you can type:
./activator clean update compile docker:publishLocal

If you are curious as to what is actually happening, you can go into the target/docker directory. You should see a Dockerfile and a stage directory.


The rest of what I say below should not be necessary as SBT should build and push your Docker app to your registry directly. But if you do want to have a little more control or just understand a few extra commands, continue reading:

At this point if you wanted to you could manually build and deploy your docker app through docker itself:

docker build -t www.pathtoyour/dockerregistry/project-name stage

(Stage is the name of the directory that has your actual files in it. Feel free to look around to understand how everything is working. playapppath/target/docker/stage)

docker push www.pathtoyour/dockerregistry/project-name 


That's the basic idea of how to deploy Play applications through Docker. Please let me know if you have any questions.

Thanks,

-Sean

Nathan Blomquist

unread,
Aug 18, 2015, 2:44:08 PM8/18/15
to play-framework
Are you asking how to deploy to Beanstalk?
I have made deploying to AWS Beanstalk work with the following changes to my build.sbt:

--- top of build.sbt ---

import com.typesafe.sbt.packager.docker._
maintainer in Docker := "Jon Smith, etc."
dockerExposedPorts := Seq(9000)
dockerBaseImage := "java:8-jre" // need to use Java 8 for Play 2.4

// this chmods the file to executable, Windows doesn't set that bit in the zip file.
dockerCommands += ExecCmd("RUN",
"chmod", "+x",
s"${(defaultLinuxInstallLocation in Docker).value}/bin/${executableScriptName.value}")




-- bottom of build.sbt file --
/**
* This task creates a zip file for use in AWS Beanstalk.
* This depends on docker:stage to create the base files, then zips them up.
* The zip file will be in the target/aws directory with a name like:
* aws_build_<name>_<version>_currentTimeMillis.zip
*/
lazy val packageAWS = taskKey[File]("Create Package for AWS Beanstalk.")
packageAWS <<= packageAWS.dependsOn(stage in config("docker"))
packageAWS := {
// we are going to place the zip output file in the target directly
val targetDirectory = (baseDirectory in Compile).value / "target" / "aws"
// get all the files and subdirectories of the stage task from docker
val inputs = Path.allSubpaths((stage in config("docker")).value)
val zipName = Seq("aws_build", name.value, version.value, System.currentTimeMillis()).mkString("_")
val output: File = targetDirectory / (zipName + ".zip")
IO.zip(inputs, output)
println("Package is located here: " + "'" + output.toPath + "'")
output
}


-- Add this line to your plugins.sbt file --
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.0.3")


Now run:
activator packageAWS

This will create zip in the target/aws directory that can be directly used in AWS Beanstalk.  If you want to launch it yourself, use the Dockerfile and associated file in target/docker/stage.

Hope this helps!

Nathan Blomquist

unread,
Aug 18, 2015, 2:45:41 PM8/18/15
to play-framework
You beat me to it!

Southin Simphoukham

unread,
Aug 21, 2015, 12:58:37 PM8/21/15
to play-fr...@googlegroups.com
Thank you Nathan!  I am looking into BeanStock.  However, I wanted to know how to build a container directly from IntelliJ and push it to my Docker hub account.

--
You received this message because you are subscribed to a topic in the Google Groups "play-framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/Aq-ySsKQzXg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/08020ed3-c79f-4c1f-af8a-a152fdd475de%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Southin Simphoukham
Co-Founder MahkEngine.com

Nathan Blomquist

unread,
Aug 21, 2015, 1:06:00 PM8/21/15
to play-framework
Unfortunately, I am not sure how to do that.
I will look into creating an SBT task for it and executing that using the SBT/Activator instead of doing it IntelliJ directly.  But that is just my preference on how I would do it.

Southin Simphoukham

unread,
Aug 21, 2015, 1:08:16 PM8/21/15
to play-fr...@googlegroups.com
Thank you Sean for the detail information.


I have a docker image locally on my laptop and pushed to my docker hub.  It's name is xxxxx/engineyard.

I want to know if the parameter "dockerBaseImage" will instruct sbt to use that docker image as the base when it builds?  The followup question that I am interested in is "Do I need to explicitly tell sbtNativePackager where xxxx/engineyard is located on my machine?  

I notice that there are no parameters for the login and password to push to docker hub?  Did I miss something in the documentation for sbnativepackager? An example would help.

import NativePackagerKeys._
import com.typesafe.sbt.SbtNativePackager._



name := """PlayDocker"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayJava)

scalaVersion := "2.11.6"

//maintainer in Docker := "Southin <sou...@mahkengine.com>"

packageSummary in Docker := "Play docker application"

packageDescription := "Play Docker [micro|nano] Service"

// Only add this if you want to rename your docker image name
packageName in Docker := "docking-station"

dockerBaseImage := "xxxxxx/engineyard" // Docker image to use as a base for the application image

dockerExposedPorts in Docker := Seq(9000, 9443) // Ports to expose from container for Docker container linking


libraryDependencies ++= Seq(
javaJdbc,
cache,
javaWs,
filters
)

// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator

--
You received this message because you are subscribed to a topic in the Google Groups "play-framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/Aq-ySsKQzXg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framewor...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Southin Simphoukham

unread,
Aug 21, 2015, 2:02:59 PM8/21/15
to play-fr...@googlegroups.com
I am running into a hurdle with Intellij executing the sbt command to run the docker.  I have Docker running using KiteMatic.  My VirtualBox is up and the "default" docker image is running.  However when I run the docker:publishLocal command from the intelliJ terminal I get

> docker:publishLocal
[error] Post http:///var/run/docker.sock/v1.20/build?cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&forcerm=1&memory=0&memswap=0&rm=1&t=docking-station%3A1.0-SNAPSHOT&ulimits=null: dial unix /var/run/docker.sock: no such file or directory.
[error] * Are you trying to connect to a TLS-enabled daemon without TLS?
[error] * Is your docker daemon up and running?
[trace] Stack trace suppressed: run last docker:publishLocal for the full output.
[error] (docker:publishLocal) Nonzero exit value: 1
[error] Total time: 1 s, completed Aug 21, 2015 11:00:26 AM


Has you seen this before?  I don't understand why sbt command in intelliJ does not acknowledge or know that Docker is running.




For more options, visit https://groups.google.com/d/optout.

Southin Simphoukham

unread,
Aug 21, 2015, 2:27:50 PM8/21/15
to play-fr...@googlegroups.com
Found a quicker solution.  Use the terminal commands outside of IntelliJ.
Reply all
Reply to author
Forward
0 new messages