More and more teams are adopting Docker at almost every step of the app lifecycle with its promises to make the lives of both developers and sysadmins much easier.
That being said, there is one part of that lifecycle that hasn't always had a clear story: deploying your containers to production. This is where Tutum, now known as Docker Cloud, fits in.
What Is Tutum?
In the past, a lot of Docker users have resorted to patching together brittle custom scripts to deploy their apps to production. Tutum removes the need for this with their "Orchestration-as-a-Service."
While an IaaS provider like AWS or Digital Ocean provides you with the raw infrastructure you need to run your application, you are still left with the responsibility of managing all of that infrastructure.
A PaaS provider, like Heroku, simplifies that for you by abstracting away the underlying infrastructure and letting you simply push code. But this has the unwanted side effect of boxing you in to their way of doing things.
The basic tradeoff is one of simplicity versus flexibility. Tutum attempts to give you the best of both worlds. As they put it, "Tutum combines the strengths of IaaS and PaaS, with none of the downside."
With Tutum, you bring your own cloud provider, and they handle the rest. There is currently native support for Microsoft Azure, Digital Ocean, AWS, and SoftLayer. In addition, with their "Bring Your Own Node" feature, there is support for virtually any Linux host.
Once you've chosen your provider, Tutum lets you build, deploy, and manage your applications however you'd like. There is a fully featured dashboard, a CLI, and even a RESTful API if you'd prefer that route.
Why Should I Try It?
If you have ever used an IaaS and were frustrated with the complexity or if you have ever used a PaaS and were frustrated with the inflexibility, Tutum could be the answer. Tutum separates the orchestration layer from the infrastructure layer. This greatly simplifies things and has the added benefit of preventing lock-in.
Running your app on AWS and looking to switch over to Digital Ocean? You are in for a headache. However, if you use Tutum to orchestrate things, making that switch is a just a few clicks and a few minutes away.
Docker isn't going anywhere any time soon. Now, with Docker's acquisition of Tutum and the subsequent rebranding to Docker Cloud, there is a clear story for how to extend your Docker usage into the production part of the app lifecycle.
Due to the acquisition and rebranding, the documentation is in a state of flux and will likely see some minor changes in the near future.
Enough of the sales pitch. Let's dig in. In this section, we'll go over some of the basic building blocks of Docker Cloud as well as cover the main concepts and terminology you need to be familiar with.
Providers
A provider is the underlying IaaS that will be responsible for the raw infrastructure needed to run your application (e.g., AWS or Digital Ocean). If you'd rather provide your own infrastructure, Docker Cloud allows you to use any Linux host connected to the internet by simply installing their cloud agent.
Nodes
A node is a Linux host furnished by your chosen provider (e.g., EC2 instances on AWS, droplets on Digital Ocean). Nodes are arranged into node clusters (which can consist of a single node). A cluster is simply a collection of nodes of the same type from the same provider. Clusters are what allow you to scale your app by simply dragging a slider to add more nodes.
Services
A service is a group of containers from the same image. These enable you to scale your application across nodes. You can also link together different services (e.g., a load balancer service to an app service) across different nodes and different providers.
Stacks
A stack allows you to combine multiple services into a logical application. Stacks are specified with a stack file. This is just a YAML-formatted document that defines what services to use and specifies other configuration such as environment variables, deployment tags, and the number of containers to run.
Now that we have the basic terminology down, let's go ahead and put it all together to deploy an example application.
A Sample Application with Docker Cloud
Since the focus of this post is on Docker Cloud, our example application will be as simple as possible. We want to demonstrate how to use Docker Cloud, not how to build an application.
For that reason, we will just be working with a "Hello World" Golang application. Similarly, we will be using Digital Ocean in this example, but the process is much the same for other providers and other languages.
Setup
First, you will need to sign up if you haven't already. Once you are logged in, we will use the dashboard to do some initial setup.
Go ahead and "add a cloud provider." In this example, we will use Digital Ocean since they make the process of linking an account as easy as clicking a button.
Click "Link Account," and you will be taken to Digital Ocean to authorize the use of your account.
Once you are back to Docker Cloud, head on back to the welcome screen.
From the welcome screen, click "Deploy your first node."
Enter a name for your node cluster and make sure your provider (Digital Ocean in this case) is selected.
Make any other changes you want or just leave the rest of the options as they are.
Finally, click "Launch Node Cluster." This will take a few minutes to get up and running.
Once your cluster is up and running, we can switch over to the command line. First, we will need to install the CLI. If you are on a Mac, you'll need Homebrew:
brew install docker-cloud
If you are on Linux or Windows:
pip install docker-cloud
Before we can really get started, we'll need to login with our Docker ID:
docker login
Great! Now that we have the basic setup out of the way, we can introduce our actual application.
Code
Go ahead and create a directory (in this case tutum-go
). In the new directory, we will need just three files. The first, main.go
, is the entirety of our Golang app:
package main import ( "io" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello, World!") } func main() { http.HandleFunc("/", hello) http.ListenAndServe(":80", nil) }
This is all pretty straightforward. Our app simply listens on port 80 and responds with the text "Hello, World!"
It's not groundbreaking, but it's perfect for demonstrating the power of Docker Cloud without distracting from the task at hand.
Next, we need a basic Dockerfile. A Dockerfile is just a text file that contains the instructions that need to be followed in order to get the desired image. For a more in depth explanation, check out Tim Butler's post on the topic.
For our purposes, something like this will do just fine:
FROM golang MAINTAINER Jason Kriss <jasonkriss@gmail.com> ADD . /go/src/github.com/jasonkriss/tutum-go RUN go install github.com/jasonkriss/tutum-go CMD /go/bin/tutum-go EXPOSE 80
Lastly, we add our docker-compose.yml
:
web: build: . ports: - "80"
That's all the code we need for our app. The rest of this section will deal with deploying this app to Docker Cloud.
Deployment
Back at the command line, let's build a new image from our source code:
docker build -t tutum-go .
Now let's tag that new image:
docker tag tutum-go jasonkriss/tutum-go
And finally, push it to the registry:
docker push jasonkriss/tutum-go
Now we just need to deploy the app as a Tutum Service:
docker-cloud service run -p 80 --name web jasonkriss/tutum-go
This command creates the service using the image we just created, gives it the name "web"
, and runs it, exposing port 80 in the container. It may take a few minutes to get up and running, but we can check on the status with the following command:
docker-cloud container ps --no-trunc --service web
Once the STATUS
is Running
, we can grab the URL under PORTS
. Open up your browser and paste in the URL. You should see "Hello, World!"
. We have deployed our first service!
Where Do We Go From Here?
So far, we have seen how to take a simple Golang application and deploy it as a Docker Cloud service running on a cluster of nodes furnished by the cloud provider of your choice.
This is super powerful. Progressing to more complicated apps and infrastructure is relatively easy to do with Docker Cloud. Let's cover a few of the next steps you might want to take for a more serious application.
Scaling up the service
We are currently running a single container. To scale to more containers, it's as easy as:
docker-cloud service scale web 2
Load balancing
If you followed the previous step and scaled your app to more containers, you are probably going to want some way to distribute requests to all of those containers. The way to do this is to deploy a specific load balancer service and link it to your existing service. More information is available here.
Using a database
Most interesting applications are going to need some sort of way to persist data. Fortunately, Docker Cloud offers support for most popular data stores through its Jumpstart library. Ultimately, this will require you to create another service for your data store and then link that into your existing service. Check here for further details.
Creating a stack
As we have seen, Docker Cloud makes getting up and running with a web app, load balancer, and database super easy. However, we still needed to define multiple services one-by-one.
Luckily, there is a way to automate this. Stacks let you specify a number of services that are linked and deploy them together. The documentation provides more information on how to do this.
Wrapping up
With the acquisition by Docker, Tutum is here to stay. This is great news both for people already using Docker, and those new to the entire platform.
It answers the question, "How do I run this in production?" by giving you the flexibility to run your own "Container Cloud" on whatever infrastructure you prefer while also giving you the simplicity and ease-of-use that you'd expect out of a PaaS.
Docker Cloud makes it effortless to "Build, deploy, and manage your apps across any cloud." Now that it is officially a part of Docker, we should see it become an even smoother process.