I'm happy to answer any questions you may have.
I'm happy to answer any questions you may have.
What’s funny, though, is that since it was “just” a lightning talk, it didn’t even make it into the roundup of notes I sent to my team after PyCon. But a mere year later, Docker was how my team (and seemingly everyone else) ran projects locally.
Any interesting memories from that day in 2013? From your perspective, what happened in the year that followed that caused docker to be adopted so widely? Were there other key moments or turning points?
That day is forever engraved in my memory... Off the top of my head:
I signed up for a lightning talk expecting an audience of 10-20 people, for a confidential demo of our unfinished project that we had so far only showed in 1-1 demos. Imagine my surprise when I learned Pycon does lightning talks on the main stage!
The previous speaker didn't show, so I started early. In the recording you can hear me joke that perhaps I should get his time allocation too - the MC was not amused.
I went over time and had to speedtalk through the end.. The MC once again was not amused and practically shoved me off stage :-D
We had a small sponsor booth at the even, where our small marketing team was prepared to pitch our product (DotCloud) but was thoroughly confused when a horde of people showed up after the talk, to ask about "Docker" - which as far as they knew was the founder's side project.
I drove down to Santa Clara on my newly acquired motorcycle - my very first trip on the freeway. I remember telling myself, "today is the day to take all the risks!"
I had a pretty much near death motorcycle accident I happened to mostly walk away from which really made me restructure my perspective on things I'm afraid of.
It also managed to make my then to be wife realize she really couldn't live without me when I sent her a photo of a mangled bike and the text "ouchies", so that accident really changed my life positively and radically.
Although I'm still sad it destroyed my OG Surface Pro. It was a maxed out launch model with the year of the dragon touch cover I bought at a Microsoft store at a mall that doesn't even exist anymore. Worn in a messenger bag on my back, and ended up like a crazy twisted piece of metal in the end.
So yeah. Motorcycles. They'll change your life.
I remember my first time trying to use a container was about 2015 on a beach cafe's wifi in Bocas del Toro, Panama. You can imagine how it went...
After a brief hiatus though I was back to it and since then it's been a core part of many a local dev stack and even production stack (compose) I've set up. I recall the magic moment for me being when I first realised you could mount src to use all your local native dev tools while completely virtualising everything else, including and especially whatever combo of runtimes and dependencies you need.
It was just a lightbulb moment, like it entirely solves 'works on my machine', setting new people up on a project, it just seems like how software engineering ought to work and once you have experienced it it's difficult to go back.
I'm curious, as its creator are you still using it, or as someone who can clearly look ahead to experimental ways of doing things are you on to the next thing whatever that may be? If so, what is it? :-)
Yes, I still use Docker. Although my way of using it has changed over time, like many others I assume.
My new project, Dagger, although it doesn't directly compete with Docker, does implement its own container runtime and orchestrator (for CI pipelines), and we recently added compatibility with Dockerfiles and Docker Compose files... So increasingly I find myself using Dagger instead of Docker, in the context of my CI pipelines.
On the other hand, I use docker compose on almost every personal project - like a minecraft server for my kids, home automation, AI hacks, etc. These days I just let my AI agent set it up for me, though :)
Yeah I've really been enjoying using AI to write docker/compose config and related ad hoc scripts. It was all pretty understandable anyway, but now you can just set up whatever you can think of in literally minutes, even if you just want a particular configuration as a one off. It's a great era for devops!
I take it vito talked you into adopting Garden? </injoke>
“You’re overpaying for CI” (https://www.youtube.com/watch?v=tsH3eTo2GLI) from KubeCon 2024 seems especially pertinent these days with AI.
Was one of my favorite talks that year and really made Dagger click for me.
Hope to see you this year in SLC!
Even if you don't need to? Even if there's no benefit?
I was handed a vibe coded project recently, a radio station playout system. For some reason, it's spread across 8 different Docker containers. One container has just Icecast in it, for example.
It's a private system that runs a single station on a dedicated server that we have full control over, but because of all the containers, it's harder to do common tasks like check a log or edit a config file.
OTOH it's a godsend for setting up a local dev machine or something like that, where you need to run different vendor provided packages. but I'm tired of all the mindless over-engineering (which unfortunately the LLMs trained on).
I was there when dotCloud announced Docker in 2013 and it was truly pragmatic. I had previously burned my hands on LXC, Juju Charms and Vagrant to containerize the apps, but it was all a house of cards. I remember helping a friend ship his whole Vagrant Box to the interview panel for a job!
It’s incredible to think about how much boilerplate Docker removed right at it's launch. Thank you.
That's for sure, especially for local dev.
You may have already answered this somewhere, so feel free to tell me what to search for or if you have a link to hand, that works too :)
I went down the rabbit hole of Incus and once I realized it requires the full network aspects to be configured, then I figured using KVM, QEMU, Libvirt was more practical. Then stumbled into nspawn and it was basically ready to go.
Although, I haven’t done enough research to know if Incus provides certain useful capabilities.
It includes project-level resource separation, advanced networking, clustering, snapshots, and more. Plus, Stéphane Graber is super responsive on the forums and issue tracker. I bounced off of Proxmox, and can't recommend Incus more for hypervisor-type scenarios.
Docker in its earlier incarnations was based on openvz, which predates lxc. The lxc project was initially a kernel development project: a collection of kernel patches to add container support. The userland tool was just a companion. When it became apparent that these patches would "win" the race to be upstreamed even though openvz was much more mature, we switched our tooling to lxc. The patches matured over time, but the userland tool (what we now know as "lxc") was finicky.
The original open-source release of Docker wrapped lxc for low-level container operations. But it was just too unreliable and we swapped it out for an in-house Go implementation called "libcontainer".
As for "commercializing": Docker was famously bad at commercializing anything, we open sourced so much (maybe too much) and still people complained that we were not open enough.
Developers are a tough market to please, especially when your business revolves around open source software.
Unless you have an option to do private cloud hosting (like all these databases and other platforms do), it’s incredibly difficult to monetize.
In the case of docker, I think it’s in the nature of the product that it’s difficult to monetize. Best you can do is enterprise support contracts, but those aren’t good enough to justify all that VC funding.
Podman has never been commercialized.
Docker's difficulties in commercializing were self-inflicted. Enterprise and open source teams were culturally siloed and as a result the enterprise products were not "native". There was a lack of focus and a "checkbox" approach to building product. There was no singular "dictator" who could enforce a coherent product design and vision, and it showed. etc.
I always assumed it was the same internal tech, now productized. Then of course, it became THE tech, overtaking vagrant and anything else for local development and deployment. The latter was the true money shot. Server runs exactly what you test with locally.
That's because there was never a proper sysadmin on your team to slap some sense in your decisions.
You've got too opinionated[0], too tied on yourself[1] monster which required too much resources what you can handle alone.
And your market is not the developers but the companies where whose developers have a daytime jobs: https://news.ycombinator.com/item?id=34377674
BTW just for giggles opened hub.docker.com with Network Tools opened:
368 requests, 9.62MB, Finish: 4.50s.
For a thing which should be a static cached copy with everything bundled. Sure, it's a progress from the previous iterations when it could hang for 30 seconds before actually loading... but this is still ridiculous.
[0] https://news.ycombinator.com/item?id=46739153
[1] Eg: the syntax to point the image to a specific registry is something... bad. So bad I just abandoned running my own registry, it wasn't worth it.
PS there is still (AFAIK) no support for a transaction-like image building in Compose. So instead of something like this:
TRANSACTION START
RUNBATCH set -eux
# TODO find a better userspace architecture detection method than querying the kernel
arch="$(uname -m)"
case "$arch" in \
aarch64) gosuArch='arm64' ;
x86_64) gosuArch='amd64' ;
*) echo >&2 "error: unsupported architecture: '$arch'"; exit 1 ;
esac
curl -fL -o /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$gosuArch.asc"
curl -fL -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$gosuArch"
export GNUPGHOME="$(mktemp -d)"
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc
chmod +x /usr/local/bin/gosu
gosu --version
gosu nobody true
TRANSACTION END
people need to write these one-liner abominations: RUN set -eux; \
# TODO find a better userspace architecture detection method than querying the kernel
arch="$(uname -m)"; \
case "$arch" in \
aarch64) gosuArch='arm64' ;; \
x86_64) gosuArch='amd64' ;; \
*) echo >&2 "error: unsupported architecture: '$arch'"; exit 1 ;; \
esac; \
curl -fL -o /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$gosuArch.asc"; \
curl -fL -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$gosuArch"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
chmod +x /usr/local/bin/gosu; \
gosu --version; \
gosu nobody true
EDIT: to add on [1]: https://news.ycombinator.com/item?id=35312087>>[0] 'Bridge' was and still is an established network term for joining two broadcast domains into one. Why the hell you decided to name your NAT'ed network layer a 'bridge'?
Like they told you 9 months ago, the terminology is exactly right. They're called "bridge" networks because they use Linux `bridge` devices to bridge `tap` adapters of all containers attached to the same Docker network.
There's nothing exotic about this terminology at all and complaining about it betrays your own lack of knowledge.
> PS there is still (AFAIK) no support for a transaction-like image building in Compose. So instead of something like this:
Do you mean Dockerfiles? RUN command has had heredoc support for 5 years now.
Oh, well. I guess you ride to your work on wheels, right? Because while you sit in the car/bus/train it's the wheels what actually rides on the road/track, right?
And if you bothered to look at that comment then why do you ignore what 'macvlan' - which is an actual bridge both in terms of a Linux device and the functionality - is not called 'bridge'?
Because you don't understand the problem. More so, you ignore the actual question there about the broadcast domains.
No, if even if you use a bridge internally when your container is on a isolated network which is invisible to anyone on your network and the container access the network behind your host through the NAT - this can't be called a bridge.
You see, if they just called it as it should, ig:
bridge => hostnatnetwork // or internalbridgenatnetwork or whatever else
macvlan => bridge
then they would be both named correctly and be the technically correct - and 99% of Docker users couldn't tell a difference - because they are not net or sys administrators.But the last 1% is the people who actually makes the workspaces for these developers where they actually do run their fancy-shmancy containers. And for that 1% it surely pays naming this as they are.
And there is also that dumb decision to silently rewrite 127.0.0.1 to Google DNS without a question. Especially when 98% of Docker users are incapable to diagnose it by themselves.
So it's not only the naming of a network functions.
But hey, I'm just knowledge lacking guy without experience at all, just yesterday saw a computer a first time in my life, sure, sure.
> RUN command has had heredoc support for 5 years now
So ten years late? Adoption is off the limits, as you can see - that snippet is from the official Docker image.
And if I need to run multiple commands and not just one RUN statement? Like the people are asking for years? And you so knowledgeable person of course do know the reason for that, right?
Because renaming things that map 1:1 onto the underlying concepts is a terrible idea that makes learning and communication harder by introducing ambiguity and indirection. "bridge" now means multiple things and not only is it needlessly obfuscated, it's wrong (explained later). I _hate_ projects that do this.
> Because you don't understand the problem. More so, you ignore the actual question there about the broadcast domains.
A Docker 'bridge' network driver creates a broadcast domain between containers attached to that network.
Rhetorical question, maybe it'll help you find a source of misunderstanding: Why do you expect it to join the broadcast domains of your containers and your LAN? And which LAN, exactly?
> No, if even if you use a bridge internally when your container is on a isolated network which is invisible to anyone on your network and the container access the network behind your host through the NAT - this can't be called a bridge.
Your misunderstanding seems to stem from the flawed assumption/expectation that every container is automatically attached to your LAN. Therefore you incorrectly expect and demand that term "bridge" accurately describe the logical connection between your container and your LAN.
Docker networks are entities independent of your LAN, they're isolated networks that primarily serve to connect containers amongst themselves.
A Docker 'bridge' network is not necessarily routed to LAN either so your suggestion of calling them "hostnatnetwork" is wrong. Auto-configuration of NAT between the internal bridge network and your LAN is just a convenience feature which you can disable, it's not an inherent property of bridge networks.
Disabling NAT for a specific brige network (com.docker.network.bridge.enable_ip_masquerade): https://docs.docker.com/engine/network/drivers/bridge/
Disabling auto-configuration of all firewall rules: https://docs.docker.com/engine/network/packet-filtering-fire...
> But hey, I'm just knowledge lacking guy without experience at all, just yesterday saw a computer a first time in my life, sure, sure.
No I didn't say that, I think you suffer from the curse of having a lot of previous experience in an adjacent area where you built a strong mental model of how things ought to work, but now you're trying to forcefully apply this same mental model onto Docker.
All of this networking terminology is consistent and applied correctly but for some reason it's not clicking with your previous knowledge and you're trying to fit a square peg through a round hole. Take a step back, investigate.
> So ten years late?
Don't shift the goalposts. You claimed it still doesn't exist.
The docker mental model isn’t crazy different. Design choices made it unnecessarily less compatible with existing mental models. This probably contributed to the feeling of it being revolutionary, but impeded its adoption with paying customers.
In my experience adoption was primarily driven by developers and sacrificing clarity would hurt adoption. This perfect familiarity was never achievable anyhow. Docker was a completely new paradigm in software development, similar to how modern cars aren't just horse carriages without the horse. It transformed everything from development, testing, deployment, updates.
Experienced sysadmins often tried to approach it with "VMs but with less overhead" mentality, which couldn't possibly work. Coworkers would ask me how they can install SSH daemons in containers to update packages and view logs, or they would refuse to adopt Dockerfiles, sometimes setting up the container manually and exporting the image. They would wonder how to install many different services in 1 container and handle crashes, etc. It was a huge shift.
> Design choices made it unnecessarily less compatible with existing mental models.
Again, I disagree. Whose mental model do you prioritize? How invested are you in making Docker work just like whatever elaborate system those enterprise admins used before?
Let's not forget that by creating new abstractions, you're penalizing users who already possess foundational knowledge of the primitives. If you do this then I'm probably going to get a whiff that you care more about enterprise sales than developer experience (duh) which is a huge red flag for me.
Sorry, but you do insist on naming 'docker' bridge a bridge because it's underlying tech is a bridge. Make up your mind.
> A Docker 'bridge' network driver creates a broadcast domain between containers attached to that network.
And noone absolutely ever cared about what it's a bridge down there. It could be using gronklew and maybe 20 people on the planet would care to learn what it is.
You are quite bent on it, but nobody cares how the containers talk between each other.
> Why do you expect it to join the broadcast domains of your containers and your LAN?
I expect a setting named 'bridge' in some $thing to actually implement a bridge.
Just like you pressing an AC button in your car expect a very specific thing to turn on/off and not 'Artifically flavoured windshield wipers served in a Container'.
Why do I want it is on me. Maybe I need it. Maybe I control my network and freely give out addresses to anything. Maybe I don't run on some cheap VPS somewere with only 1 IP I can't choose nor change. Bazillion of options. None matters because this is not about 'why do you want it'.
> And which LAN, exactly?
The path of a least automagik.
Only one ethernet interface? Then connect to that ethernet interface. Bitch in the logs what automagik was used and this can lead to the problems.
Many interfaces? Just shutdown (least pain for newbies) or start without attaching (harder to troubleshoot for newbies). Bitch in the logs in either case.
> Your misunderstanding seems to stem from the flawed assumption/expectation that every container is automatically attached to your LAN
'Your misunderstanding seems to stem what there are some people assume what they are driving in like c-a-a-r. When even 5y.o. knows it's the wheels what drives you around.'
> Docker networks are entities independent of your LAN, they're isolated networks that primarily serve to connect containers amongst themselves.
Yes, exactly. Don't call it 'bridge' ~20 years ago and we don't have this talk here.
> Auto-configuration of NAT between the internal bridge network and your LAN is just a convenience feature which you can disable, it's not an inherent property of bridge networks.
It's not even a property of a bridge network. For someone claming knowledge superiority this is a quite lame statement.
> links
Really.
> previous experience in an adjacent area where
Ah, yes, irrelevant 'adjacent area' of computer networks. I'm out of words.[0]
> All of this networking terminology is consistent and applied correctly
No. Go drive your wheels home.
> Don't shift the goalposts. You claimed it still doesn't exist.
I'm just mentioned RUN as an example. You decided what multiline is the goalpost.
And yes, if even the official Docker images doesn't use RUN heredocs then... there is something wrong with them. Like being implemented too late.
[0] but perfectly explains your previous 'flawed assumption'
Just like nobody ever cared that the container isn't bridged to their LAN in the first place - in fact the isolation is a feature.
But you should care, it's only the most common building block of network isolation for containers/VMs on Linux.
---
I'm not going to get into it further. I tried to explain nicely but you seem hell bent on complaining and not learning anything new. At this point the appropriate response is: RTFM, it's all in there, their docs are great.
If you don't have a clue about how things work under the hood and if you have no interest in learning anything, then stop complaining about imaginary technical inaccuracies.
If you decide to edit your tone, I'm happy to discuss more here re: filesystem transactionality tradeoffs, since that's something I've struggled with in both directions WRT containers.
I think you are the one who built an alternate layering system? On mobile, don't like to search rn.
If yes the basics are in the first comment- just not limited to the one RUN statement ofc. And if I do remember how the layers are made then making it transaction-like would be a great dedup saver eg for adding a static rarely changed artifacts - there could be essentially a ~one layer for how many you want images.
Implementation wouldn't be so difficult - you just stop committing until TRAN END; but the main is too provide a mental model for a not very experiencied dev how this supports his work and makes it more efficient on the storage and execution.
bullshit, you've been cunty right out of the gate since your first reply. I'm just surprised anyone else in the thread had as much patience as they've shown here.
you seem exactly like the type of person who is incapable of realizing they're a complete asshole and wonders why people choose to avoid them.
Now, considering you don't even know me: go in the bathroom, look atvthe mirror and repeat your comment.
Come back when the enlightment hit you.
lol What on god's green earth does this have to do with commercializing Docker? Do you really think better lighthouse scores on hub.docker.com was what was holding them back?
> what was holding them back?
Did you miss 'up to 30 secs' in the previous comment? It's not about lighthouse scores. It's the whole feeling of a hodge-podged project which is run by people who are - maybe - passionate but ultimately lacking in the basics.
The ultimate buyers of their product was the system operators and the system owners - not the developers per se. They failed hard everything that space. Having a dog slow the main content site didn't added anything positive.
Right, which is why bringing upva meaningless stat like how many assets their web site downloads feels like satire.
yes, and no. Probably both. Docker would not become such a default standard if it wasnt for all the open sourcing.
To me the arbitrarily complex docker networking makes perfect sense. Especially in a compose setup. I want my containers to be able to talk to each other, but I don't want them on my local network or even accessible (sometimes) from the local machine. The various internal networks offer isolation of containers from the rest of the network stack. If I have a rails app in a docker compose configuration with PG, Redis, Elasticsearch, etc, in a development environment, most of the time I don't want the service/accessory containers anywhere near anything other than the app's container. And if I want several compose stacks to work together, I just put them on the same named network. I apologize if I misunderstood your point.
Which can be achieved with normal routed networks with firewall on the “router” just fine, even on IPv4. Each container can have its own IP address, its own hostname and listen on a standard port, all reachable from containers and from the main OS of the workstation.
I think docker is not weird, it is very linear.
Docker has the merit to take a bunch of tools and to create an organized view of it.
I want to point you to Misterio https://github.com/daitangio/misterio which is a very thin layer on top of docker compose.
It simplify my homelab and works like a charm, and it is a waaaaay easier to use than k8s.
Thank you again, and let me know if you plan a trip in Milan :) for a meeting
People are underestimating now big of a tech shift it was back in the day.
I hope the plug is appropriate in this setting - apologies if not.
In retrospect, of course, it was earth-shattering for the company, despite a valiant effort. The entire expertise of deploying long lived Linux servers and carefully shepherding them through change management with Chef became a relic to most developers. Totally changed the way applications were deployed.
Was an exciting time!
For one, did you get rich beyond all comprehension and did you start a band with your wealth?
Second, do you still program ?
I was lucky enough to get in this industry when Docker was new. Sure beats trying to figure out why X happens on machine A and doesn’t on machine B.
I did not start a band, but I did build a nice house, help my family etc.
I still program everyday, working on my second startup, https://dagger.io (please forgive the plug). We have a very active discord if you want to come say hi.
I guess my follow up question is once you’re financially independent, what continues to motivate you?
Is it fun?
Do you feel like you’re creating tools that the industry needs.
I imagine if I ever get rich I’d work on music and small games.
Video games that you buy once and get to play forever, self host, etc. With a full open source commitment within 5 years or so. I’d probably create a game studio in a lower cost of living country though.
We actually use the same Discord server for community and private team communications. So we are literally there all the time.
Hit on a message's permalink (which is the "X hours ago" link), and in there you'll find the action to Favorite it.
When self-hosting Dagger, you can run it on Kubernetes. Beyond that, we don't use Kubernetes at all ourselves.
Shortly before this (the weekend after you secured YC funding, IIRC), I['m almost certain I] met you in downtown Oakland at Saagar & Tiffany's /r/bayarea meetup [0] – won't go into further details, other than I was one of their co-conspirators =P
My point of writing this is dualfold:
1) Thank you for sharing your design – I literally just installed my first Docker module (last week) and am floored at all the problems Docker might help me solve (I am not employed in tech)
2) My recollections of you, this decade+ later, was of a humble young man (we're the same age) that didn't know what else to do with his newfound techfame (and money) than keep'on keepin'on.
After watching your Docker Debut video, I'm fairly certain it WAS you: we chatted about dirtbikes (and just what the hell you were going to do now that you "had money" – then such a foreign concept to us both)... if this wasn't you it still seems to echo in your mannerisms/tact/approach. May your humbleness and cleverness prevail!
[0] It might have been at Gustafson's NYE party (I was the guy remorselessly conjuringbitches; "Volcano"); we had a mutual friend at MalwareBytes?
Docker completely changed my life. When I started using it in 2014, I really appreciated how well it solved certain problems I had for web development.
It spawned a near endless stream of contract work and video courses for about 10 years, along with being introduced to the Docker captain's program early on. Met so many great people and had a chance to visit a few countries around the world through Docker.
It's one of those pieces of tech that has followed me around for half my career and will likely continue until the end. It's the best community I've ever been a part of.
And yes the community has always been the best part of Docker...
What was your imagined use case when you first came up with it?
Did you think Docker as it is used in the industry right now is where you imagined it would be used?
Any use cases for it that the industry missed but you think would have made things even better?
> If WASM+WASI existed in 2008, we wouldn't have needed to created Docker. That's how important it is. Webassembly on the server is the future of computing. A standardized system interface was the missing link. Let's hope WASI is up to the task!
How are you feeling about WASI today?
I'm curious if when you were originally designing it, what tradeoffs you chose between, for example did you consider a non-daemonized design or was it daemonized from the beginning?
Having had some time now and also seeing how other people have riffed off of the idea and refined it, what would you have done differently? If you have a retrospective at some point already, I'd be interested to read it.
I have some accumulation of personal architectural guidelines that I built up from trial-and-error + reading others' experience and reflecting on how their design could've affected something I made. As a result, I really value those kinds of discussions about tradeoffs.
I know that containerization on Unix-like systems didn't begin with Docker, but I definitely think Docker was the first accessible interface for it.
I think app containerization is something that has so many benefits and it's the obvious correct approach for its use cases once you wrap your head around it. This was already understood at big tech companies pre-Docker (e.g. Borg, Tupperware, user app sandboxing on iOS and Android), but I think it really took something like docker to make it mainstream.
As far as I'm concerned, you can probably consider yourself like the Ken Thompson or Dennis Ritchie of your era in terms of the impacts of your contribution.
Java App Servers with their WAR file deployments across a cluster were the closest equivalent.
Docker was the enabler for alternatives.
So, not only did I not anticipate this kind of success, I did not even have a reference frame for what success might even look like. All I knew was, I had an itch that I had to scratch, and I had nothing better to do :)
I think the breakthrough with Docker was bundling the AUFS-based image layer format with a centralized container image sharing registry. This was revolutionary at the time. But another huge element of success was Solomon and others evangelizing the technology relentlessly at meetups and conferences. I distinctly remember attending a demo in 2012 where the crowd was very excited to see the Docker workflow that we now take for granted, in large part because Solomon was so good at presenting it. At the time, I was working at a cloud PaaS company where we developed a similar technology on top of LXC and BTRFS (but no image registry). Docker really made me think hard about what we were doing, although I didn't end up making any moves.
https://jpetazzo.github.io/2017/02/24/from-dotcloud-to-docke...
> the previous generation of the technology used by dotCloud [...], which was using LXC with AUFS
One small note, the earliest versions (2007-2011) were based on vserver then openvz, which predated lxc. Back then you had to patch the kernel to get container primitives. And since virtualization also required patches (eg. Xen), we had to carefully combine both sets of patches, which was poorly supported because nobody else was crazy enough to stack 2 kinds of virtualization!
https://news.ycombinator.com/item?id=2032821
Then it pivoted to docker:
When Docker came out it solved so many issues we were having. Thank you for scratching that itch.
I didnt get it at that time haha.
One design principle that was very important to me, was portability and avoiding fragmentation. I wanted every image name to have the same meaning in every engine, so that when writing a Dockerfile, you could have confidence that it would actually behave the same on every docker installation. In this we disagreed with other platforms (like Red Hat) who sought to "embrace and extend" Docker by changing the meaning of short names. We always fought this to avoid fragmentation of the platform. This did not make sense from Red Hat's perspective, since they were the platform - who cared about fragmenting Docker? That led to some negativity which is probably what you're remembering.
At the same time early Docker users wanted the ability to host their own images without being forced to use our central registry. Using Go's system solved both problems at once.
I personally never use the short names and have really come to like your solution. I host my own registry and I can glance at a build or compose file and immediately know if I’m depending on any external resources that I shouldn’t be.
I originally disliked it, but it’s been my favorite namespace solution for a long time now.
None of these things can be transposed today, so I guess I can't answer...
For what it's worth, my current project (dagger) is written in Go.
Another explicit goal was to facilitate contribution. We thought Go syntax was "vanilla" enough to attract a broader set of contributors than a more niche, opinionated language like Erlang, Haskell, Clojure etc. I think that also worked out well - Docker was known for attracting many contributors, many of them making their very first open source contributions. We even ran special meetups to help people become contributors, that was fun.
Thank you.
Actually there are some longer unedited versions I might release.
Prior to the creation of Docker, did you have experience with other containerization technologies like Solaris Zones and FreeBSD Jails?
Did you at some point, either prior to or after making Docker for Linux, consider building something like Docker on top of FreeBSD Jails?
As a user of both Linux and FreeBSD, running Docker containers and Jails on each of them respectively, it would be interesting to see what FreeBSD Jails could be with something like Docker built on top of it while also taking advantage of other features on FreeBSD like fully using ZFS snapshots, ZFS send/recv, ZFS clone, vnet, and so on. Such that spinning up a container would under the hood receive ZFS snapshots from the “Docker registry” equivalent server, and it might clone the snapshot locally before starting up a container instance so that multiple container instances would be using the same locally available ZFS snapshot that was received once from the “Docker registry” equivalent.
(And as a result that, with ansible, continues to be my preferred way to deploy while the rest of the world passed me by…)
However Moby was a poor choice for a skunkworks project, it involved mostly communications and project management, which requires consistency and scale. Overall it was poorly executed because I failed to build enough support internally ("Solomon's at it again, let him do his thing"). Here I am trying to explain it on Twitter after the keynote, using a picture of a hand-drawn diagram, because nobody in marketing or product was assigned to help. https://x.com/solomonstre/status/855918630915133440
I think the goal of Moby was fundamentally correct: we were trying to replicate the Red Hat model, with well-scoped upstream components (linux -> runc, containerd..) integrated into a commercial product (Docker -> RHEL), with a faster-moving community project in between (Fedora -> Moby).
This was a way for us to clarify that Docker was a product, with a community of users, and Moby was an open source project, with a community of contributors. This clarity was very much needed, because different communities were projecting very different expectations on the brand "Docker", and these expectations conflicted with each other.
In a way, Moby aspired to be what CNCF ended up becoming - the "big tent" where the broader community meets to hammer out the general shape of the container stack. It seems obvious now that a single company can't be the sole authority over such a vast scope. But in the first years of Docker, we really did have that level of influence, because we literally invented the market, and brought the community together in meetups and an ever-growing Dockercon. It's only when Google and Red Hat pushed Kubernetes and CNCF, that our influence over the stack started to wane. Maybe it was for the better, I don't know if we would have been up to the task as designers and engineers. But at least there would have been a consistent design, with a Linus Torvalds figure willing and able to say "no" to stupid and redundant features. For a while I played that role - but then I was replaced by SIGs and committees.
In recent years I have shifted over to Podman, primarily because it defaults to rootless without a daemon.
Is that something you considered for docker early on , and if so why did you decide on running as root?
I also feel lucky that people are still using my work, that it endures without me, and that it generates (mostly) positive reactions. There was a time where Docker had a lot of haters, which was hard on me. But with time I've noticed that the negativity gets mostly washed away, and what remains is positive interactions like the ones in this whole thread. So now Docker is this cool experience I share with lots of people around the world, and when we meet we get to talk about this shared interest. I love it.
I've struggled for years wanting something that wasn't K3S or K8S. Something good for small cluster management that had a lower level of entry, that I'd feel better handing off to other teams.
Docker Swarm seemed to fight the puzzle, but falls short based on things that needed to be fixed or finalized, that just never happened.
Any reason that whole pathway got abandoned? Other than just "Google uses Kubes so just everyone can use it"?
I’ve been following dagger and it’s been really interesting to see the evolution of the design, and new set of abstractions. There’s also nix which has seen popularity, with their approach of building layered oci containers.
The sole idea of containerising an application, its utils and dependencies all into one container is a real big deal in early 2010s. The product has been so visionary that it has been re-pivoted as secure sandboxes which is most needed right now. Kudos!
Why doesn't docker respect unix filesystem permissions? I use docker on a shared server, i can delete docker images of other users. This is bonkers.
Is it a defect of a particular docker setup (following standard instructions on ubuntu), or it's an intrinsic feature of docker itself?
Same reason a Postgres root can delete tables of other users.
It could, but it would be a shim on top of Docker to respect them.
Docker is a service daemon running as root, and the images of other users are just entries created by the other users in its registry, not server files that have permissions of each user.
When you're creating a new docker image, you just send a command to that daemon process - you're not passing your user account credentials to create. As far as docker is concerned, it's just one more image it knows, not an image belonging to you specifically.
Why choose to break user boundaries? Why can't docker images be files in the possession of each user?
In the shared daemon model, there are no user boundaries. Even if the files belonged to each user permissions-wise, the central daemon running as root would be able to edit all.
Q: Why not have container builds and runs be invoking-user-specific by default? A: As the adjacent commenter pointed out, this would be an overlay on fundamentally rootful behavior. It would also remove a lot of "works on my machine, works anywhere", since different user accounts running/building containers could be restricted in different ways on different computers, so my "docker build" and your "docker build" might both work, but do different things or fail in different ways. Note that this isn't the same as saying "rootful dockerd is good"; it's not (usually)! That's why rootless docker (https://docs.docker.com/engine/security/rootless/) is recommended in many environments. But even in rootless, the run-user of the container and build are still uniform with the rootful behavior (albeit they require more participation from the daemon-owning user account WRT UID mapping/user namespaces/privileged actions), which I think is a good thing. Rootless docker, last I used it, behaved sensibly re: vs. user container images (kept per-user) and globally-cached layers (removable by anyone), but that may have been a specific configuration where I was using it.
Q: Why aren't docker images user-browsable files? A: I can't say for sure; I didn't build Docker, but I hear the guy who did is in the neighborhood :). I suspect it's a combination of caching (since build stanzas/Dockerfile lines are intended to be proxies for the content address of a layer, there's nothing to gain by making layer caches per-user), implementation convenience, and an influence from the Golang platform wherein (after the age of vendoring wound down) the developer tooling has many convenience layers that de-emphasize user visibility of build/download artifacts a la "go run". Docker goes further, though. And yes, I know that you can get at OCI images/layers as files. But most people don't.
All of the above applies to Linux, ymmv on other OSes
The folks at infracoders / DevOps meetups would think we were a bit "out there", then what do you know - 2013 rolls around and we quickly started to shift to Docker (too early some might say), but not long after shifting from LXC to Docker it seemed many others finally started to come round to containerisation.
Fast forward to 2026 and I've recently done some work with a client who is only just "getting into containers" (a Windows shop).
Thanks for your early work to bring better containerisation to Linux Solomon. It's funny to think we're 13 years from Dockers release. Time flies.
Went from the good old days of vagrant (xen/kvm) to lxc/lxd to docker, and docker truly clicked all the way from development to production.
But honestly, thanks to Docker hub even more. The CLI is only one part of the puzzle, the worldwide registry is an immense undertaking.
The most successful project that we worked on together was "project Piñata" which later became Docker for Mac. It turns out bundling a Linux VM in a native Mac app, and integrating it into the host filesystem, networking stack etc requires lots of magic..
Now, most of the Unikernel team were very active OCaml developers, and created MirageOS among other ocaml projects. While working on Piñata, they simply reached for the tools they were most familiar with.
When acquiring our company, Solomon took us to a remote farm in France for a week for an offsite, fed us fantastic food and wine, and the first prototype of that Docker for Mac VM was working by the end of the week! It took a few months to hack together the shell. There's a video of Solomon and the pinãta launch party on my blog ;-) https://anil.recoil.org/notes/cacm-docker-cover#getting-invo...
There was a whole other slice of work we did for project Piñata too in the form of datakit (https://github.com/moby/datakit) that was well ahead of its time. I was looking at this archived code again just last week while thinking about agentic git workflows!
How did I not know about this video until today!
Hope you're doing well.
Am firing up Dagger to give it a try on our geospatial workflows for the first time just now; it’s got the same attention to CLI detail as Docker 1.0 did :-)
What are you up to these days?
Hope things are going well with you at Dagger(?)!
My memory from that era when Docker was getting big was our biggest user completely ignored us. Which I thought was quite odd at the time.
I did speak to Greg several times.
I think over the years there was natural overlap, people who contributed to Docker would also be kernel contributors. Especially when we spun out runc, containerd, which created a more vendor-neutral space for maintainers to focus on the bottom of the userland stack with minimum drama.
To the extent that Red Hat employees overlap with kernel folks, that made it more difficult to collaborate since Red Hat was overtly aggressive towards Docker, and generally made our engineers feel unwelcome on "Red Hat turf". I discovered that they had devolved into a toxic company with a facade of benevolence. This made me sad because Red Hat was an inspiration to me. One of those "don't meet your heroes" situations.
Not sure what you meant by the "ignoring" part.
We had public discussions on the Linux Kernel mailing list and later on the containers list.
It was a collaborative effort from vserver, openvz, IBM, and Linux Networx, and google. I think those were all the original groups, my apologies if I have forgotten someone.
After Docker made a splash I occasionally asked other developers if they had any contacts at Docker. To the best of my knowledge we never received a bug report, or a feature request. No one from Docker ever showed up at any of our meetings.
I know at one point I wanted to let someone know that Docker they were holding the pieces wrong when it came to security.
Eventually I think one of the OpenVZ guys wound up working for Docker for a time. But that was quite late in the timeline.
I was passing through RedHat about the time of the spat you mention. My impression at the time was that Docker never worked well with anyone, and after some frustrations trying to cooperate the RedHat userspace folks decided it was easier to get a real standard without Docker.
At that point I had gotten the unprivileged user namespace support into RedHat's kernel and changed a lot of minds about it's utility.
I don't remember Docker ever picking up unprivileged user namespace support and as a result was a security disaster waiting to happen.
It felt to me like Docker treated the userspace API for containers like most folks treat the POSIX API. Fixed in stone. In fact there was a lot of wiggle room, and opportunity to shape things for anyone who was willing to dive deep into the technical details.
Red Hat was frustrated with us because they were used to calling the shots. They couldn't fathom that we would refuse a pull request from them. Well guess what, every project is entitled to saying no. And Red Hat's contributions were just overall not good, or they didn't bother to consult with the maintainers on our design principles - like independence from the underlying OS distro.
You're reminding me why working with that company was such a pain. Always with the fucking superiority complex and passive aggressive drama.
As for a "security disaster waiting to happen". My view was, and remains, that the only isolation you can trust is the hypervisor. Kernel level isolation is not strong enough, and unprivileged user namespaces never actually mattered in cloud architectures. Your work on that feature was just security theater and ultimately useless, so spare me the lecture.
I do think Docker embraced user namespaces after my time but I couldn't care less.
Docker is probably the highest-profile software written in Go. Are you happy with that choice? Would you do it in Rust if it was available at the time, or Zug?
When it comes to the author calling Docker weird, after looking at some of their other postings, something about glass houses comes to mind.
Was it all for the `docker.sock`?
And multi stage builds are just a directed graph short hand for having separate intermediate dockerfiles. There’s nothing special about them either.
If I had to pick one thing that is tricky for someone new to docker to understand, it’s how the filesystem state is cached using the previous state, the env, and the raw command text.
Docker is much more than memorising a handful of Dockerfile directives.
Docker syntax is one of those things that just immediately falls out of my head when I close the editor. I don't care about it at all.
Even better: there are many, many tools that build OCI images without using the Docker syntax. I haven't hand-written a Dockerfile in at least six years.
LLMs have not loved the needle here in my sphere, it was already bouncing off of the zero on the gauge.
edit: this isn't to say the syntax is good or bad (though there are several questionable parts of it) but extremely simple, and concise enough that you can just look up literally any command with great ease. It's surely a large part of its success, for better or for worse.
When I was learning Docker I can't tell you how many people would describe it to me by analogy to a standardized shipping container, and start going off about shipping container dimensions and supersized cargo ships and trucks and railcars... and finish by smiling beatifically, like they had just explained the whole thing in a masterstroke. Let's... uh... not do that. :-D
In a problem set, the student might learn a bit about dockerfiles or docker-compose.yml... but only, I think, so they can try building and running a container of their own!
Funny how little has changed except the names, I guess.
You're a genius well done making containerization actually happen.
Am I on the right track?
Once I realized how difficult it is to write complex code that actually satisfies the borrow checker, I was perfectly happy with writing somewhat slower code in Go or Python.
Anyway, I clarified on a sibling comment the reasoning behind my question.
So they would probably never rewrite from Python into C or C++, because not cool, too hard kind of motivation, otherwise they would not have picked Go.
So that begs the question, if the obession as you call it, was already a thing back then, would Rust have been the lucky candidate?
As for endorsed by Google, see Dart and Flutter, Android Things, Fuchsia.
Now everything combined, plus Docker and Kubernetes, yes it was definitely a factor.
It's a language with its pros and cons, I like the simplicity, it's a good choice for services that just expose an API/GRPC/etc... and the performances are not that bad.
This "but rust is faster" obsession often comes from people that don't even know what they are talking about or are even able to consider if thinking about performance make sense for a specific use cases. Sometimes, or at least it did before LLMs, having something simple to modify was more important that chasing supposedly higher performance because the rust people keep blabbering about it.
> would Rust have been the lucky candidate?
Probably not, considering that the author give me a "simple solutions are best" vibe.
Python and Go are both memory-managed languages. That is perhaps the hardest part of programming (outside of getting the code to do what is intended).
Go and Rust are both compiled, but Rust requires the developer to figure out all of the memory management before compilation, which slows down development to a crawl.
Almost no company will rationally choose Rust over Go if they know how the development speed tradeoff looks like.
I would have chosen C++, but given that isn't the new darling any longer as in the 1990's, that begs the question of the new kid in town that everyone is now rewriting everything into.