Running a Clojure Uberjar inside Docker
For a sideproject I wanted to deploy a Clojure uberjar on a remote server using Docker. I imagined that to be fairly straight foward but there are some caveats you need to be aware of.
Naively my first attempt looked somewhat like this:
FROM dockerfile/java ADD https://example.com/app-standalone.jar / EXPOSE 8080 ENTRYPOINT [ "java", "-verbose", "-jar", "/app-standalone.jar" ]
I expected this to work. But it didn't. Instead it just printed the following:
[Opened /usr/lib/jvm/java-7-oracle/jre/lib/rt.jar] # this can vary depending on what JRE you're using
And that has only been printed because I added
-verbose when starting the jar. So if you're not
running the jar verbosely it'll fail without any output. Took me
quite some time to figure that out.
As it turns out the
dockerfile/java image contains a
WORKDIR command that somehow breaks my
java invocation, even though it is using absolute
What worked for me
I ended up splitting the procedure into two files in a way that allowed me to always get the most recent jar when starting the docker container.
Dockerfile basically just adds a small script to
the container that downloads and starts a jar it downloads from
somewhere (S3 in my case).
FROM dockerfile/java ADD fetch-and-run.sh / EXPOSE 42042 EXPOSE 3000 CMD ["/bin/sh", "/fetch-and-run.sh"]
And here is
#! /bin/sh wget https://s3.amazonaws.com/example/yo-standalone.jar -O /yo-standalone.jar; java -verbose -jar /yo-standalone.jar
Now when you build a new image from that Dockerfile it adds the
fetch-and-run.sh script to the image's filesystem.
Note that the jar is not part of the image but that it will be
downloaded whenever a new container is being started from the
image. That way a simple restart will always fetch the most recent
version of the jar. In some scenarios it might become confusing to
not have precise deployment tracking but in my case it turned out
much more convenient than going through the process of destroying
the container, deleting the image, creating a new image and
starting up a new container.