53

I had a friend who said:

Docker is amazing. You can use it to replicate production and all its quirks on your local machine. Then you can deploy that instance straight through all the staging workflows super-quick.

Now this would be true if the developers were writing Ruby, PHP or Go - where there was a direction binary link to the operating system.

But when using Java - there is already a virtual layer between the operating system and the language, making consistency of operation regardless of the underlying operating system.

Arguably, in this case, the benefits of running Docker for developers locally to replicate the production environment are negated. (Compared to Ruby, PHP or Go).

I'm open to discussion on this and am keen to hear a dissenting point of view (with evidence).

Are the development benefits of using Docker negated when using Java compared to other languages closer to Unix binaries?

  • 34
    Why do you think ruby and php are binary? Ruby and php are technically even more virtual than Java - in Java you have to compile first then execute your program in a virtual machine. In Ruby and php you ship source code and the virtual machine reads the source directly. – slebetman Jul 17 '17 at 15:44
  • 12
    "But when using Java - there is already a virtual layer between the operation system and the language, making consistency of operation regardless of the underlying operating system. " LOL. Java invented "write once, test everywhere." – Andy Jul 17 '17 at 22:22
  • 2
    Java is a moving target. Occasionally features are introduced that break things (the security tightening a few years back were prime examples) or you run into a bug that requires you use a specific version. It is much easier to control this in docker than using the native packaging system of the host computer. – Thorbjørn Ravn Andersen Jul 17 '17 at 22:30
  • 1
    "making consistency of operation regardless of the underlying operating system" Note that making the language runtime behave consistently doesn't negate the fact that you probably still have some external dependencies. Could be something as simple as using a particular file path for your logs. – jpmc26 Jul 19 '17 at 0:03
86

Not at all.

Imagine you're running the version 1.8.0 of Java on both your development machine and the server. By the way, you're working simultaneously on two projects, both using Java.

One day, a bug is found in JVM, and the servers which run the first project you're working on are migrated to 1.8.1. By the way, the servers running the second project aren't affected by the bug, and are managed by a different team of system administrators, who may not be willing to update to 1.8.1.

Now, at least for one of the projects, you're running a different version of Java.

This may not bother you too much (until one server migrates to 1.9, while the other one keeps the old version), but this would mean that you're not replicating production environment any longer on your local machine, which makes it possible for tiny bugs to creep in.

If you imagine that your file system, your dependencies, your security settings, your local configuration and your version of Linux itself differ from production, you are putting yourself at risk of writing code which will fail in production. Instead of taking this risk, you could be using virtualization or Docker, with minor to no productivity loss.

  • 20
    Also this sort of thing happens ALL the time in larger companies. It's not just a theoretical thing. – enderland Jul 17 '17 at 19:11
  • 5
    What do you do when you discovery a bug in Docker? – Owen Jul 17 '17 at 21:46
  • Also Java 9 will break things. There will be quite some effort needed. – Thorbjørn Ravn Andersen Jul 17 '17 at 22:31
  • 8
    @Owen Same thing you do when you find a bug in Java. Or in {Linux,Windows}. Or in your CPU. – Kroltan Jul 18 '17 at 2:01
  • 1
    @Trilarion: Yes, though mostly in the form of blog posts by company developers. That said, any of the "Learn more" links on docker.com/customers will provide examples of large companies using docker to solve such problems. That said, usually such companies were taking it for granted that they needed a perfect match between production and development, and accomplished this with VMs. Later, they realized, "hey, Docker solves the same problem as VMs, except it runs faster and can be used to keep deployments consistent." – Brian Jul 19 '17 at 13:54
35

You rarely just deploy a "Java App". Your java application has a lot of different support programs around it. We use Apache HTTPD, Apache Tomcat, ActiveMQ for messaging, an FTP Deamon, MySQL and a handful of custom services to integrate with programs that don't work directly with Java.

This doesn't even go into the development software that goes along with it--eclipse, ant, adobe flex, groovy, firefox and subversion (I'm skipping quite a few)

It takes between a full day and a week to set up a new workstation--we've discussed moving to Docker to simplify this issue. It would be amazing if we could reliably roll out a new workstation in a couple hours.

Not to mention the fact that when we deploy we need to maintain upwards of--20 servers; Docker is starting to look like a pretty good deal!

(20 seems Pretty painful for an app that only runs on a single server at a time... but multiply that one server by clusters(x2), test/staging/prod(x3), Internal/External(x2) and primary site/backup site(x2) and you get up there pretty quickly)

  • Why not make images? – Dmitry Kudriavtsev Jul 17 '17 at 23:38
  • We hope to. We're a small team trying to add features to a pretty heavily used/important system and don't have enough control over the servers to dictate their deployment. Might use it for dev though, we are already pretty constrained at 32mb ram--I assume running from a docker image will have some overhead... but our plan is to move in that direction. – Bill K Jul 17 '17 at 23:48
  • I meant for the workstations – Dmitry Kudriavtsev Jul 17 '17 at 23:55
  • Time and memory--we already have to leave pieces off to run in our 32gb workstations (the 64gb servers run it all fine). We've experimented a little though and may give it a try next time we need to build a new dev workstation. – Bill K Jul 17 '17 at 23:59
8

This question would also be pertinent for golang, where you can just extract statically linked binaries and run them somewhere, as opposed to Python or C++ where you usually have a large number of linked libraries which leads people to just build a docker container out of the development environment.

There are two points to answer here:

One: there has to be a better way, and there is: you can build smaller (and more efficient) docker containers using just the install environment, which leads to similar advantages as in the case of Golang-with-environment versus Golang-just-binaries containers. In the case of Java, you can build a fat jar or an installable app which contains all the library jars and a shell script; in the case of Python, you could use auditwheel to build self-contained wheels that are independent of the build environment (and you could use C++ with static linking to almost the same effect).

Two: what do you need docker for? In Java land, you can do a lot of separation between different components by using class loaders, but the main point is what is around the Java application. No Java application runs by itself - if it does not run in docker, it would usually have to be supervised by supervisord or systemd or the likes. Enter Kubernetes, Marathon, or Docker cloud, which use the container abstraction to virtualize not the host itself, but actually virtualize the whole network such that you can just deploy containers and they run on some random host.

Microservices usually run on docker-based clouds because it allows you to treat your docker hosts as cattle, not as pets, and similarly with the dockerized applications. Of course, this abstraction becomes leaky as soon as you mount host volumes onto docker and need to run docker containers on exactly the host that has these volumes. Some people get even around that.

5

This is a really good question but after working with Docker, I would turn it around:

Are the benefits of the JVM negated by containerization (e.g. Docker)?

Containers really challenge a lot of the assumptions I have about development that come from my experience. For example, if someone were to hard-code a path to a resource file in an application, a lot of experienced developers would know that this is problematic and you should make it configurable. But if you are targeting a container, is this really the case? When you build the container, you tell it what the directory structures are. You are configuring the path there. So should you configure it twice? What's the benefit? If you don't make them match, it won't work so... DRY?

I recently created a prototype application with Java and Docker which essentially watched the GC events and when the old portion of the heap hit a threshold percentage, it would shut itself down. Docker (swarm mode) would then spin up a new one. Essentially, it eliminated the need for major GC-cycles in the JVM and let docker manage them. It didn't work as well as I might have hoped (clients saw some impact of the shutdown) but it was functional enough to do a live demo to a crowd.

You should really just try containers out if you are curious. It really is a disruptive technology and you will need to come to grips with it. Docker is a great place to start but there is at least one other viable alternative which is good for everyone, IMO.

  • "...but there is at least one other viable alternative which is good for everyone" So which might it be this one other viable alternative? – Trilarion Jul 19 '17 at 7:52
  • @Trilarion rkt (or rocket). It's currently supported by Kubernetes along with Docker. – JimmyJames Jul 19 '17 at 13:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.