Containers have been a buzzword for a few years now, and somehow Platform-as-a-Service (Paas) is connected, but how do you get started using PaaS for your own projects? Let's dive in.
If you’ve spent any time in the last year looking at software development jobs or blog posts related to tech, you’ve probably noticed how frequently the term “container” gets thrown around. For an up-and-coming developer, the idea of containers might seem confusing, and even more daunting is using a container in practice. There’s all sorts of complicated jargon that surrounds the idea of containers, especially when you dive in further and start throwing in terms like “Platform as a Service (PaaS)”. Luckily, these services can play a big role in making the development process less chaotic once you get a feeling for how they work.
The recent popularity of technologies like Docker and Kubernetes has helped “container” become a buzzword for good reasons. Containers remove a lot of the headaches involved in the development process and many developers find them to be resource-efficient time savers that play a huge role in eliminating the need for complicated technical overhead.
In order to get a better idea of what a container is in the digital world, it can be helpful to picture a physical container and think about the purpose that it serves. With physical containers, a person can essentially take a bunch of miscellaneous items and pack them into a neat, single object that moves from place-to-place with ease.
Just like a shipping container, the ship (or ‘platform’) doesn’t really need to worry about the contents of each container. It can move them, track them, and separate them as if each one was identical.
Digital containers work in a similar fashion. You can take the code, dependencies, configurations, and other aspects of an application and package them all into a single contained object.
Critically, containers are not ‘persistent,’ they don’t have any custom pre-installed software beyond a standardized package. In Heroku, we call them "stacks" and you have 3 or so to choose from. For example, here's what's in our latest stack. Any extra code you require (see ‘dependencies’ a bit further on in this article) needs to be explicitly listed by you, and will get installed when the container is ‘spun up’ with your application code. This lack of persistence actually works with our metaphor: once we’re done with a shipping container, we expect it to be largely empty. We might expect a few general-purpose things to be present like tie-downs and rails for a car, these are the ‘standard stack’ components.
Luxury cars or canned tuna, the same container can carry them both
But we wouldn’t go to ship our precious Ming vase in a container and show up expecting it to be pre-filled foam cut in the shape of the outside of our Ming Vase.
This becomes incredibly helpful to keep in mind when you get to the point of accounting for things like infrastructure and security.
Before diving too deep into the terminology surrounding containers, it’s important to make a note about the distinction between “containers” and “dynos” -- there is none. Dyno is the Heroku-specific term for container. You may see “dyno” and “container” used interchangeably in relation to Heroku, but container is the generic term. Heroku created the term “dyno” long before the term
container became a standard.
There are other services and even self-hosted tools to run containers, but I don’t use them for reasons I’ll get into in the following points.
A Platform as a Service or PaaS can simply be defined as a platform that allows users to create, run, and manage applications without subjecting users to the headaches involved in building and managing infrastructure. Put simply, the user manages the application while the PaaS manages things like storage, runtimes,networking, security, and servers. Popular PaaS options include Heroku, AWS Elastic Beanstalk, Google App Engine, and Microsoft Azure. All of these provide tools to let you create, control, and remove containers, generally referred to as ‘orchestration.’
Can you use containers and run all the orchestration around containers yourself, without a Platform doing it for you? You absolutely can. Tools like Kubernetes exist for this purpose, but the past few years have revealed an ugly truth about self-hosted containers: they are pretty tough to maintain.
The vision of containers is that the system is easy to look at in modules. We imagine a foreman saying ‘load up some more containers over here! Those over there aren’t being used let’s empty them to free up resources.’
Kelsey Hightower is an evangelist who gave the keynote at KubeCon this year. He regularly talks about how platforms are much easier to use than Kubernetes.
If you’re reading this, you’re a developer. I’m not saying that Kubernetes is too hard for you to use. I am saying that orchestrating your containers on a platform that you manage yourself isn’t something you can master in a weekend-- and after you’ve done the work of learning, maintenance of Kubernetes is at least a part-time job. Using a tool like Heroku gives you the control you need for your business needs without the arbitrary heavy lifting of running your own container orchestration tool.
Heroku acts as a great example of how the terminology surrounding PaaS and containers can make the concepts seem a lot more complicated than they actually are. A lot of newer developers will build their second or third web apps on Heroku without realizing that it’s giving them practice using PaaS and container technologies.
Heroku is aptly described as a “platform as a service based on a managed container system”. When a user pushes their application to it, the applications get containerized and placed within the broader platform that manages things like hosting, infrastructure, and security. Put simply, the user is pushing what exists inside of the container and the platform is doing the rest of the heavy lifting.
I feel like I understand my application’s ‘environment’ when I am running my own server: my environment is everything except the application code, all the stuff and things I have installed on my server, right? How can I be ‘managing my environment’ on a PaaS system, where I don’t install software separately? The answer is: the environment in this example is everything that changes when I move my application from development, to test, to staging, and to production. The location of databases, and any specific routing settings, along with anything else that changes on the way to production, needs to be clearly defined. If you’re a student of 12-Factor app design, you know this should be clearly defined and controllable. Heroku makes this easy with an environment tool for each of your dynos!
We often talk about “managing dependencies”, but what are dependencies when we have a containerized application on a platform-as-a-service? Dependencies can broadly be defined as pieces of software that an application relies on to run correctly.
Cool terms like ‘dependency injection’ are really just ‘adding some code to your program that you copied from somewhere else’
These dependencies are declared in different ways depending on the programming language being used. The Gemfile for Bundler handles dependencies for Ruby apps, a package.json for npm handles dependencies for Node.js apps, and so on. Using tools like this means that you will explicitly declare your dependencies instead of just grabbing blobs of code and adding them to your application. It also means you can automatically get updates and track where your code comes from.
Dependencies are built by the platform-as-a-service based on what is in the source code and dependency file. You can read more about this here.
As discussed previously, applications on Heroku are held in containers (otherwise known as “dynos”). Routers handle inbound requests and point them towards these containers. More specifically, the router ensures that an incoming web request is delivered to (one of possibly many) containers running your web application. The router also ensures that traffic is evenly distributed across containers to avoid overloading one while another sits empty. How does this distribution happen? The short answer is a random-selection algorithm, which is touched upon here.
Scaling is important to consider once you move into the realm of larger applications. The term “scaling” essentially refers to the practice of configuring an application in a way that allows it to be stable and usable as the scope and user base grow. Without scaling, an abundance of traffic can overload a contained application and cause all sorts of issues. Scaling happens in one of two ways on Heroku:
- Vertical scaling, making your dyno larger and more capable of handling requests quickly
- Horizontal scaling, spinning up multiple copies of your dynos, so that each has a smaller fraction of the total requests
Heroku has options for both manual and automatic application scaling. You can read more about this process here.
The great advantage of having Heroku handle your routing, and your code running in containers that have all their software needs explicitly listed as dependencies, is that you can create more containers and scale horizontally seamlessly. There should be no human attention required to from one container to two to 1,000. Costs should always be optimized, so we also want automation to scale down: removing active containers when there’s no need for them. Heroku also makes vertical scaling much simpler than it would be with a traditional virtual machine.
In the ancient days of yore, scaling was a process of literally buying more servers and hooking them up, but even after more of the process was virtualized, there wasn't an easy path to add a second server, largely because of things like routing, orchestration, and the dependencies mentioned above. But with Heroku containers (dynos), it ispossible to guarantee that starting up a new dyno will create an exact replica of what you already have. With Heroku to handle the routing of the request to your two new dynos, scaling can be as easy as dragging a slider.
While this article somewhat spoke ill of running your own stack of containers, I can recommend two books if you’re interested in that direction, check out Cody Bumgardner’s OpenStack in Action or Kelsey Hightower’s Learn Kubernetes the Hard Way.