Running Scala Native in Docker

Now that we’ve established that Docker is running and properly configured, we can hit Ctrl + C in the docker run terminal to shut down our nginx container. Running Scala Native in Docker is just as easy: I’ve published an image called rwhaling/scala-native-book with a full Scala Native installation and all of the code in the book on Docker Hub, so let’s run it like this:

 $ docker run -it -p 8080:8080 rwhaling/scala-native-book
 :scala-native:~ $ ~/book-code #

Unlike nginx, which started the nginx server immediately, this container opens up a shell. In this Appendix, you’ll know you’re in the container environment when you see a prompt like :scala-native:some_directory $, whereas a prompt on your host machine will be indicated with a plain $.

You’ll also note that we’ve changed the form of the port argument—by specifying -p 8080:8080 we tell Docker to use the same port number, both inside and outside of the container, so you can reach it at localhost:8080 in a web browser or other utility.

Let’s take a look around:

 :scala-native:~ $ ls -al
 total 221632
 drwxr-xr-x 11 root root 4096 Jan 12 15:54 .
 drwx------ 9 root root 4096 Jan 12 17:45 ..
 -rw-r--r-- 1 root root 6148 Jan 12 15:32 .DS_Store
 -rw-r--r-- 1 root root 107 Jan 12 15:29 .dockerignore
 -rw-r--r-- 1 root root 1352 Jan 12 15:53 Dockerfile
 drwxr-xr-x 2 root root 4096 Dec 16 19:19 ForkWaitShell
 drwxr-xr-x 3 root root 4096 Mar 21 2018 HTTPClient
 drwxr-xr-x 3 root root 4096 Mar 21 2018 HTTPServer
 drwxr-xr-x 8 root root 4096 Jan 12 15:54 InputAndOutput
 drwxr-xr-x 2 root root 4096 Sep 7 02:23 LibUVFutures
 drwxr-xr-x 2 root root 4096 Jul 23 00:27 LibUVServer
 drwxr-xr-x 2 root root 4096 Jul 10 2018 MapReduce
 drwxr-xr-x 9 root root 4096 Jul 10 2018 MemoryManagement
 -rw-r--r-- 1 root root 1246 Dec 16 19:40 build.sbt
 -rw-r--r-- 1 root root 226885816 May 2 2018 googlebooks-eng-all...
 -rwxr-xr-x 1 root root 0 Jan 12 15:25 start_docker.sh

Here, we have a directory for each chapter in the book, as well as some data to work with. We can build and run a Hello, World program like this:

 ~ $ cd InputAndOutput/hello_native/
 ~/book-code/InputAndOutput/hello_native $ sbt run
 [warn] Executing in batch mode.
 ...
 [info] Compiling 1 Scala source to /...
 [info] Linking (2671 ms)
 [info] Discovered 1275 classes and 9462 methods
 [info] Optimizing (debug mode) (4288 ms)
 [info] Generating intermediate code (1258 ms)
 [info] Produced 37 files
 [info] Compiling to native code (2504 ms)
 [info] Linking native code (immix gc) (202 ms)
 hello, world
 [success] Total time: 22 s, completed Jan 12, 2019 5:47:48 PM

Success! And since we have port 8080 mapped, even the HTTP servers we write later will work just fine inside this Docker container.

There’s one catch, though. Because Docker containers are immutable, if we change any files, these changes will be lost if we terminate and restart the container. If you intend to play with the code or write new Scala Native programs, you’ll want to create a directory on your host system to hold your files and then mount it into the container with an extra argument. You can do this by passing an extra argument to docker run in the form -v source_directory_path:target_container_path. First, let’s create a directory on our host system, like this:

 $ mkdir ~/my_code

Then we can mount our local my_code directory to the path /root/my_code in the container filesystem like this:

 $ docker run -it -p 8080:8080 -v ~/my_code:/root/my_code \
  rwhaling/scala-native-book
 scala-native> ~/book-code # ls ..
 book-code my_code

Now, the my_code directory is visible from within the container, and any changes made will persist.

I highly recommend testing this out, making a few changes from both inside and outside the container, and verifying that changes are visible and persistent across container restarts. Docker is a robust and proven technology, but it’s easy to make a mistake with some of the more complicated commands we’re using. I also suggest creating a local shell script to launch the container just the way you prefer. You can save a lot of typing with a simple two-line file like this:

 #!/bin/bash
 docker run -it -p 8080:8080 -v ~/my_code:/root/my_code \
  rwhaling/scala-native-book

Caveats aside, you’re good to go! If you came to this Appendix from the Introduction, you can go back and resume the sample project.

Footnotes

[66]

https://gitter.im/scala-native-book/community

[67]

https://www.scala-sbt.org/release/docs/Setup.html

[68]

https://brew.sh

[69]

https://pragprog.com/titles/rwscala/source_code

[70]

https://docs.docker.com/install

Thank you!

How did you enjoy this book? Please let us know. Take a moment and email us at support@pragprog.com with your feedback. Tell us your story and you could win free ebooks. Please use the subject line “Book Feedback.”

Ready for your next great Pragmatic Bookshelf book? Come on over to https://pragprog.com and use the coupon code BUYANOTHER2020 to save 30% on your next ebook.

Void where prohibited, restricted, or otherwise unwelcome. Do not use ebooks near water. If rash persists, see a doctor. Doesn’t apply to The Pragmatic Programmer ebook because it’s older than the Pragmatic Bookshelf itself. Side effects may include increased knowledge and skill, increased marketability, and deep satisfaction. Increase dosage regularly.

And thank you for your continued support,

Andy Hunt, Publisher

images/Coupon.png