Thanks in advance!
Just so you know, I currently work on a project at my company that uses AWS, Codeship and BitBucket for development and production. AWS and Elasticbeanstalk host our application, Codeship runs tests on changes to branches in BitBucket and then pushes the code that passes on certain branches to different AWS environments for Development or Production.
Current setup is something like:
- Develop locally (OS X) - Test deploy to local Vagrant Linux VM (provisioned by Ansible) - Deploy to staging/live Linux VM w/ Ansible (or Fabric if I'm being lazy)
I've been following the Docker hype for some time now, but ever time I look into it, I couldn't find any info on how Docker could make my life simpler or easier. If anything, it would just add another complex abstraction layer to have to deal with.
What am I missing?
If your vagrant image resembles production, it's probably fine, but there's a level of confidence to be reached from deploying the exact entire self-contained binary, shipping it through QA and staging, and eventually promoting it to production.
Docker is more about process isolation using LXC than having a whole VM for a particular app. You still need some operating system underneath your docker deploys, so it feels redundant in a world where I already have a VM for each project. However I could see it shining at hosting a half dozen to few dozen services from the same machine.
One thing I don't like aesthetically is the tendency to expose local folders to the container. I prefer complete encapsulation.
If you are referring to docker-machine (née boot2docker) sharing your home directory into the VirtualBox, that's a necessity brought on by the fact that you are not developing on Linux and Docker is (currently) Linux only, so something has to give in that relationship. It is, IIRC, also more-or-less optional, with the tremendous downside that you must scp/rsync your workspace into VirtualBox by hand, before ssh-ing in to execute `docker build`.
Software engineering is often difficult because programmers have to deal with inconsistent environments for development and for production execution of their products. Due to mismatches between these environments, developers often found bugs that surface in one environment but not in another.
Hardware based virtualization (VMWare, HyperV, etc) helped with the inconsistency issue because it enabled developers to create dev/test environments that could later be replicated into production. However this category of virtualization requires more computational resources (esp. storage) than operating system virtualization like LXC used by Docker.
In addition to requiring less resources than hardware virtualization, Docker defined a convenient container specification format (Dockerfile) and a way to share these specifications (DockerHub). When used together, these Docker technologies accelerate the process of defining a consistent environment for both development and production in your application. Dockerfiles are easy to maintain and help reduce the need for a dedicated operations team for your application. In buzzword speak, your team can become more "DevOps".
Docker, by the virtue of relying on a thinner virtualization layer than hardware hypervisors like VMWare, also has higher performance for I/O intensive operations. When used on bare metal hardware, you going to be able to get better performance for many databases in Docker containers compared to databases running in a virtual machine guest.
So to recap, Docker can help you
- maintain consistent dev/test/prod environments
- use less resources than hardware virtualization
- free up the time your team spends on dev to ops handoffs
- improve your app I/O performance compared to running in a hardware virtualization based virtual machine guest
However if you are using AWS, note that Docker Container Service available from Amazon actually doesn't give you Docker on bare metal. That's because Docker Containers run in AWS virtual machine guests virtualized by Xen hypervisor. So with AWS you are paying a penalty in resources and performance when using Docker.
I also don't get the argument about running the same container in dev/test/prod. For example my company is working on going Docker and one of the problem with these environments is that app running there has different configuration. So the idea to solve it is to create three different versions of the same container. Genius! But now are you really running the same thing in dev/test/prod? How is it different to what we did in the past? Especially that before Docker through our continuous delivery we actually were using exact same artifact on machines set up with chef that were configured the same way as in prod, while with Docker now we plan to use three different containers.
I don't see benefits to running Docker in AWS. In my opinion, AWS implemented its Docker-based Container Service very poorly. I advise my customers against using AWS when want to use Docker. There are many bare metal as a service providers out in the marketplace.
>the argument about running the same container in dev/test/prod
Is this issue really caused by Docker because you said that you had consistent environments when built by chef?
Yes, you can achieve something similar using multiple layers in OpsWorks or different deployment schemes with normal Chef, but IMO containers make provisioning and deploying combinations of components easier than most other provisioning and deployment solutions. There's less opportunity for unexpected version collisions and because the network infrastructure is virtual, you can move containers between underlying VMs, allowing capacity planning without substantial reconfiguration.
I think this is the way Container-as-a-Service to go, instead of the current form of AWS ECS.
We're pretty heavily invested in Docker. To this point, it's really nice knowing that all the developers are operating in consistent environments.
An additional bonus is that using Docker makes it really easy to propagate infrastructure changes to the rest of your team for use in development. And, more importantly, know those infrastructure changes are consistent across local dev setups.
As an example, I recently incorporated Sphinx search into a project we were working on. I didn't want to require devs to install Sphinx on their own machines and get it up and running for search to function properly. I also didn't want devs to have the overhead of running Sphinx for search on their local boxes unless they were actively working on something related to search. Basically, I wanted search to be optionally configured to run on startup.
I used a DockerFile to setup Sphinx in its own container, pushed the DockerFile to a Tools source repository we use, and then incorporated the build and running of that container into our startup scripts (just some simple orchestration stuff for the local machine written in bash). Now, if a dev wants a containerized search mechanism they run a simple bash script to build that container, then run another command to spin up our dockerized web app with a connection to a running sphinx search container. We do this for all of our services: mysql, redis, sphinx, the web app itself, and anything else we might need.
As an added bonus, all the Docker CLI work and orchestration of our application is easily hidden behind a shell script. If a dev wants to run the webapp, they simply run: app server dev. If they want the app with search they run: app server dev search from the command line. Developers never need to know what's going on under the hood to get their job done. From their perspective, it just works.
Does Docker handle multi-environment configuration management? For example: qa, stage and live have the same config files, but different values.
Currently we're using Ansible and we set variables for a specific environment, then we feed those variables into config files based on where we're deploying to (config files are not duplicated, only variables that feed into config files.)
All of our configuration is in git and we can quickly see and change it.
How does Docker handle this?
We have a single playbook to deploy everything, i.e. deploy multiple (micro)services, heavily using docker images pulled from a private registry.
With a single playbook, we have multiple Ansible inventory / hosts file for each environment: QA, prod. Sensitive information / secrets are stored in Ansible-vault groupvar files. QA people have ssh access to their own machines, while Prod ops have their own separate ssh access and machines.
The playbook was refactored to heavily use roles, wherein config template files are dynamically setup using inputs from inventory vars and groupvars.
The roles are also topology independent, meaning a QA project cluster can actually be a single big VM with mocked DBs, while the Prod cluster can be spread across multiple machines.
Docker helped simplify the code deployment. Prior to deployment, docker images are built and tested by Jenkins first prior to pushing the images to the registry.
Some will even go as far as using a CM tool to do the entire internal Dockerfile build, and the Dockerfile is just a wrapper around the CM tool. This does require more bloat inside the Docker image, as you need to have your CM tool or whatever other supporting files/scripts installed in the image, but it does make more complex scenarios much simpler.
This pattern is maybe even more helpful than harmful, for making your dev environment more closely match production, when your final deploy target is not a docker container.
(You are obviously going to want to see those build scripts running in test, if not earlier; certainly once, before they should kick off in a production environment.) You could do more individual steps in the docker file, just like you could store your token credentials and database handles in the git repository. Neither way is "completely wrong" but there is a trade-off.
In the long run it's a bad idea: you wind up with a snowflake PaaS that only you maintain and only you can understand or extend. The amount of engineering effort behind Heroku, Cloud Foundry or OpenShift is enormous and you can get support on a high level.
I'm biased, because I work for Pivotal (who founded Cloud Foundry), but in my view rolling your own PaaS is a strategic error at this point.
In more general terms: more the complex the environment, the more moving pieces, the more developers on the team, the more servers in production, the more likely there's going be a discrepancy between what Developer-A has running on his machine, and what Developer-B has running on theirs. Docker helps keep everybody on the same page.
For me personally: I'm a dev on a number of projects, and Docker helps me keep my dependencies straight. I no longer have to change things around locally just to work on Project-A, I just get their latest Docker image, and I'm good to go.
A docker container is also way more lightweight. Instead of running a full OS, you I only run one process. So your docker image starts within seconds
Secondly, composition. Can you provision and link the 10 instances that make up your application? Web servers, app servers, proxies, caches, databases, hadoop etc.
I think this second ability is the truly compelling one for me. The features that allow this (swarm and compose for docker, lots of other competing orchestration stuff) are still pretty young, but it would still push me in the direction of containerization over virtualization.
Although I do use docker to run deluge in a container with openvpn on my home pc, but only because someone else had gone to the trouble of writing the dockerfile and getting it to work.
It seems to break a lot though, when I have time I'm going to get rid of it and replace it with a systemd-nspawn container, because there's less handwaving involved and I can get it to work correctly.
Would you feel differently if you hadn't already ramped up on all those technologies?
What I mean is that since docker sort of overlaps with much of what people are doing with configuration management, containers, build/packaging systems, and virtualization, it has the potential to reduce the complexity of the stack. If someone's starting fresh, they can potentially avoid having to learn to use and deploy some or all of those different components and just go with docker.
That's actually pretty cool.
I have a VM setup with transmission/openvpn since I was having issues getting the VPN to work with Docker's networking and it was just easier to use a standard VM instead.
I'm sure you could easily change it to work with other VPN providers
Some of our newer services need a up to date version of glibc and a lot of other dependencies CentOS can't provide. So we use docker to boot up Ubuntu 14.04 containers and run the services with special needs in them.
Another great thing is isolating scripts we don't trust. We allow our customers to run scripts of all kind on our servers --> inside Docker containers. So the customers can't mess with the hostsystem.
Is CentOS not the state-of-the-art Linux distro to run for servers (besides RHEL for support)?
In many cases now, they are not. Docker containers can run on CoreOS, which machines are designed to be configured entirely from a cloud-config file, organized in clusters.
With Deis for example, you can build and orchestrate your scalable web service in Docker containers without even writing a Dockerfile, or necessarily knowing anything about how the Docker container is built. The builder creates slugs with the necessary binaries to host your service, and you tell the container how to run itself with a (often one-line) Procfile.
I would still want chef scripts for my database server, but for things that can live in a container on a Fleet cluster, I most certainly do not use Chef, but I absolutely do get reproducible hands-off builds for my runtime environment, and without spending time individually preparing the host machines.
You're right, for now, but hopefully not forever.
Docker, the company, has got an insane valuation, so is monetize anything and everything in sight to validate that valuation. But trying to give away tools to developers is an uphill battle on a good day, never mind selling to developers. So Docker is pursuing the end of the market that's likely to pay off - the data center, and that's why there's such a huge push behind putting Docker into production.
Now, my experience with current CM tools is that it's still easier to boot a VM and tinker with it to get it working 'normally' (ie, bash + editing config files directly), and then throw that VM away and play with my chosen CM tool to get it working there instead.
Dockerfiles do a good job of bridging that divide, out of the box. On a fresh machine, I install the base OS, and then install docker, and I'm up and running Dockerfiles, albiet with a cold (docker build) cache.
Hopefully the next generation of CM tools can blend the both so setting up a local target is easy as 'docker build' and ongoing maintenance of deployed machines is as easy as 'puppet agent --onetime'.
(Ok, I know there are real use cases for Docker, but I see a lot of hype as well. People telling my mathematician friend that she needs to use docker at the start of her project - it is likely to be a one off graph she needs to produce for a research paper).
Reproducibility is a big push.... but not like you are suggesting. Shipping a dockerfile is the equivalent of saying "This works, if you use this flask, this pipette, this GCMS and this piece of litmus paper"
Docker is not the only solution to problems. It solves some, but you can't tack it on to everything.
As you noted, reproducibility is a huge issue in the scientific community (according to docker users/vendors I've spoke to) to the extent that there are a number of funded startups trying to solve this problem (some using Docker.)
What has been also very surprising is the big companies who have read only copies of analytic data they want to run computations on - sandboxing the data scientists scripts in a container has helped them tremendously in terms of supporting the execution.
Take the docker-compose for example. You can just check the code out, run a single script that builds the project for your environment and everything is pretty much self contained in the dockerfile (https://github.com/docker/compose/blob/master/Dockerfile). You don't have to clog up your host computer with deps and you get an executable plopped into an output bin folder.
Additionally, the steps in the dockerfile get cached so subsequent builds are really fast.
First off there's the FROM line, which can contain whatever opaque image you feel like that already has dependencies inside it, and who knows how they got there or what will happen when it needs to be updated.
Then there's the fact that it's like a script but worse: every line creates a new image, and docker will try to cache the results after each line, but that cache can work against you if you're not really careful (imagine if build systems like make worked that way? No dependency tree, just refusing to execute the first half of your makefile because well, it worked last time so why do it again?
And in practice, you get to find out how many people just put an "apt-get update" in their docker file too. Now our backwards compatiblility is really just equal to Debian's. Hope there's no back ports repos in there or anything that would give a non-backwards-compatible package!
It's certainly possible to use Dockerfiles to create reproducible builds, but it's literally no better than a shell script at doing that. You have all the rope you need to hang yourself and then some.
Docker builds actually aren't reproducible. There are many sources of non-determinism that Docker cannot address. Do you use the base images from DockerHub as-is or do you run 'apt-get upgrade' or whatever for security patches? If you do, the result you get from building that image (as opposed to using what's in a cache) is different depending on the time it was built. The same goes for any Dockerfiles that compile from source. Hell, just extracting a source tarball results in a different hash of the source tree because of the timestamps on the files. You and I have little hope of building the same image and getting the same exact result.
Build reproducibility is a very interesting topic with some unsolved issues, but Docker isn't helping with it. See https://reproducible.debian.net for a good resource about build reproducibility.
For me personally, the time it takes from performing an edit to seeing your change "live" on a developer's machine is extremely important. To this end we've spent some effort in making our own services and dependencies run natively on both OS X and Linux to minimize the turnaround time (currently at around 4 seconds).
Docker fixes the "works on my machine" problem, which is worth tackling but not something you run into too often, but (in my admittedly limited experience) introduces pain into the developer's workflow. Right now, I'm leaning towards enforcing identical environments in CI testing and production via Docker images, but not necessarily extending that to the developer's machines. Developers can still download images of dependencies, just not for the thing they're actually developing. I'd love to hear alternative takes.
So to solve the live reload problem we do only one thing in development which we don't do anywhere else: the Dockerfile copies all the current source files into the image, but we run the container with a mounted volume of the source code - which in dev mappes exactly the same way the Dockerfile defines the src copy.
This way when you create the image and start the dev container it won't change anything, but as the src is mounted on top of the included src in the image the regular (Rails) auto reload works perfectly.
For test and prod we just simply don't do any volume mounting at all, and use the baked in src directly.
Easy and fast everywhere, all you have to control is how and when the images are created (ex: we do a full clean checkout in a new directory before building a test image, to ensure it only contains committed code. EDIT: by test I mean for local testing, while you're working on revisions, a CI server does the automatic testing).
I would love to find the time to modernize in the context of machine/swarm/compose.
One of the thoughts[1] was using docker volumes as sophisticated pipes to other docker processes, allowing for a different kind of blog/publish/editor workflow while being agnostic in tools (blog engine, editor [web or some other mechanism]) for how the content is actually created.
Needless to say, there are many aspects of Docker I find really powerful, and I particularly delight in taking an existing workflow and modernizing it in that context.
Long winded context, but, suffice to say, a 4sec turnaround time would be way too long for me personally. I know first hand as well as through all of the talks on Docker out there it is possible to get near realtime updates of your app in local dev.
If Docker was fixing this only, I would still use it. There is nothing better than a single binary deployment that is byte to byte the same as it was running on a dev laptop and a QA env.
(Yes, I'm being hyperbolic, unless you want to have your entire application running from a servlet container with nothing in front of it. And I agree, a single deployment object is just about the only way to keep your sanity. But still, this isn't the first thing that's proclaimed that advantage.)
If you running in AWS, you use VMs anyway so the overhead is there no matter what (and also is not your concern, because you pay for the VMs). By adding Docker there you basically adding one extra layer on top of it, so from the infrastructure point of view you making things even more complex.
https://www.youtube.com/watch?v=zVUPmmUU3yY
this was a year ago, so a little out of date. I now work for another company that is into Docker.
I also have various bits on my blog:
check out the jenkins ones, for example:
http://zwischenzugs.tk/index.php/2014/11/08/taming-slaves-wi...
http://zwischenzugs.tk/index.php/2015/03/19/scale-your-jenki...
Using Docker meant that the slaves could be built from scratch as well.
See here: http://zwischenzugs.tk/index.php/2014/11/08/taming-slaves-wi...
For my website I have it set up with continuous integration to run my tests when I merge into master and build a docker image which it then pushes to the docker registry. I then have it ssh into my host server, pull that image, then run the new container and remove the old one.
Boom, i've just deployed my website by simply merging a PR into my master!
This is just a simple use case, and I probably wouldn't suggest deploying a production ready site like this, but it's really cool! It's really simple to just pass around images and have things up and running on local dev's too
I prefer to manually deploy, it's only one command, and I can make sure it's all worked correctly.
That said, I will be moving that command to a chat command, as I like that. But even then, it'll be a manually triggered command.
I have auto deploy setup for CI testing, as in that case I do want to know that those branches are ready for deployment to prod, when I want to.
I was also playing around with a chat command to spin up PR's/branches that haven't been merged into master yet, onto a temp container for viewing! Dunno, maybe i'm just not as familiar with other tools that can do similar things as easily
You have two choices:
1. Upgrade to CentOS 7.x.
2. Use Docker and install the software into a container using a newer OS (CentOS 7.x or a newer Debian).
#1 is very expensive and sometimes impossible (if you need to be on CentOS 6.x for compatibility reasons).
#2 is very cheap.
There's one of your business cases right there.
Instead of spinning up new VMs in each environment for one new application, we can instead run a Ubuntu container with the application within the existing environment. This brings with it all the other benefits such as continuous delivery and orchestration that we didn't have before.
Once the platform is established there is no limit what we can run within a repeatable and consistent environment.
Everything else is still nice, but it's basically "dev environments suck less".
This ecosystem is still so raw.
Try Lattice: http://lattice.cf/
Disclaimer, I work for Pivotal, which developed Lattice based on Cloud Foundry components.
Why Use Docker: "How does this help you build better software? When your app is in Docker containers, you don’t have to worry about setting up and maintaining different environments or different tooling for each language. Focus on creating new features, fixing issues and shipping software."
Business Case: "...With Docker, you can easily take copies of your live environment and run on any new endpoint running Docker..."
I've created several repos on Github for that matter. Here's for example some boilerplate for running Node.js, Express, Nginx, Redis and Grunt/Gulp inside Docker containers:
That said, I'm only using it in development. For production there's so many options I don't even know where to begin: http://stackoverflow.com/a/18287169/3557327
I'm saying this because I know docker solves a lot of pain on the devops side, but on the "software" side it's been painful all the time I've touched it. I.e. practically speaking, it makes releasing much slower, sometimes I'm forced to do a hard reset on the container rather than just reload nginx, etc.
My suggestion is to go with what's simpler for your stack. If you're struggling with having to manage and deploy new configured/secure ec2 instances every day, then it might be worth looking into docker.
To expand on this:
* Heroku have introduced Docker-based tools to run their buildpacks outside of their staging servers,
* Cloud Foundry has, in public beta, the Diego scheduler, which can accept and manage Docker images,
* OpenShift 3 uses Docker and Kubernetes as its core components.
Disclaimer: I work for Pivotal, who founded Cloud Foundry.
If we want to get really specific, Its also common to see the "DB" image split up between the image of the disk where the data is actually persisted, and the image of the actual DB process. This makes it easy to play around with your data under different versions of your DB.
There are a lot of really great reasons to use Docker, or any container technology for CI.
First off containers give you a standard interface to a reproducable build. This means you can run something in a container and expect it to behave the same way as something a co-worker runs on their workstation, or something run in the staging or production environments. For CI this is an absolute necessity. Rather than running tests locally, and expecting a CI server closely tracking the production/staging environments to catch issues with different version of the OS or libraries you can expect any build that passes locally to also pass on CI. This cuts down on a lot of potential back and forth. The only shared dependency between CI/local/prod/staging is docker itself.
Another benefit is (almost) complete isolation. This means rather than having different vm images tracking different projects, you can have a single vm image with docker, and have each container running on the vm for any version of any build across your system. From a CI perspective you can abstract most of the complex configuration for your applications into "docker build -t myapp_test ./Dockerfile.test && docker run myapp_test".
Containers use a differential filesystem, so N running containers for an application will take up 1 X the size of the container image + N x the average space of changes made in the running containers on top of that base image. This makes larger images highly space efficient without having to worry about different instances treading on the same folders.
The line between dev and ops blurs a little (devops), but clear responsibilities. Ops becomes responsible for maintaining the docker infrastructure, and dev is responsible for everything inside the container boundary, the container image, installed packages, code compilation, and how the containers interact. A container mantra is "no more 'well it worked on MY machine'". If it works for the dev, it really will work in prod.
Besides this, there a number of benefits around speed, accessibility, debugging, standardization, the list goes on. There are also a ton of great and varied Docker CI solutions out there, from specific Docker based CI like us (codeship), Shippable, Drone, Circleci, as well as standard solutions like jenkins via plugins. Many hosting solutions are supporting docker redeploy hooks for CI purposes. The standardized nature of containers make it trivial for vendors to provide integrations. Even if you don't use docker yourselves, this is certainly a great space to watch.
Technically you can use docker for CI/CD without using it for deploying your app. When you do this you lose some of the benefits listed, but not all. You lose the cohesion between CI/local and prod, but you still gain a whole lot in terms of speed and complexity within your CI infrastructure.
Thomas Shaw did a great talk at Dockercon on introducing Docker to Demonware for CI across a variety of projects. I don't think the video is up yet, but it's well worth a watch if you're thinking of bringing it into your company. In the meantime we wrote a blog post on his talk: http://blog.codeship.com/dockercon-2015-using-docker-to-driv....
If anyone is interested in joining our beta, just drop me an email: brendan at codeship.com.
My only warning is that using anything but Ubuntu for your build host is going to take way too long and you're going to be waiting hours for it to complete if you don't have any layers cached.
#1 is in my dayjob:
We use docker in combination with vagrant for spinning up a test environment consisting of several containers with different components (both ur own products and 3rd party) to run integration tests against them.
The main reasons for this approach are: - We can supply containers with the installed producs which saves time on automated runs since you don't have to run a setup every time
- We can provide certain customizations which are only needed for testing and which we don't want to ship to customers without doing all the steps needed for that over and over again
- We have exact control and version how the environment looks like.
- Resources are better distributed than in hardware virtualization environments
#2 Is a pet project of mine, a backend for a mobile App. There are still big parts missing, but in the moment it consists of a backend application which exposes a REST API running on equinox plus a database (in an own container).
The reasons I see for using docker here:
- I have control and versioning of the environment
- I can test on my laptop in the same components as prod, but scaled down (by just spinning up the database and one backend container)
- Since more and more cloud providers are supporting Docker (I am currently having an eye on AWS and DigitalOcean, haven't decided yet), switching the provider in the future will be easier compared to having, say a proprietary image or whatever.
- If I ever scale up the poject and onboard new teammembers, the entry barriers for (at least) helping in Ops will be lower than if they have to learn the single technologies until they get at least basic knowledge of the project.
That said I've paged the founders to this thread, they can make the case much more effectively than I can. (disclosure: I don't work for Codeship).
What are the business cases for using Docker over some other container-based solution?
we're a webshop, and recently we've standardized our stack on symfony2/nginx/postgresql, so all our websites use that. but beside of that we have some that we maintain that need to run on old version of php/centos.
As we have only 1 server internally for pre-staging environments, docker does help us to save a lot of memory/cpu compare to what we had before (virtualbox, yes...), without needing a lot of machine to setup (like openstack).
Also we don't really have a guy dedicated to sysadmin, so the less time we need to spent on server administration, the better we feel. So we have a set of 3 containers (for symfony+php_fpm / postgresql / nginx ) that already tuned to meet our needs, with a ansible playbook https://github.com/allan-simon/ansible-docker-symfony2-vagra... , that we reuse for every new project we have. So that the developers can have a working stack, without needing to reinvent the wheel, they even don't need any knowledge of system adminstration "run this ansible command, done" ! without any risk to break other services.
Also the reproductability and the stateless properties of docker containers has helped to nearly eliminate the class of bugs "the guy that does not work in our company anymore made a tweak one day on the server to solve this business critical bug, but nobody know what it is but we need to redeploy and the bug has reappeared"
Plusses:
- Dont see any environment related issues because the docker image is the same in every environment
- Easy onboarding to teams that use docker because you dont need to setup anything new. This is especially useful if your company encourages developers to work across teams
- Ops can build around infrastructure around this and be sure that every team builds and runs code in the same way
- If your application is complex, using docker-compose, its extremely simple to setup your dev environment
- The community is moving towards docker, and it doesnt hurt your resume if you have production docker experience
Minuses:
- For an extremely simple application (that you think will remain simple over its lifetime), it might be more overhead to use docker than not use it
- Even though we’ve been using boot2docker and vagrant to setup docker on MacOSX, it hasnt worked seamlessly. When you get on and off a vpn for example, boot2docker has constantly messed things up. If you can get your dev setup right, docker works well. If not, it can be a pain sometimes on OSX
- Although its easy to build docker images for most of the open source software out there (if docker images dont already exist), it can be a pain to do that for enterprise software. Try using docker with oracle db. You might get it to work. You wont have fun with it !!
I've used puppet for several years to manage our infrastructure, and puppet is still managing all our staff and student laptops, but for servers, I've switched everything to CoreOS + Docker.
When we dockerize the app, they can be setup with the docker image and ready to go in under an hour, without having to screw with their system ... much.
On the infrastructure deployment side of things.... Previous to our "dockerized" infrastructure we were managing about 7 different AMI's for all our servers and it was becoming a pain in the butt to manage the installation of new software if our application called for it, create a new AMI, then re-deploy said AMI. If you have experience with AWS and you have done this enough times, I'm sure you have faced at one point or another long wait times for your AMI to be created before you can re-deploy with that newly created AMI. This is time wasted on the application deployment side of things, but also on the personnel side of things while you wait for that damn thing to be created so you can re-deploy. Time is money and money waiting for resources to be available or for AMI's to be created is money taken away from the business. Additionally though in its infancy stage, we are using docker-compose (https://docs.docker.com/compose/) which offers some really nice ways of defining your container infrastructure within a single machine, I highly recommend looking into this for further efficiency.
* Solaris Zones, see also SmartOS Zones based on that
* FreeBSD jails
It's working pretty well. Once you check in your code, docker repository hooked to bitbucket will build the docker image and then you can start deployment from Tutum with one click.
You can compare different Docker solutions (http://www.cloud66.com/compare) and read how Cloud 66 used Docker.(http://blog.cloud66.com/docker-in-production-from-a-to-z/). (disclaimer: I do work at Cloud 66 )
My experience with Deis has been wonderful. If you ever looked at Heroku but got to the pricing page and didn't look any further, Deis has the same workflow (and much of the same stack, Cedar) as Heroku. The whole thing is built on docker containers, and designed with failover in mind.
I see that Codeship costs a fair amount of money on the higher end of usage; for the cost of a few months on their enterprise subscription, you could probably build your own CI cluster on Deis. CoreOS also targets AWS, and I don't have any idea what your AWS environment looks like, but you could likely build a Deis cluster on AWS just as easily as you could on your own hardware, if not easier.
I try not to think of Docker as an end so much as a means. For me, it doesn't even matter that it's using Docker under the hood, but if you have containerized your application, Deis can work on already built images just as easily as Heroku works on git repositories.
I can't use Heroku for serious things because it costs too much, and we're small potatoes. But I've got plenty of hardware lying around, and some slightly bigger iron that if I'm being honest is probably underutilized, this is based on knowing that it hosts multiple kernels using virtualization, and the only reason those different tasks run on different machines is to keep them nominally isolated for increased maintainability.
Containerization is "virtualization lite." If I can take those services and jobs that all run on their own virtual machines and make them all run on Deis instead (or even just the ones that don't maintain any internal state of their own), I will gain a resource boost by not having to virtualize all of that separate virtual hardware and individual Linux kernels anymore. The marginal cost of another container is lower than a full virtual machine. If it fits into CI, the maintenance cost is lower too, because that's one less individual system that needs to get apt-get upgrade. If we were better at adopting things like chef, this might not be an argument, but for us it still is.
I inherited a lot of legacy stuff. Your situation might not be anything like mine. If you are already drinking the CI kool-aid, you might not honestly have much to gain from Docker that would compel you to invest time and effort into using it to host your apps.
If Deis looks a little complicated, you might check out dokku. Your laptop probably doesn't have enough power to spin up a whole Deis cluster, but you can still get "almost like the Heroku experience" using Dokku, with Docker under the hood providing support. I'm not going to promise you that it will cut your AWS bills in half, but if you did drink the kool-aid, it might be worth checking out just how much of your currently required development infrastructure and outsourced hosting needs can just go away when you add containerization to your developer toolbelt.
I shed a single tear when I realized I could just fire up flask + nginx + uwsgi within seconds after installing docker.
For a business perspective, it's a little tricky. I guess it can help if you need to offer an onsite version of your SaaS app and the enterprise client had strict rules about being on site.
What would really make docker kickass is if they had a way to encrypt all the source code somehow and protect it.