Skip to content

Commit 401f89b

Browse files
committed
Adding documentation, examples and tests.
1 parent ac82b8d commit 401f89b

File tree

10 files changed

+143
-14
lines changed

10 files changed

+143
-14
lines changed

src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala

+14-11
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import sbt.Keys.{
1818
import packager.Keys._
1919
import linux.LinuxPlugin.autoImport.{ daemonUser, defaultLinuxInstallLocation }
2020
import universal.UniversalPlugin.autoImport.stage
21-
import SbtNativePackager.Universal
21+
import SbtNativePackager.{ Universal, Linux }
2222

2323
/**
2424
* == Docker Plugin ==
@@ -74,17 +74,18 @@ object DockerPlugin extends AutoPlugin {
7474

7575
val generalCommands = makeFrom(dockerBaseImage.value) +: makeMaintainer((maintainer in Docker).value).toSeq
7676

77-
generalCommands ++
77+
generalCommands ++ Seq(
78+
makeWorkdir(dockerBaseDirectory),
79+
makeAdd(dockerBaseDirectory),
80+
makeChown(user, group, "." :: Nil)
81+
) ++
82+
makeExposePorts(dockerExposedPorts.value) ++
83+
makeVolumes(dockerExposedVolumes.value, user, group) ++
7884
Seq(
79-
makeAdd(dockerBaseDirectory),
80-
makeWorkdir(dockerBaseDirectory),
81-
makeChown(user, group, "."),
8285
makeUser(user),
8386
makeEntrypoint(dockerEntrypoint.value),
8487
makeCmd(dockerCmd.value)
85-
) ++
86-
makeExposePorts(dockerExposedPorts.value) ++
87-
makeVolumes(dockerExposedVolumes.value, user, group)
88+
)
8889

8990
}
9091

@@ -158,8 +159,8 @@ object DockerPlugin extends AutoPlugin {
158159
* @param directory to chown recursively
159160
* @return chown command, owning the installation directory with the daemonuser
160161
*/
161-
private final def makeChown(daemonUser: String, daemonGroup: String, directory: String): CmdLike =
162-
ExecCmd("RUN", "chown", "-R", s"$daemonUser:$daemonGroup", directory)
162+
private final def makeChown(daemonUser: String, daemonGroup: String, directories: Seq[String]): CmdLike =
163+
ExecCmd("RUN", Seq("chown", "-R", s"$daemonUser:$daemonGroup") ++ directories: _*)
163164

164165
/**
165166
* @param daemonUser
@@ -199,12 +200,14 @@ object DockerPlugin extends AutoPlugin {
199200
*
200201
* @param exposedVolumes
201202
* @return commands to create, chown and declare volumes
203+
* @see http://stackoverflow.com/questions/23544282/what-is-the-best-way-to-manage-permissions-for-docker-shared-volumes
204+
* @see https://docs.docker.com/userguide/dockervolumes/
202205
*/
203206
private final def makeVolumes(exposedVolumes: Seq[String], daemonUser: String, daemonGroup: String): Seq[CmdLike] = {
204207
if (exposedVolumes.isEmpty) Seq()
205208
else Seq(
206209
ExecCmd("RUN", Seq("mkdir", "-p") ++ exposedVolumes: _*),
207-
makeChown(daemonUser, daemonGroup, exposedVolumes mkString " "),
210+
makeChown(daemonUser, daemonGroup, exposedVolumes),
208211
ExecCmd("VOLUME", exposedVolumes: _*)
209212
)
210213
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import com.typesafe.sbt.packager.docker._
2+
3+
enablePlugins(JavaAppPackaging)
4+
5+
name := "docker-commands"
6+
7+
version := "0.1.0"
8+
9+
maintainer := "Gary Coady <[email protected]>"
10+
11+
dockerCommands := Seq(
12+
Cmd("FROM", "dockerfile/java:latest"),
13+
Cmd("MAINTAINER", maintainer.value),
14+
ExecCmd("CMD", "echo", "Hello, World from Docker")
15+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version"))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Main extends App {
2+
println("Hello world")
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Generate the Docker image locally
2+
> docker:publishLocal
3+
$ exec bash -c 'docker run docker-test:latest | grep -q "Hello world"'

src/sbt-test/docker/volumes/build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ name := "simple-test"
44

55
version := "0.1.0"
66

7-
dockerExposedVolumes in Docker := Seq("/opt/docker/logs", "/opt/docker/config")
7+
dockerExposedVolumes := Seq("/opt/docker/logs", "/opt/docker/config")

src/sbt-test/docker/volumes/test

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Stage the distribution and ensure files show up.
22
> docker:stage
33
$ exec grep -q -F 'VOLUME ["/opt/docker/logs", "/opt/docker/config"]' target/docker/Dockerfile
4+
$ exec grep -q -F 'RUN ["chown", "-R", "daemon:daemon", "/opt/docker/logs", "/opt/docker/config"]' target/docker/Dockerfile
45
$ exec grep -q -F 'RUN ["mkdir", "-p", "/opt/docker/logs", "/opt/docker/config"]' target/docker/Dockerfile

src/sphinx/formats/docker.rst

+95-2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ The Docker support provides the following commands:
121121
Customize
122122
---------
123123

124+
There are some predefined settings, which you can easily customize. These
125+
settings are explained in some detail in the next sections. If you want to
126+
describe your Dockerfile completely yourself, you can provide your own
127+
`docker commands` as described in `Custom Dockerfile`_.
128+
124129
Docker Image Name
125130
~~~~~~~~~~~~~~~~~
126131

@@ -149,9 +154,13 @@ Docker Image Customization
149154

150155
.. code-block:: scala
151156
152-
dockerExposedPorts in Docker := Seq(9000, 9443)
157+
dockerExposedPorts := Seq(9000, 9443)
158+
159+
dockerExposedVolumes := Seq("/opt/docker/logs")
160+
153161
154-
dockerExposedVolumes in Docker := Seq("/opt/docker/logs")
162+
In order to work properly with `USER daemon` the exposed volumes first
163+
created (if not existend) and chowned.
155164

156165
Install Location
157166
~~~~~~~~~~~~~~~~
@@ -161,3 +170,87 @@ The files from ``mappings in Docker`` are extracted underneath this directory.
161170
.. code-block:: scala
162171
163172
defaultLinuxInstallLocation in Docker := "/opt/docker"
173+
174+
Custom Dockerfile
175+
~~~~~~~~~~~~~~~~~
176+
177+
All settings before are used to create a single sequence of docker commands.
178+
You have the option to write all of them on your own, filter or change existing
179+
commands or simply add some.
180+
181+
First of all you should take a look what you docker commands look like.
182+
In your sbt console type
183+
184+
.. code-block:: bash
185+
186+
> show dockerCommands
187+
[info] List(Cmd(FROM,dockerfile/java:latest), Cmd(MAINTAINER,Your Name <[email protected]>), ...)
188+
189+
190+
191+
Remove Commands
192+
===============
193+
194+
SBT Native Packager added some commands you may not need. For example
195+
the chowning of a exposed volume.
196+
197+
.. code-block:: scala
198+
199+
import com.typesafe.sbt.packager.docker._
200+
201+
// we want to filter the chown command for '/data'
202+
dockerExposedVolumes += "/data"
203+
204+
dockerCommands := dockerCommands.value.filterNot {
205+
206+
// ExecCmd is a case class, and args is a varargs variable, so you need to bind it with @
207+
case ExecCmd("RUN", args @ _*) => args.contains("chown") && args.contains("/data")
208+
209+
// dont filter the rest
210+
case cmd => false
211+
}
212+
213+
214+
Add Commands
215+
============
216+
217+
Adding commands is as straigtforward as adding anything in a list.
218+
219+
.. code-block:: scala
220+
221+
import com.typesafe.sbt.packager.docker._
222+
223+
dockerCommands += Cmd("USER", daemonUser.value)
224+
225+
dockerCommands ++= Seq(
226+
// setting the run script executable
227+
ExecCmd("RUN",
228+
"chmod", "u+x",
229+
s"${(defaultLinuxInstallLocation in Docker).value}/bin/${executableScriptName.value}"),
230+
// setting a daemon user
231+
Cmd("USER", "daemon")
232+
)
233+
234+
235+
Write from Scratch
236+
==================
237+
238+
You can simply wipe out all docker commands with
239+
240+
.. code-block:: scala
241+
242+
dockerCommands := Seq()
243+
244+
245+
Now let's start adding some Docker commands.
246+
247+
.. code-block:: scala
248+
249+
import com.typesafe.sbt.packager.docker._
250+
251+
dockerCommands := Seq(
252+
Cmd("FROM", "dockerfile/java:latest"),
253+
Cmd("MAINTAINER", maintainer.value),
254+
ExecCmd("CMD", "echo", "Hello, World from Docker")
255+
)
256+

test-project-docker/build.sbt

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import com.typesafe.sbt.packager.docker._
2+
13
enablePlugins(JavaAppPackaging)
24

35
name := "docker-test"
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
import java.nio.file._
2+
import scala.util._
3+
14
object Main extends App {
25
println("Hello world")
6+
7+
val path = Paths get "/data/test01"
8+
val result = Try(Files createFile path)
9+
10+
println(result)
311
}

0 commit comments

Comments
 (0)