- [Instructor] Now that we've automated the process
of getting your code from your laptop
into your private Docker registry,
let's go ahead and start looking at
the other side of that process,
getting code out of your registry and onto your servers.
So let's talk about deployment and places to deploy,
stages of deployment.
So the traditional places to deploy things
are a development environment,
this can be your laptop or a dedicated development machine
you use, or, most often, a bit of both,
there's often a staging environment in a company
for testing things out
that are just about to go to production,
and then people often talk about production, the real deal.
One of the things we work towards in this course is
making it so that there isn't just one staging.
Automate your deployment so it can push to many places,
and then you can use that as a tool
to build whatever flow you need.
One of those places just happens to be the production.
In general, each of these needs a deployer,
but if you can arrange your project
so that you have one deployer,
where you just check an option, deploy to production,
deploy to staging, deploy to other staging,
that can be a nice thing to work towards.
So there are a couple of different strategies towards
choosing what to actually deploy.
There's the fixed branch project, which is,
we deploy whatever hits the master branch,
or we deploy whatever hits the release branch.
And that's pretty good.
This approach gives you a nice, solid,
easy-to-explain approach to how you're building your system.
Something hits this branch, it gets deployed.
It's a little bit constraining in the long run,
because sometimes you'll want to go and redeploy something
that was deployed previously
or deploy an old version into a new place.
It's an excellent place to start,
that's where the demos in this course are going to go.
Where we want to work towards is, deploy any commit you want
at any time, to any place.
That's the long-term goal.
It's very, very nice to be able to say,
this is the code that was in production on Tuesday,
then this hash was in production,
then that git-hash was in production,
definitely a thing to work towards.
Now, continuous deployment is, you check it in,
it goes to production.
Boom, that's super scary.
So we solved this problem by inventing a new word,
continuous delivery.
Every commit gets delivered to the point of deploying
but not quite deployed.
This frightens people quite a lot less.
It also is an excellent place to sit
while you build trust in your systems,
so you know it's actually going to work,
and more importantly, learn the ways that it fails.
Then you can turn on continual deployment,
for the projects that have shown that they're ready.
Let's talk about the actual deployment processes.
A traditional, solid option for many years
is the update in place model.
You have an old server, you want to deploy new code,
you put the new code onto the server,
turn off the old code, start the new code, good to go.
In Dockerland, this looks like having a server
that runs a Docker image, so pretty much the same thing.
You can use the same server, you just change it
from running your code directly to running a Docker image.
Then, when there's a new version of that Docker image,
you go through and just restart that container,
it pulls the new image, and you get the same thing.
This is an excellent place to start,
especially in environments
where cloud-based deployment is not desirable or feasible.
One step up from that is
the so-called blue-green deployment,
where you have your running system, call it blue,
as an arbitrary name,
and you're about to deploy a new one, call it green.
You leave blue running and then deploy green.
When they're all ready, you switch over.
There are a lot of ways to go about this.
You can do it by literally switching the IP address
by sending a message to your router, saying,
hey, that IP address is over here now.
You can do it by changing a DNS name, I do that quite a lot.
You can do it with load balancers,
where you have an intermediate system
that receives all your traffic
and is responsible for dispatching it
to the currently-running system.
I prefer this method over DNS-based, in my personal life.
I do run it both ways in different places.
Just to talk a little bit more about using DNS
for this process, you create the new service,
then you assign the production name to it.
Keep in mind, the DNS propagation
through the internet is slow.
When you make your change, it's going to take about,
depending on your time-to-live on your DNS settings,
15 minutes to an hour
to propagate through the whole internet.
So there's going to be an overlap,
where both of your systems are running,
the old one and the new one.
So you just have to be aware that your changes
will need to run in the presence of their predecessors.
This is a solid option.
It will work in cases where you don't have any control
over the deployment environment,
and it's a bit slower than many of the other options,
especially the load balancer-based ones.
Load balancers can respond very quickly.
They receive all the traffic
and can do things like deploy to the new traffic
and then immediately switch back if something goes wrong.
They can also do more interesting deployments,
like deploy the new systems,
then scale the old systems back to half,
see it still works, continue scaling back,
and there are many, many options for using load balancers.
Here's just a little bit of advice
for when you're getting started.
Be ready to roll back from the start.
Don't make a deployer that you're going to test in production,
where you have not ever tried rolling it back.
It is probably possible for a deployment to work correctly
the first time, on the first go of a new system,
I just haven't seen it.
If you're transitioning to a system
that uses automatic load balancing,
don't transition any faster than half of the speed
that that thing can respond to changes in load.
In other words, if you shove all of your traffic
to it immediately, and it's running with one unit of power,
and it needs 100, then it's going to just fall over and die,
and not scale up.
So be careful how quickly
you hit load balancers with new traffic.
The same goes with DNS.
Give them time to scale up,
and give the load balancer itself time to scale up.
You don't want to take down
the load balancer with new traffic.
So take it a little slow, during the deployment.
Also, this one has bitten me so many times,
if you get into a failure case where you deploy new code
and then your service just falls over and dies,
and then the fact that it falls over and dies
means it's serving no traffic, no traffic means no load,
and that will cause the system to scale down.
And sometimes, I've had it scale down to zero.
Then I do a revert, but it's at zero, so it never comes up.
So it never gets any load, so it doesn't scale up.
I call this a pathological inheritance.
So put safeties in your code to say,
don't inherit crazy scaling conditions.
And most importantly, get something small working.
Have some fun, and get a theme that actually works
in your environment, then build on top of that.