

Running java on Docker images on your Mac – A getting started guide | Jeroen van...
source link: https://vanwilgenburg.wordpress.com/2017/05/15/running-java-on-docker-images-on-your-mac-a-getting-started-guide/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Running java on Docker images on your Mac – A getting started guide
A few weeks ago I finally gave Docker a shot. It wasn’t a really smooth ride so I decided to write an article about it. I will run a Zookeeper as an example to get experience with Docker. After this description I’ll show you the obstacles I encountered and how to solve them. I will also provide some links to help you do some real life things with Docker.
For a long time I thought Docker was a big hype, but it seems things got more serious. A long while ago I gave Docker for Mac a shot, but it wasn’t really mature yet. Running Docker on a Virtual Machine was a no-go for me, it kind of defeats the purpose of Docker and I was really happy with Vagrant.
Docker for Mac
Docker for Mac is finally usable. It still has a few rough edges on the networking part, but good enough to use during development or create images that will run on a Linux production environment.
Which image should I use?
There are a lot of different images. I wanted a light weight image with just a jdk. The official java image for Docker is deprecated and the openjdk image is suggested as its successor. Then there’s a lot of choice. I picked openjdk:alpine
because its description sounded pretty good : “Alpine Linux is much smaller than most distribution base images (~5MB), and thus leads to much slimmer images in general.”
Create a simple image that prints the java version
My first step was something even simpler than the obligatory ‘Hello World’, just print the Java version. This implicitly also shows that we’re dealing with OpenJDK instead of Oracle Java .
Create a file named Dockerfile
with the following contents :
FROM openjdk:alpine
CMD java
This will define an image based on the Alpine images and runs the command CMD
. You can build the image with :
docker build -t jvwilge
/hello-world
The image will be created and should be visible when you run docker images
. The minus t option tags the image in the 'name:tag'
format so it’s findable in the images list under jvwilge/hello-world
. It’s a bit larger than the 5MB Alpine was advertised with, but still a pretty decent size.
To run the image execute
docker run -it --
rm
--name hello-world-1 jvwilge
/hello-world
This will start the image and print the java version :
openjdk version "1.8.0_111-internal"
OpenJDK Runtime Environment (build 1.8.0_111-internal-alpine-r0-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)
The option rm
removes the container after completion. Note the difference between container and image. A container is a running instance of an image. Containers are visible with docker ps
. But since our fresh container quits immediately after completion and is very fast you won’t see anything there (but I’ll show you later).
Taking it to the next level: Building a Zookeeper image
Go to (or create) a new directory and create a file named Dockerfile
:
FROM openjdk:alpine
ARG ZK_VERSION=3.4.10
ENV ZK_HOME /home/zookeeper/zookeeper-$ZK_VERSION
# zkServer.sh uses bash, so we have to install it.
RUN apk add --update bash && rm -rf /var/cache/apk/*
RUN adduser -S zookeeper
USER zookeeper
WORKDIR /home/zookeeper
RUN wget http://apache.40b.nl/zookeeper/zookeeper-$ZK_VERSION/zookeeper-$ZK_VERSION.tar.gz
RUN tar xfz zookeeper-$ZK_VERSION.tar.gz
RUN rm zookeeper*.tar.gz
ADD zoo.cfg $ZK_HOME/conf/zoo.cfg
EXPOSE 2181
CMD $ZK_HOME/bin/zkServer.sh start-foreground
The image can be build with :
docker build -t jvwilge
/zookeeper
.
The ARG
instruction defines a variable that can be changed at build time. A default value is optional. In the following example we can provide another version of Zookeeper :
docker build --build-arg ZK_VERSION=3.4.8 -t jvwilge
/zookeeper
.
The ENV
instruction is almost the same, but cannot be overridden. Both ARG
and ENV
are variables that can be used in the RUN
instruction.
Next step is to install bash (needed for zkServer.sh
) and add a user zookeeper. Switching to this user is done with the USER
instruction.
With the WORKDIR
command we switch to a working directory, download Zookeeper (note the $ZK_VERSION
variable), extract it and remove the downloaded .tar.gz file.
With ADD
you can add a file that is available on the host machine. In this case it is a zoo.cfg
placed in the same directory as Dockerfie
on the host machine.
EXPOSE
exposes the Zookeeper port to the host machine (this can be mapped to another port number at runtime).
CMD
starts the server. More on CMD
vs ENTRYPOINT
later.
Running the Zookeeper image
Run the image with :
docker run -d -it --rm -p 12181:2181 --name zookeeper1 jvwilge/zookeeper
With -p you can map the exposed port to another port. In this case zookeeper will be available on the host machine on port 12181.
Telnet to port 12181 and the ruok
(are you ok?) command can verify things are working :
telnet localhost 12181
Trying ::1...
Connected to localhost.
Escape character is '^]'.
ruok
imok
Connection closed by foreign host.
The image runs in the background (it’s technically an container now) and is visible with docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
699d2c66c289 jvwilge/zookeeper "/bin/sh -c '$ZK_H..." 2 minutes ago Up 2 minutes 0.0.0.0:12181->2181/tcp zookeeper1
Stop the container with docker stop 699d2c66c289
. Where 699d2c66c289 is the CONTAINER ID.
CMD vs ENTRYPOINT (or service image vs. executable image)
The Docker documentation states “ENTRYPOINT should be defined when using the container as an executable.”. This is a bit vague when you don’t know what an executable image is and what the alternative is.
The alternative is a service image, a long running container (like a web server of a Kafka broker).
An executable image is short lived.
Bash/file not found in $PATH
Some applications depend on bash, when this is the case you can insert the following line to your Dockerfile
:
RUN apk add --update bash && rm -rf /var/cache/apk/*
‘I see a lot of images with tag <none>’
When you’re building an image as a less experienced user you will run into errors. Those error will leave scars in the form of a <none> tag. When you display the images with docker images
you’ll probably see some. These images will clog up your hard disk eventually.
To remove these images you first have to remove the containers or otherwise you’ll get the following error
$ docker rmi a7b133710d3f
Error response from daemon: conflict: unable to delete a7b133710d3f (must be forced) - image is being used by stopped container aa67b2abc73e
Of course you can add --force
but this will still leave the containers on your disk. To remove the containers properly run :
docker
rm
$(docker
ps
-a -q)
Note that when then are no results at docker ps -a -q
you will see the message "docker rm" requires at least 1 argument(s).
When this command is successful you can remove the images (without having to force it).
docker rmi $(docker images |
grep
'^<none>'
|
awk
'{print $3}'
)
Source (note that you have to use single quotes)
‘I want to have a prompt/run shell commands on the container’
Logging in into your docker container is not intended, but sometimes you want to check things without having to rebuild your images.
To get a bash prompt on your container run
docker
exec
-t -i container_name
/bin/bash
Note that bash needs to be installed to ‘bash into’ the container.
Networking on the mac
There are some issues with networking with Docker on the Mac which are described in ‘Known Limitations, Use Cases, and Workarounds’ .
Note that the sudo ifconfig lo0 alias 10.200.10.1/24
command should be executed after every restart of your Mac!
Other useful links
I don’t want to withhold the links that didn’t make it into this article (but are very useful) :
How to get a Docker container’s IP address from the host?
Best practices for writing Dockerfiles
The JVM and Docker, a good idea? by Christopher Batey @ Devoxx UK 2016
Conclusion
I hope this article will save you some time when starting with Docker. Please feel free to comment on the article with the issues you ran into, this way we can help others to get started with Docker more quickly
Recommend
-
42
-
50
README.md av R Bindings to FFmpeg
-
5
On many projects CORS headers are configured incorrectly. Usually by putting some wildcards (*) in the config and things ‘work’. In this article I will show how to create tests for the correct headers (using Karate, but it should be applicabl...
-
12
Knowing Adobe Photoshop, Illustrator and InDesign can open a whole new digital career ...
-
7
Since HTTP/2 is gaining momentum I thought it would be a nice experiment to see if it’s possible to convert some applications to HTTP/2. We have a bunch of Spring Boot micro services and those services communicate with each other via REST cal...
-
10
Finding the link between heart rate and running pace with Spark ML – Fitting a linear regression model Besides crafting software I’m an avid runner and cyclist. Firstly for my health and secondly because of all the cool gadg...
-
5
Getting started with Akka Stream Kafka – Using Kafka the reactive streams way A few days ago my eyes fell on a new release of Akka Stream Kafka. Since I’m doing a lot with Kafka currently and I really wanted to get my hands...
-
13
Why HTTP/2 with TLS is not supported properly in Java 8 – And what you can do about it Recently I got a bit frustrated that Undertow is still the only HTTP/2 server in Java that properly supports HTTP/2 with TLS. Today I fou...
-
12
The default behaviour of a Spark-job is losing data when it explodes. This isn’t a bad choice per se, but at my current project we need higher reliability. In this article I’ll talk about at least once delivery with the Spark write ahead log....
-
3
Getting Started with Pre-built Docker Images Images are the fundamental component of docker. In this guide, we will discuss what docker images are, how to build them, how to manage them, and how to use them. Let's get started...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK