Why we have containers

or, How a young program grew a little bit closer to software.

One day a shiny new app was completed. All the code was just right, and it was ready to go out in the world and be useful!

The little app burst onto the street and shouted, “I’m ready to run!”

An ant looked up at it and asked, “Oh, where do you run?”

The app looked bashful. “Um, um, on a computer! I need a computer to run on!”

It went to the store and bought a shiny new computer, then plugged it in. “Run me!” said the app to the computer.

The computer blinked lazily and said, “What?”

“Run me!” said the app.

“Whaaat?” said the computer.

“Oh, why won’t this computer run me?” cried the app to the world.

A helpful beetle walked up and asked, “Which operating system does your computer have?”

The app looked startled. “Oh, the computer needs an operating system. Of course!”

And it ran off to the store and bought an operating system. It picked the one called Buster; it looked safe and full-featured. The app fed the operating system to the computer, and the computer smiled. “What would you like me to run?”

The app shouted, “Me! Me! Run me!”

The computer looked at the app strangely and said, “What are you? You don’t look like an executable.”

The app said, “I’m a program! I’m made of beautiful elegant Java code!”

The computer said, “Java? Command not found.”

The app said, “Oh, of course, the computer needs Java!”

And it ran off to the store and bought a nice, familiar Java runtime, nothing too new. It fed the runtime to the computer.

The app shouted, “Now run me!”

And the computer did!

“Look at me, world! I’m running!” and the app ran around and around. 

But then the app grew lonely. “Where are all the users?”

It spied a nearby grasshopper. “Hey grasshopper,” said the app, “Why don’t you call me? I’m full of perfectly functioning endpoints.”

The grasshopper looked at the app strangely. “How would I access you? Are you even on the network?”

The app looked sheepish. “Oh, the network. Right. I have to hook up this computer to the network.”

The app ran to the store for a cable, plugged it into a network port in the nearest access point, and tried to plug it into the computer. But it wouldn’t fit in any of the computer’s ports!

“Computer, why can’t I plug you into the network?”

The computer answered, “Help not found. Perhaps I could answer that question if I were connected to a network.”

The app sat down and cried.

A sympathetic lizard happened by. “Dude, you OK?”

The app breathed in deeply and sighed, “I want to connect this computer to the network but there’s no place to plug in the network cable!”

The lizard walked around the computer and took a look at the back. “Looks like you might need to install a network card.”

The app looked up, “The computer and the operating system aren’t enough to talk to the network?”

The lizard replied, “Networking is a whole ‘nother problem. Here, I’ll help you install a card.”

And the lizard and the app went to the store together, and came back with an ethernet card. While the app looked on in wonder, the lizard sliced open the computer, inserted the ethernet card, and sewed the computer back up, this time with a nice ethernet port on the back. 

The app, victorious, plugged in the network cable. “Computer! Wake up! You have network now!”

The computer looked at the app, “Network? I don’t see any network.”

The lizard rolled its eyes at the computer. “Through the ethernet card I just installed.”

The computer stared blankly “Ethernet card?”

The lizard walked up to the computer and whispered something the app couldn’t understand.

a lizard licks a computer. a piece of paper looks on, surprised.

The computer’s eyes widened. “Oh you mean THAT ethernet card!” It proudly opened its default browser.

“Thank you, lizard!” the app leaped with joy.

“Best of luck, kid,” the lizard replied as it went on its way.

“Computer, please open port 3000 to the world!” the app requested. “And run me! Because I listen on that port.”

The computer cooperated this time.

“And give me our IP address!” (That’s not literally what the app said, but it gave the incantation that has that effect.)

The computer communicated over the network, and supplied the address.

The app ran around to its friends, telling them its IP address and port. The other apps were able to connect! The app was useful!

Until it went down randomly, of course. But that’s a different story.

Except the days when it was overwhelmed by too many requests. But that’s a different story too.

Months later, the whole computer was brought down by an exploited vulnerability, and that’s a different story entirely.

The app was so proud of its beautiful, useful code that it published the code to the internet for everyone to see. Hooray!

In fact, the app was SO useful that others wanted to run it. There were thousands of downloads, and a few successful runs reported.

One day an armadillo waddled up and said, “Hey, I’m trying to run your code, but it doesn’t work on my computer.”

The app replied, “Well it runs just fine on this computer here!” and pointed to the computer, whirring away.

The armadillo walked around the computer. “What operating system does it run?”

“Buster,” replied the app.

“Oh. I’m running Alpine, maybe that’s the difference.” The armadillo walked away.

Soon others came by, some running different versions of Java, others who didn’t have the right directory structure, and the app became annoyed with all the questions.

“Look,” said the app. “Why can’t you all run me in Buster, on my favorite Java version, in the directory I’m used to, on the port I like?”

A hedgehog replied gruffly, “Because my other apps run in a newer Java, on a slimmer OS. You don’t get the computer to yourself!”

The chipmunk next to him added, “You don’t get to dictate my filesystem organization!”

The app was discouraged. “My Java code is not enough to make software that runs! I also need an operating system, a runtime, a filesystem, and I want them just so. Why can’t I put that in code too?”

A friendly firefly alighted and remarked, “This is why we have containers.

Containers let us write code (a Dockerfile) to describe the computer an app needs to run on. Choose an operating system, install any runtimes and libraries needed, and populate the file system. This reduces many of the app’s expectations to one: a container runtime.

The app jumped up and down excitedly. “I want to define a container!”

And with the firefly’s help, it did. It included the Dockerfile in its source code, and other developers used it. The app got fewer complaints, because everyone could build a suitable container.

The armadillo didn’t want to run a container, but she could still look at the Dockerfile to see all the app’s expectations.

The firefly and the app became good friends.

Much later, one sad day the app’s computer shut off and wouldn’t turn on again. The app complained to the firefly about needing to buy a new computer and set everything up again.

“You run in a container now, right?” reminded the firefly.

The app looked proud. “Yes, I can.”

“I run my apps in a container runtime. Would you like to run in it too?” the firefly offered.

The app gasped, “Really? You’d share your runtime with me?”

The firefly replied, “I trust you. You can run alongside these other apps, which work on different operating systems, and none of them will even notice!”

And that’s what they did.

The app and the firefly happily moved on to solve new problems.