How to Deploy All Day yet Deploy Nothing
mr.si
mr.si
1. Docker is a first-class citizen on Linux, and a second-class citizen everywhere else. "Setting up Docker" on Linux means installing the Docker daemon. "Setting up Docker" on OSX or Windows means installing a Linux VM containing Docker and getting it to port-forward the docker daemon from that VM to your host. After it's set up, there's no day-to-day usage difference—but that stumbling block is a big one.
2. Nothing AWS offers—no matter how much it might look that way—is an end-user platform. It's all infrastructure, the kind of thing sysadmins set up/deal with. Infrastructure-as-a-Service effectively means "our market is bigcorp CIOs making buy-vs-build decisions": decisions of whether to provision more local data-center infrastructure, or provision that same infrastructure "in the cloud."
In other words: Elastic Beanstalk isn't for prototyping an instance of your app! Instead, it's for CIOs considering replacing "our data center containing a bunch of machines with docker daemons on them" with "our AWS VPC containing a bunch of opaque instances with docker daemons on them." The same goes for every other AWS service: the documentation and "semantic models" of AWS services are not targeted at app developers, but rather at the sysadmins who were implementing the CIO's whims by keeping local infrastructure going at-scale, and are now implementing the CIO's whims by porting said infrastructure to the Amazon cloud.
AWS might be intuitive to you as a developer if you have 5+ years of devops experience, deploying your own code and and managing the infrastructure it sits on. Otherwise, the choices AWS offers will be pretty opaque to you.
(Side-note: there's a business model [that AWS allows and encourages] in taking an AWS IaaS-level component, and shellacking a coat of UX onto it to make it into a PaaS component, and making your money by arbitraging on the "PaaS premium." Heroku is PaaS-shellacked EC2 instances; Tarsnap (or Dropbox, even) is PaaS-shellacked S3 buckets; etc. I'm surprised more of these businesses don't exist.)
On a laptop you now have an extra OS running, with all the associated costs: talking to disk every now and then, doing os-y things.
If nothing else, it feels like my battery runs out faster with docker-machine on and no containers running. But maybe somebody has actual numbers on this?
Oh, they do; but because they target niches, they might be small and not be on your radar. Also, the whole field is still pretty green, in the grand scheme of things; as you say, it takes years to be able to properly leverage the AWS ecosystem.
I don't agree here. I'm definitely in the sysadmin camp but I'd like to think I've advanced from where I was when that was my job title 5 years ago or so.
For us, Cloud Formation was the real eye-opener. We leveraged CF to build a rather sophisticated environment. We referred the CF to our customers who then set it up on their own. We did this over several customers, with various degrees of AWS experience from zero to expert, and various backgrounds from security, to network, to IT. All were successful. I'd describe all as end-users.
The reproducibility, atomicity, and ease of this solution gave us huge gains.
They tend to be small, and only wrap a single aspect of the AWS service.
My simple site wraps Route53, allowing you to maintain and change DNS via git-pushes, chances are you've not heard of it because the number of users it suits is pretty small - https://dns-api.com/
It's not just AWS. This is pretty much true of every infrastructure/cloud as a service company. They either have too many knobs with all sorts of unintended interactions and half-baked integrations or they abstract away way too much and you have no control over anything and can only deploy a nodejs or django application that follows a very specific rigid structure. Oh and did I mention most of this stuff is insecure by default and if you want to do anything in a secure way then your n-layer configuration nightmare is now 10x worse (probably why most places are looking for 10x programmers). Oh and there is also networking/NAT, user management, logging, artifact distributions, service discovery, etc. to worry about as well using tools that are just as half-baked.
At what point does it make sense to use docker? Is it worth learning all of the above crazyness if you have less than 10K people using your service and are 1 person?
If you do things right and stage your artifacting and deployment process properly then that is 90% of the battle I think because none of the cloud providers are magic. Any service they have that promises to abstract away your deployment and configuration pipeline is a bold-faced lie. Heck, they don't even have a way for automating the network topology configuration that isn't a nightmarish maze of JSON (I'm speaking of course of cloud formation). So even if you are using docker, that is in no way a solution to a proper deployment pipeline with properly versioned artifacts and dependencies.
Cheers, will stick with getting better at developing software and not worry about the container craze yet. thanks.
Hence why I prefer things like OOCSS over Bootstrap, Capistrano over Docker. Bootstrap forces your markup to conform to your framework, drowning you in incoherent class names that are going to flee your mind the second you have to remember why you put them there. OOCSS makes you treat your markup and CSS holistically, so that when it comes time to troubleshoot a browser bug, you can easily apprehend what your markup was supposed to do and why you did it that way.
Docker automates things that don't really need to be automated, unless you've got the kind of problem that really could make use of Docker's abstractions. People think they need Docker when they don't, then get surprised when Docker doesn't magically solve the problem they were hoping it would solve.
Make things work in the simple case, and then iterate towards the complex. If you ignore this, then you will eventually find yourself in the situation where you have a deadline to meet that you simply won't be able to meet because you're writing technical checks that your skills won't be able to cash.
Oh the good old times when I was learning to program. Configuration was just a simple INI parser written in two hours from scratch. Networking was done by Apache, user management meant a database table, logging was done with a function wrapping over fprintf(), "artifact distributions" meant res/ folder, service discovery was done on paper. And somehow everything worked. It worked better and was infinitely more manageable, and was mostly dependency-free.
I can see how the above would cause problems for e.g. Google. But 99% of companies and open-source projects are not Google.
Web development is insane.
You and I apparently remember things very differently.
Of course this is a slippery slope and often devs not familiar with RPM eg end up reinventing the wheel as each deployment failure breeds distrust between teams and more workarounds and safeguards get introduced.
It should be, but well... this is something if you're using PHP.
If you're using anything hipster (ruby, iirc python, Java) you're out of luck with that.
I worked on Cloud Foundry buildpacks for a while. The PHP buildpack is actually one of the more complicated ones, because at staging time it tries to recreate a shared hosting environment in a standalone container.
The Ruby buildpack is complicated for legacy reasons, but for 99% of modern apps all it really does is run bundler and rackup.
Meanwhile every PHP app wants to keep on living in the 90s.
Arguably the Java buildpack has the simplest job, if you use a sane build tool. "Here, launch this jar".
You might have a database and a web app. But the database gets slow, so you add a caching layer. Then you need to scale up to accomodate more users. You've got to be able to back up all your users' data. And when your app gets complicated, deployments can break things, so you also need to be able to roll back quickly. Once you have a dozen or more servers going, you realize that if one goes down everything breaks, so you have to add redundancy to each part of the system, which adds even more concerns about how backups and recovery is handled. Then you need to add some search features to your growing dataset, which necessitates another kind of database to index your primary database, and more app servers. Oh, and by this point when things break, it becomes really hard to tell why things are broken, so you need monitoring and centralized logging, and whoops, those are two more kinds of databases and the associated web applications to manage them. And when you're at this scale, you have to coordinate multiple pieces of the system for any change you make, so you have additional software to manage that. And by now, you'll realize your original code was terrible, and while you are wise enough to know not to try to rewrite everything, you instead take various pieces of your infrastructure and break them into microservices in new languages, and...
Are you getting the picture?
If you want to experiment with an entirely new stack of technologies intended for deploying distributed, multi-tier, scalable apps, that's cool, but don't feign surprise if it takes you more than 30 minutes.
None of it is hard, honestly - it's all well-documented things that a smart person can teach themselves how to do. And I honestly think that having one person take end-to-end responsibility for delivering one piece of functionality results in much higher quality than having twenty people specializing in a single layer as it applies to twenty different deliverables.
It would be useful if there was a guide on how to scale your app wisely. > So what are the basic steps you will go through? > What are caveats and best practices per step? > What are the important choices and when do you make them?
Could you recommend a resource for answers on these questions?
I took your comment and edited it a bit:
Start: database + web app
Slow database: adding caching layer
Need to backup: starting back up all your users' data
App gets complicated, deployments break: being able to roll back quickly
You have a dozen or more servers. If one goes down everything breaks: adding redundancy to each part of the system and improve backups and recovery.
You need search features: add another kind of database to index your primary database and add more app servers.
Now when things break, it becomes really hard to tell why things are broken: add monitoring and centralized logging. Those are two more kinds of databases and web applications to manage them.
Coordinate multiple pieces of the system for any change you make: add additional software to manage that.
You'll realize your original code was terrible: you take various pieces of your infrastructure and break them into microservices in new languages.
And...
I worked that way for two years. It doesn't really matter if everything works smoothly under Vagrant if every day you want to kill yourself at your desk because you can't run an Vagrant and a browser at the same time without bringing the system to its knees.
After a few nights of trying to get Docker to run on my work laptop, I figured there was an issue with Windows security as the VM would be created but Docker would fail to initialise. One of my colleagues said a CentOS worked for him. By then I had dumped Docker for Vagrant; which also had the same issues. I was now trying to figure out how to run Vagrant on Hyper-V as Vbox was acting up. I grew some grey hair those weekends. I'd rather be conservative with my time; use what works and wait for some of these tools to mature.
I'm extremely conservative these days. I beat my head against Capistrano long enough to learn its ins and outs, so if some new tool doesn't work with minimal Googling, I go right back to good-ole' Cap. I have a provisioning procedure I adapt for each cloud host that basically gets the machine ready for cap deploy. If cap deploy doesn't run smoothly, I alter my provisioning procedure once I figure out why. Usually it's for gem OS dependencies.
Any replacement strategy would have to beat the ease and reliability of Capistrano. That's going to be tough.
Or, since I work for Pivotal: why not Pivotal Web Services?
The Ruby buildpack (which is > 90% identical code between the two) is pretty well-tested for deploying Rails at this point.
So much effort, just to get to zero. Somehow, somewhere, this has to change.