Hacker News new | ask | show | jobs
by minimaxir 3981 days ago
While the article goes into the more technical reasons for not using Docker in production, the practical reason "Why Docker Is Not Yet Succeeding Widely in Production" is that if it ain't broke, don't fix it. The advantages of Docker do not necessarily outweigh the opportunity cost of rewriting the startup's entire infrastructure.

Docker will likely be more prevalent in a few years with startups who have built their infrastructure form the ground up.

7 comments

Docker solves a problem that most people don't have. It's not a PaaS, rather, it's (some of) the building blocks to create your own PaaS. Most folks don't need that. Most folks want to put files on a server and start a process. For those folks, Docker in the raw ends up being a whole lot of confusing & unnecessary scaffolding.
Moreover, Docker / Kubernetes aims to solve the problem of building services that can easily scale to hundreds of machines and hundreds of millions of users, "Google-style".

That's great, if that's what you need. But most people aren't building a service like that. HN, I believe, runs on one machine, with a second for failover purposes. And HN still has many, many more users than typical company-internal services, community services, or at the extreme end personal services.

When you aren't operating at absurd scale, "Google-style" infrastructure doesn't do you any favors. But the industry sure wants to convince us that scalability is the most important property of infrastructure, because then they can sell us complicated tech we don't need and support contracts to help us use it.

(Disclosure: I'm the lead developer of https://sandstorm.io, which is explicitly designed for small-scale.)

"But the industry sure wants to convince us that scalability is the most important property of infrastructure, because then they can sell us complicated tech we don't need and support contracts to help us use it."

And lets not forget: replace any and all efforts at code optimization with "just throw another rack of blades at it".

i just use google cloud's HTTP Loadbalancer and AutoScale. it automatically spanws/remove's VM's based on load.
There was also a time when most people thought they didn't need version control. Back in the 80s and 90s it was a justifiable viewpoint because existing version control systems sucked.

The problem with Docker is not that it doesn't solve (or attempt to solve) widespread problems. At its best, Docker gives you dev/production parity, and dependency isolation which is useful even for solo developers working part-time. The problem is that it's not a well-defined problem that can be solved by thinking really hard and coming up with an elegant model—like, for example, version control—it's messy and the effort to make it work isn't worth it most of the time right now.

That's no reason to write off Docker though. Pushing files to manually configured servers or VPSes is messy and leads to all kinds of long-term pain. You can add Chef / Puppet, but it turns into its own hairy mess. There's no easy solution, but from where I stand, the abstraction that Docker/LXC provide is one that has the most unfulfilled promise in front of it.

> At its best, Docker gives you dev/production parity

I get that when I use the same OS and built-in package manager?

I would virtualize the environment using something like VirtualBox for my dev and EC2/DigitalOcean/etc on prod.

> and dependency isolation

If you're going to scale something, you're going to split everything out on different virtualized servers anyway, so you'll get your isolation that way.

Basically, current mainstream practice is to virtualize on the OS level, where as Docker is pushing to have things virtualized on the process level.

I personally don't see the advantage ... just more complexity in your stack. I never have to mess with the current virtualization structure, I don't even see it. It looks just like a "server", even though it's not. Isn't that better?

To be fair, I've worked in places where all the devs were on the same OS, same version, and we still had problems.

But I agree, just use VirtualBox. I know Idea already supports deploying to VMs and you they just look like another machine, so no learning curve. All the benefits with none of the hassle.

Yeah, but then there's still the issue of secrets, you need to have testing PayPal credentials, testing mailing service credentials, etc. There's the issue of deploying changes fast without leaving files in an inconsistent state (you don't want half of some file to run). How about installing the required dependencies?

I don't use Docker, but those are problems I can think of off the top of my head.

Docker doesn't credibly solve the credentials problem and the other problems you outline (which do exist) are as practically solved with something like Packer. And I mean, I'm not a Packer fan--oh look, VirtualBox failed to remove a port mapping for the VM that just shut down, throw away the whole build--but it's built on much, much more battle-tested technology with a much wider base of understanding.

(And, later, if you want to play with Docker, Packer lets you do that too. But you should use the Racker DSL in any case, because life is too short to deal with Packer's weird JSON by hand.)

Thanks for pointing me to Racker (https://github.com/aspring/racker). I'm currently building Packer and Terraform images with chunked together Python scripts that work, but I wouldn't call them a great solution. I'm actually using Packer specifically so I can start with regular EC2, and then move to a more Docker-based infrastructure.
Credentials have to be managed separately from Docker anyway.

> There's the issue of deploying changes fast without leaving files in an inconsistent state (you don't want half of some file to run). How about installing the required dependencies?

rpm / dpkg also install dependencies, are quite fast and well tested. They have the advantage of working in a standard environment which most sysadmins know but the disadvantage that you need to configure your apps to follow something like LSB (e.g. install to standard extension locations rather than overwriting system files, etc.).

The one issue everything has is handling replacement of a running service and that's not something which Docker itself solves – either way you need some higher level orchestration system, request routers, etc. Some of those systems assume Docker but that's not really the value for this issue.

> the disadvantage that you need to configure your apps to follow something like LSB (e.g. install to standard extension locations rather than overwriting system files, etc.).

Common misconception. You only need to do this if you're going to try to push the packages upstream. If they're for your own consumption, you can do what you like. Slap a bunch of files in /opt, and be done with it - let apt manage versions for you and be happy.

As with many things, this is one area where you've just got to know what to ignore. It's simpler than it looks.

rpm and fast don't really go together. dpkg is much better. dnf will be interesting.
> Yeah, but then there's still the issue of secrets

How would Docker help with this? Genuinely curious.

I store them in bash scripts outside the repo that populate the relevant data into environment variables and execute the code. The code then references the environment variables.

> How about installing the required dependencies?

There are two kinds. On the OS level and on the platform level.

On the OS level, you can have a simple bash script. If you need something more complex, there are things like Chef/Puppet/etc.

On the platform level, you have NPM/Composer/PIP/etc which you can trigger with a simple cron script or with a git hook.

> There's the issue of deploying changes fast without leaving files in an inconsistent state

So the argument here is that you're replacing one file in one go vs possibly thousands? That in the latter scenario the user might hit code while it's in the process of being updated?

Ok. With docker, you would shut it down to update. You would have to.

Same goes for the traditional deployment? Shut it down, update, start it back up?

You can, of course, automate all of this with web hooks on Github/Bitbucket, for both docker and the traditional deployment.

The traditional deployment should also be faster, since it's an incremental compressed update being done through git.

Kubernetes secrets are a really great solution to this problem. [1] They are stored at the cluster level and injected into the pod (group of containers deployed together) via a file system mount. This means that each pod only has access to its secrets which is enforced by the the file system namespace. If an entire machine is compromised, only the secrets of pods currently scheduled onto that machine are able to be stolen. That's a high level, but it's worth taking a look at the design doc.

Edit: forgot to mention, the file system mount means that they don't need to be in env var, which are fairly easy to dump if you have access to the box or are shipping containers around in plain text.

1. https://github.com/GoogleCloudPlatform/kubernetes/blob/maste...

I don't know if Docker helps with this, I don't use Docker. But some kind of solution has to exist.

How AWS does updates is it first downloads the new code into a separate folder and then switches the link to point to the new folder instead.

But AWS has an unsatisfactory feeling because it downloads the entire code instead of doing a git update. These are all issues that could be fixed, and someone has to do them. I have no idea if Docker helps with any of them, but the opportunity is still there.

Ansible, systemd and go is stealing my heart at the moment. Basically pick the tech that doesn't cause the problems to start with.

I still reckon that the main reason VMware ESX is as successful as it is comes down to the lack of isolation and sheer deployment hell that windows has been for years. The same can be said for python or ruby on a Linux machine for example. Docker removes some of that pain like ESX does.

That's a bit of my point... If you're building relatively small independent services with Docker you can deploy service A with node 0.10 as it's tested environment and service B with iojs 2.4 on the same server, without them conflicting... when you need to update/enhance/upgrade service A you then can update the runtime.

The same can be said for ruby, python and any number of other language environments where you have multiple services that were written at different times with differing base targets. I've seen plenty of instances where updating a host server to a new runtime breaks some service that also runs on a given server.

With docker, you can run them all... given, you can do the same with virtualization, but that has a lot more overhead. It's about maximum utilization with minimal overhead... For many systems, you only need 2-3 servers for redundancy, but a lot can run on a single server (or very small cluster/set)

I have to agree on ansible, systemd and go... I haven't done much with go, but the single executible is a really nice artifact that's very portable... and ansible is just nice. I haven't had the chance to work with systemd, but it's at least interesting.

> The same can be said for ruby, python and any number of other language environments where you have multiple services that were written at different times with differing base targets. I've seen plenty of instances where updating a host server to a new runtime breaks some service that also runs on a given server.

This is a solved problem in Python and Ruby. In Python, use virtual environments. In Ruby, use RVM. You won't have the issue of one tenant breaking another.

And with node, you can use nvm... however there are libraries and references at a broader scope than just Python, Ruby or Node... Say you need an updated version of the system's lib-foo.

A runtime environment for a given service/application can vary a lot, and can break under the most unusual of circumstances. An upgrade of a server for one application can break another. Then you're stuck trying to rollback, and then spend days fixing the other service. With docker (or virtualization) you can segregate them from each other.

You're correct, but I can see that there's certainly a place for having a single solution that works across all ecosystems.

Also, RVM in production? Sledgehammer to crack a nut :-)

In local system yes, but in production its painful to work with. With RVM for isolation you would create gemsets for each app with specific ruby version. It OK for 2-3 applications, but anything more than that would be a pain to work with. And then if you plan to put everything behind passenger, it would just be too messy. Think of automating this? Would be a nightmare to maintain. Over here containerization does help.
Node has this too : nave, npm and n. But using these tools means that you are not longer using the package manager of the system and this can be a problem sometimes. Eg you need to open your firewall to something else that it is not the standard pkg manager.

I see docker as a valid attempt to fix limitations of existing and broken package system (eg: apt) at a price that I am not yet willing to pay.

Virtual environments doesn't work for the interpreter itself. Not only that some of the packages will need to build c extensions and they use different versions of the same library which might break.
It partially is, until you need native dependencies.
Which version of RVM are we running again?
If you want to put files on a server and start a process, you are probably looking for something like Apache, not a "PaaS" necessarily.
Docker will likely be more prevalent in a few years with startups who have built their infrastructure form the ground up.

The opposite seems likely ... Docker will fade and become deprecated as building infrastructure from the ground up locally to feed into the cloud becomes cheaper and cheaper still. AWS is not always so cost-effective when you truly dig in and crunch the numbers.

My guess as to why Docker won't succeed widely in production is because it's a software-based solution trying to glue together slippery pieces that just don't want to be glued together. The core issue of security will never be solved by a Docker-like solution; that problem is best solved by integrated hardware.

This very issue is being addressed in ClearLinux: http://sched.co/3YD5

DevOps/infra guy here rolling out Docker startup-wide at the moment. You and minimaxir are both correct.

With regards to docker/lxc/container security, you're right. Some of the biggest players haven't solved the lxc/docker/container security issues yet; its a really hard problem to solve. Breaking out of container will always be easier than breaking out of deeper levels of virtualization (Xen/KVM).

> Breaking out of container will always be easier than breaking out of deeper levels of virtualization (Xen/KVM).

I agree it's not easy to get right, but it doesn't seem necessary that containers will always be leaky. Solaris/Illumos Zones are an OS-level virtualization approach that's pretty airtight, for example.

I agree. But that's my biggest problem with Docker. Who runs SmartOS and uses Zones? Why?

When you have a local server, that supports KVM and Zones, you choose KVM as the cleaner abstraction. While surrounded by neat tech, Zones are actually a bit of a pain and not all that portable between systems IME. OTOH I can `zfs send/recv` over SSH, drop a short bit of JSON in, and have my KVM instance reliably moved to another SmartOS box 100% of the time, no worries.

So unless you're really worried about that last 5% or whatever of overhead, what's the point of Docker? It's not actually very portable at all it seems (on my Mac I'd have to run it inside VirtualBox). I don't have much experience with it, but my guess is that similar to Zones, you're at the mercy of the host system as far as common dependencies like OpenSSL or gcc go.

It seems like a solution to a problem I'm having trouble even imagining. A slightly lower overhead, less secure, less portable lightweight "VM" with slightly less overhead. I guess if you're a PaaS and you could increase margins by 5% overnight by switching to Docker that might make sense?

As someone who's set up Solaris 10, OpenBSD, FreeBSD, SmartOS, Debian, Redhat, Ubuntu, KVM, Xen, etc etc etc, I just have a real hard time figuring out Docker's value proposition. It seems like the Solaris world went from Zones to KVM, and some people are attempting to do just the opposite. Which I just can't think of a good excuse for.

I believe Docker's biggest feature is it's speed of building. It's a trade-off of portability vs. temporary-ness.

I currently use it for MySQL DB restoration and remote bug-checking by having a handful of xtrabackup instances that I can quickly attach a docker to, hand an IP to a developer, and he can then debug the problem with production data _at that exact point in time._

When they're done, I simply throw that docker away.

It's a tool that (in my mind) doesn't solve any existing problems better than a lot of tools out there. It instead should be thought of like a better hammer for the same nail. Think of it like... would you rather have a giant set of wrenches, or a single ratchet with a set of sockets? They both accomplish the same thing, but both are better for certain jobs.

> AWS is not always so cost-effective when you truly dig in and crunch the numbers.

If you have a consistent level of traffic (i.e. you don't have inordinately wild upswings/downswings like e.g. Reddit), AWS isn't even remotely cost-effective. I was going to do the math to compare our current physical server infrastructure with AWS, and even if you factor in that physical servers need to be in pairs (for redundancy) and over-provisioned (for traffic spikes), I didn't even get as far as back-of-the-envelope math before it was obvious that AWS was completely infeasible.

There's one clear cut use case where AWS/Azure are incredibly cheap - Disaster Recovery. At my last job, we maintained a small DB instance and nothing else but an empty VPC. Within 15 minutes, we could spin up the entire DR stack including resizing the DB to support Production. There's no equivalent for this when you ONLY run your own hardware - you're stuck with a second site that sits there idle (unless you intend to do Active-Active which has its own share of problems).
Running your own hardware is always going to be cheaper - but you also need to employ folks with hardware management skills. That's fine if you already have those.

Similarly, cloud offerings give you remote reach easily - one company I work at has it's production servers almost literally on the direct opposite point of the globe. You can do datacentres with remote hands, sure, but it's another layer of complexity. Hardware also has a mild barrier to entry in the form of cost - for small shops, doling out the five or six figures you need for initial hardware is a pretty sizable chunk.

I have mixed feelings about Docker. I've found three major use cases so far:

(1) Testing.

(2) Build environments -- it's helpful to build distribution Linux binaries in older Linux versions like CentOS 6 so that they'll work on a wider range of production systems.

(3) Installing and running "big ball of mud" applications that want to drag in forty libraries, three different databases, memcached, and require a custom Apache configuration (and only Apache, thank you very much).

#3 is really the killer app.

This has led me to conclude that Docker is a stopgap anesthetic solution to a deeper source of pain: the Rube Goldberg Machine development anti-pattern.

More specifically, Docker is a far better solution than the abomination known as the "omnibus package," namely the gigantic RPM or DEB file that barfs thousands of libraries and other crap all over your system (that may conflict with what you have).

Well written software that minimizes dependencies and sprawl and abides by good development and deployment practices doesn't need Docker the way big lumps of finely woven angel hair spaghetti do.

Docker might still be nice for perfect reproducibility, ability to manage deployments like git repos, and other neat features, but it's less of a requirement. It becomes maybe a nice-to-have, not a must-have.

But... if my software is not a sprawling mess that demands that I mangle and pollute the entire system to install it, why not just coordinate development and deployment with 'git'? Release: git tag. Deploy: git pull X, git checkout tag, restart.

Finally, Docker has a bit of systemd disease. It tries to do too much in one package/binary. This made the rounds around HN a while back:

https://github.com/p8952/bocker

It demonstrates that at least some of Docker's core functionality does not require a monster application but can be achieved by using modern filesystems and Linux features more directly.

So honestly I am a bit "meh" about Docker right now. But hey it's the hype. Reading devops stuff these days makes me wonder if "Docker docker docker docker docker docker docker" is a grammatically correct sentence like "Buffalo buffalo buffalo buffalo buffalo buffalo."

>Docker might still be nice for perfect reproducibility

Docker actually doesn't help reproducibility at all, because the underlying reproducibility problems present in the distro and build systems are used are still present. See GNU Guix, Nix, and Debian's Reproducible Builds project for efforts to make build truly reproducible.

I had a good laugh when I read "the Rube Goldberg Machine development anti-pattern". This describes the situation of "modern" web development perfectly. I'll add that such software typically requires 3 or more different package managers in order to get all of the necessary software. And yes, Omnibus is an abomination and Docker is much better.

I think Docker is papering over issues with another abstraction layer. It's like static linking an entire operating system for each application. Rather than solving the problem with traditional package management, Docker masks the problem by allowing you to make a disk image per application. That's great and all, but now you have an application that can only reasonably be run from within a Linux container managed by Docker. Solving this problem at the systems level, which tools like GNU Guix do, allows even complex, big ball of mud software to run in any environment, whether that is unvirtualized "bare metal", a virtual machine, or a container.

> It's like static linking an entire operating system for each application.

You say it like it's a problem, but that's the most concise description of Docker I've yet read. It rhymes with the way all the fed up oldies using Go like its static linking.

This is pretty much how I view Docker as well. Except it's not really the entire operating system. A VM image is the ultimate static linking.
Nothing wrong with linking together a couple things to build an app... I call it Rube Goldberg (a.k.a. ball of mud, pile of crap, etc.) when it's like dozens of things that all have to be tweaked in exactly a certain way or everything assplodes.

I simply will not run apps like that unless I have no choice. If I see that, plonk it goes into the trash.

... and yes, the whole package management situation is comical. Every language has its own package management system, and the OS, and sometimes people use both at the same time. It's ridiculous.

> It demonstrates that at least some of Docker's core functionality does not require a monster application

```The following packages are needed to run bocker.

btrfs-progs curl iproute2 iptables libcgroup-tools util-linux >= 2.25.2 coreutils >= 7.5 Because most distributions do not ship a new enough version of util-linux you will probably need grab the sources from here and compile it yourself.

Additionally your system will need to be configured with the following.

A btrfs filesystem mounted under /var/bocker A network bridge called bridge0 and an IP of 10.0.0.1/24 IP forwarding enabled in /proc/sys/net/ipv4/ip_forward A firewall routing traffic from bridge0 to a physical interface. A base-image which contains the filesystem to seed your container with.```

Is this the "well-written software" pattern that you're talking about? Because to me, this looks like a "big ball of mud" - i.e. dependence on an eclectic combination of libraries, co-programs, and environment configuration - and indeed, if for some perverse reason I felt like I wanted to deploy this in production, it's exactly the kind of thing I'd wind up writing a Dockerfile for. (Which, I notice is functionality "Bocker" doesn't attempt to replicate.)

A few packages are needed, but in their standard configurations. Bocker does not require you to install hundreds and specially tinker with each one the way many web stacks do.
> is that if it ain't broke, don't fix it.

I hate being passive-aggressive so I'll be directly aggresive here: this mentality is a way to say, "I don't want to revisit the operational aspects of my system because I don't like to do that work. Find someone else."

Like any aspect of your system, your ops and deploy components can rot. Pretending otherwise is outright ignoring a consistent lesson offered by those who came before and have failed over and over.

Docker offers to take over as a project many aspects of the system subject to bit-rot and make an explicit and consistent container abstraction for software to compose. While it has many features we do need (I agree wholeheartedly that it'd be great to parallelize layer creation, less so about secret exposure since the environment & volume tooling already can do that), it has also replaced whole categories of software and devops tooling with simple and extensible metaphors.

I disagree. It's all about "the evil you know".

And then there's the part where Weave is slow, so you might as well stick to VMs or hardware...

http://www.generictestdomain.net/docker/weave/networking/stu...

On Weave, yeah. Not the best performance, and improving. Flannel is obviously better, and one of the reasons we're excited about rocket. That changes almost nothing for shops hoping to move to containerized architectures now. It's only for existing early adopters.

The idea that docker introduces that much uncertainty is outright fear mongering. There is a huge amount of recalcitrance in the community to do anything meaningful in the space due to a proposed risk aversion. My personal opinion is that we're all pretending we didn't write incredibly delicate and brittle provisioning and monitoring code with very dated tools.

Many people I know, and more than a few I respect, ultimately point to all their provisioning shell scripts as the ultimate reluctance to change things. "It will be really hard to migrate and test these! Generating them is a pain!" Of course, the elephant in the room is we all knew this going into it and we all know we SHOULDN'T have been doing things like generate shell script execution and using git to provision on production boxes and w/e other hacky shit we've done.

Of course, what we have is not any one thing but all too often an amalgam of spare hours and quick fixes and patches laid over some existing provisioning system like salt, ansible (or just a whole shit ton of puppet work).

Counter-intuitively, suddenly everyone has become a devops luddite when it comes to a genuinely novel approach even though container abstractions have already proven themselves at scale. People hem and haw and suggest that somehow it's not ready for production. Meanwhile major players in the space are already using them, even for core services, with excellent results.

Lightweight containerization has been used to solve this for awhile now. Docker as a product and initiative is relatively new, but to suggest it was the first example of a container engine used in production ignores the actual history of lightweight containers.

Show me how I can easily audit all my docker containers for vulnerabilities from spacewalk

Show me a docker-aware Rapid7

There are a lot of tools for security and compliance completely thrown out with the bathwater when you move to containers. You're not going to get enterprises to bite until you can satisfy the auditors.

Cool. I'm glad that I'm in the only top 10 bank in the US using stacakto.
I had a very smooth workflow on Python/Django/AWS. Thought of checking out Dockers for the last project and boy did that hurt! "if it ain't broken, don't fix it" is very appropriate here. I would suggest that until you've huge issues with deployment, skip dockers. For me, it added loads of work instead of simplifying the flow.
How does Python/Django deploy itself to AWS?

Last time I checked, Python and Django are agnostic to their operational concerns and deployment.

Even if you're building brand new infrastructure from scratch right now many issues (discussed elsewhere in these comments and the article) are still unsolved.
Yup. At my last gig we built out a Mesos cluster and were deploying Docker containers, but we couldn't answer "how do we practically secure this to the same level as independent virtual machines?" and, finding no good answer, we went back to auto-scaling groups and baked AMIs.
Yes, doing the same thing here as well. Still using docker to streamline deployments though, but one docker container/role per instance, no "orchestration" for containers (baked AMIs, ASGs).
I did that at one place, but I wasn't super satisfied with the process--having to download container images on spin-up was annoyingly slow and I didn't feel like we were getting better dev/prod consistency versus Vagrant and Packer.
We bake the container into the AMI, so no fetch is necessary at spin up (there is no cost to generate AMIs, only storage fees, so cost is not an issue).

Packer is used to build the AMIs with the containers built-in, and Docker is used both in Prod (single container to each AMI) and Dev (Docker Compose to bring up entire dev env locally). Both used a shared docker registry.

Ahh, gotcha. That's a neat approach, though the double hit of Docker builds + AMI builds feels a little weird to me. Thanks for the insight.
It's quite possible but the most straightforward answer is somewhat ugly - install endpoint security in every container. For example, each container would need to have intrusion detection, iptables, etc. Other options would include having containers route traffic with a virtual LAN setup and you have a container whose function is to replace your usual network security appliances. And the irony is that shared services like that can be put into both control and data planes which is easy with hypervisors and software defined networking combined with storage fabric security. When it comes to security, you honestly should be securing things at every layer anyway, but in a lot of places I see people not bothering with iptables and delegating 80%+ of the security responsibilities to operations while application teams focus upon application security.
I was wondering, what did you think of the production readiness of Mesos independent of Docker?
Seems reasonable, if you want to be running lots of things on the same boxes without isolation (I'm not comfortable with that, but you might be). If you're sharing those resources for stuff like Spark, ElasticSearch, etc. I think it makes sense as a work scheduler, but there are a lot of other options to consider too.
I have a client, pre-funding but has some revenue, who is hell-bent on using their Rackspace credit for their production environment. "But we have a sysadmin who works for yahoo"

He tries to demo me what they have currently and the damn thing timed out during login. I laughed.

The cost of these headaches is easily avoidable. Get off the ground and running first, pay the kind-of-premium Heroku bill, and when you're ready to really scale, make the switch.

There are few exceptions to managing an infrastructure, such as RackSpace, a cluster of AWS nodes, your own metal, etc. versus something like Heroku.

New startup. Did not use docker. Happy with scripts and ansible.