Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It is pretty cool, but I'm starting to see a lot of comments like this about the Dockerfile:

> I don’t need to worry about the version of node, nor of the dependencies nor anything else. If it’s worked for them, it’ll work for me. As simple as that!

This isn't true as far as I can tell, the Dockerfile will have a series of lines like this

    RUN apt-get install x
    RUN apt-get install y
    RUN apt-get install z
    RUN cat "config line" >> /etc/config.conf
which does not guarantee success any more than a makefile on a clean install would. Those versions can change, bugs can be introduced or features changed and the config file location or type can change. If you build it today and I tomorrow then we could have different images running.

I'm aware that this file is to generate a "run anywhere" image, but I worry people might be treating it as a huge step on from installation scripts when it's very similar. The image part afterwards, however, is a huge step onwards.



Spot on. Once an image has been built its safe to say that it can be moved around and ran even after a lot of time has passed. The build process is another story; even though you have the steps(the logic) for creating the image(the result), you still need to control the package sources(the input data) to get an image that works correctly. I think the build process maintains its "run anywhere" property, but it doesn't maintain its "run anytime" property.


I've been doing a lot of research lately into more deterministic dependency management and reproducible builds by leveraging hashes via git.

You might be interested in MDM[1], which is a general-purpose dependency manager for binary blobs.

Specifically for container images, you also might be interested in hroot[2] -- it separates the concept of the image and transport out from the containerization system.

I agree wholeheartedly that it's the image permanence that's the interesting part about containers right now. In the last 24 hours I actually had an experience where a docker setup full of apt-get's failed to reproduce an image (new deps were added upstream that broke the system). Fortunately with hroot, I had the exact filesystems I had previously produced in a permanent, transportable system, and all covered by a hash so my production system could fetch exactly the correct version. I could have done this all manually with tars, but that's a pain for nontrivial use cases, and I could have done it with a docker registry, but I'm too much of a security nut to use the public one, and I already have git infrastructure set up, so it's actually easier to use that than try to spin up a private docker registry and secure it, etc.

[1] http://github.com/polydawn/mdm [2] http://github.com/polydawn/hroot


Why would you use apt-get with an upstream repository? Deployment 101 is to set up your own local repo mirror so that you control exactly what binary objects get deployed.


Dockerfiles are just "run anywhere", not "run any time". Maybe I should have made it clear. The creator still needs to maintain his Dockerfile. Maybe http://blog.docker.io/2013/11/introducing-trusted-builds/ will make things easier.


I think the level of detail you have worked fine for the writing style, my comment is somewhat nitpicky. Your statement is generally true, if they use the dockerfile they posted then it's extremely likely to work for you too.

It was mostly a clarification for people reading that the dockerfile doesn't guarantee repeatable builds.

Thanks for the post :)


Hi, Docker author here.

This is a perfect example of how we're trying to design Docker: by looking for the right balance between evolution and revolution.

Evolution means it has to fit into your current way of working and thinking. Revolution means it has to make your life 10x better in some way. It's a very fine line to walk.

I think a lot of bleeding edge tools sacrifice evolution because it involves too many compromises - there's a kind of "if they don't get it, their application is not worthy of my tool" mentality, and as a result the majority of developers are left on the side of the road. I see several tools named in this thread which suffer from this problem, and as a result will never get a chance to solve the problem at a large scale.

In this example of build repeatability, "evolution" means we can't magically make every application build in a truly repeatable way overnight. However, we can frame the problem in such a way that lack of repeatability becomes more visible, and there's an easy and gradual path to making your own build repeatable.

Sure, you can litter your Dockerfile with "run apt-get install" lines, and that does partially improves build repeatability: first with a guaranteed starting point, second with build caching, which by default will avoid re-running the same command twice. Your build probably wasn't repeatable to begin with, and in the meantime you benefit from all the other cool aspects of Docker (repeatable runtime, etc), so it's already a net positive.

Later you can start removing side effects: for example by building your dependencies from source, straight from upstream. In that case your dependencies are built in a controlled environment, from a controlled source revision, and you can keep doing this all the way down. The end result is a full dependency graph at the commit granularity, comparable to nix for example - except it's not a requirement to start using docker :)


Hi, nice to speak to you.

I agree, this is the right way to go about it. Someone with a nicely repeatable build can go ahead and get that with docker too, someone without still that gets a nicely distributable image. Docker seems to have taken off quickly as there's a benefit very soon after you start using it, and very little to get in the way of you having something running.

There's an issue in that people see the claims of one part and think they apply to the whole (I don't think the poster thinks that, but people reading it might get that impression), but this is a problem of education, not a technical one.


The dependency issues are solved if you reuse a given docker image; as you said.

Yes, the procedure of generating the image (Dockerfile) is basically a glorified installation script.

But I don't understand why you use the properties of the image creation tool to refute runtime properties of docker images.

EDIT: like if when discussing the properties of a perfect headache free binary package management system, you mention that the code is still not guaranteed to be the same because when the packages are built, two builds of the same package could be slightly different. The purpose of the binary packaging scheme is to use the built artifact. Repeatable builds are a secondary goal.


> But I don't understand why you use the properties of the image creation tool to refute runtime properties of docker images.

I'm not, my concern is that the language used suggested that having a Dockerfile meant that if it builds for one person it would build for all when this isn't the case.

That's not a problem with docker, as it's not something docker is trying to (or claiming to) solve. I'm worried that some people might think it is, so thought I'd post here to clarify things.


This is solvable by using a more deterministic system like Nix as the base build box.


Or using a package manager which allows to specify exact versions of the artifacts, like npm or maven.


or apt-get...


For that to work you'd have to have your own repository with all the packages you install. Old specific versions will not be preserved in the upstream repos if a new package is released.


Right, but that's not really a problem, is it? My understanding is that committing dependencies is strongly discouraged -- if you're writing libraries or modules intended for distribution and others' use. On the other hand if you're deploying a standalone app, locking down any specific dependencies' versions and committing them is actually considered a best practice, as it's the only way to be sure it won't unexpectedly change. Right? I'm genuinely interested in others' thoughts and experiences here.


The problem is that you're now forcing all of your users to use the library you bundled. First, this bloats the system, since you now don't share dependencies between applications. Second, it makes the system more complicated because there are multiple library copies floating around the filesystem. Third, it means that when you really do need to change a library/dependency, you can't just update the libfoo package, you have to update every application.

In my experience (Linux on the desktop), bundling dependencies is an indicator of poor software quality, but I realize that the situation may be different on other systems.

In this case, I think that the solution is to use the distro's package manager to pin minor versions and rely on the distribution's updates for security fixes. Hosting your own repo is a bad idea, since it means you won't get any software updates. Software updates are really important -- they have security patches and bug fixes. If you're worried about the distro changing something from under your feet, you should pick something more stable. Debian or CentOS are good choices.


Ok, but here it seems like you're referring to "[my] users" as if they were consumers of the library -- that is, as if they were developers. That's still my first case in which I agree committing / bundling dependencies is a bad idea. I'm talking about the 2nd case, of locking down dependencies used to build an application whose "users" are not even aware of the presence of dependent libraries nor the structure nor configuration of the underlying software. In this second case, isn't [freezing/shrinkwrapping/committing/bundling] the dependencies generally considered the right thing to do?

Of course, updating the dependencies (whether for patches or more consequential updates) in subsequent releases is fine... but within a given release cycle, one otherwise runs the risk of unexpected inconsistency, between e.g. a developer build and a CI build done a short time later.

I think this discussion illustrates the problem and might be more articulate than I'm being: https://github.com/bower/bower/pull/538

Thanks @hdevalence -- and anyone else who cares to comment. :)


That is just basic common sense. It is easy to mirror upstream repos that you need. Don't allow your systems to have dependencies that are outside of your control.


If run in the same machine, I think it will install the same version every time... won't docker cache the change and just play it back?


not if there is a non-cacheable command like "apt-get update". And if the subsequent command is something like "apt-get nodejs", then potentially two builds can have two different versions




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: