[GDD] Orchestrating Containers (Part 2 of 5) 25 November 2017

I’m so excited for your journey. Still have some awesome stuff coming up in the free course, and even more beyond that!
 
I've been working really hard on these courses.
 
My original goal was to teach Microservices, but I realized that I couldn't tell that story without DevOps.
 
This course teaches you the fundamentals you need to be a part of the DevOps world, and the DevOps world is in a beautiful renaissance.
 
 
GitOps is a favorite subject of mine.
 
DevOps, in my opinion - GitOps being the best flavor, is the prerequisite for microservices.
 
"With simplicity of the services, some complexity necessarily moves to the architecture"
 
 
If you think anything we've done so far is powerful, what's yet to come  is gonna blow your mind.
 
 
🤯🤯🤯
 
 
We haven’t even scratched the surface of how powerful this stuff is.
 
Let me give you a taste:

 
Image if running `npm install rabbitmq` set up a production ready, highly-available, rabbitmq deployment in your production system.
 
 
Wouldn’t that be amazing?
 
 
How much time do you think you’d save?
 
 
Is it even possible for it to be so simple?
 
 
Hint: Yes. But it’s not npm that will give you that power (or an AWS certification.. lol 😂)
 
 
NOW…
 
For today…
 
 
I’m also excited for you, because I want to reveal my “productivity hack” I told you about earlier on.
 
 
So many tutorials on the internet get this wrong.
 
 
That is - the proper way to handle Development Orchestration.
 
 
This enables you to onboard new engineers with a single command.
 
 
No more “it works on my machine”.
 
I've even had engineers COMMIT TO MASTER AND DEPLOY TO PRODUCTION ON THEIR FIRST DAY.
 
How long do you spend on onboarding? How long did it take you to get code to production in your current gig?
 
Anyway...
 
 
Yesterday I showed you how to orchestrate the production ready container we built.
 
version: '3.4'
 
services:
 
 my-container:
  image: my-container
  ports:
   - 3000:3000
 
While this is perfectly valid for running a built container, you lose out on all of your development tooling!
 
No hot reloading, hell, you can’t even make changes and hit refresh!
 
Not great for a development workflow.
 
Actually, quite bad, haha. 😂
 
Luckily, it’s an easy fix.
 
Many tutorials will tell you that you need to create a development version of your Dockerfile. `Dockerfile.dev` or similar.
 
I’m telling you, this is SO very wrong.
 
Instead of making a Dockerfile which adds all of your code, I want to reframe your ideas on what a container can be.
 
This is also exactly how I started making containers.
 
Here's how you should look at docker containers:
 
An environment that you can place your code into to run.
 
I think that may sound a bit confusing still, so let me break it down.
 
Right now, on your dev machine, you probably have some tools installed. 
 
Python, Node, Ruby, Java, maybe MongoDb… whatever the tools are required to run your code.
 
When you run your code on your machine, it works, because you’ve configured your environment.
 
Containers work the same way.
 
For production, we want to seal the box so it won’t break open while being shipped, but, while it’s in development, we can leave the box open.
 
To do this, instead of using a Dockerfile to build a custom image, we will just use a generic environment, and place our code inside of it to run using a volume.
 
version: '3.4'
 
services:
 
  my-container:
    image: node:10
    volumes:
      - .:/usr/src/svc
    working_dir: /usr/src/svc
    ports:
           - 3000:3000
    command: bash -c "npm i && npm run dev"
 
Now, when we run `docker-compose up`, our current directory will be mounted into the `node:10` container. The command is then executed, which will install the npm dependencies, and then start the app in dev mode.
 
The `volumes` key in the config file above is where that magic happens. Your current directory '.' is mapped to /usr/src/svc in the node container. We then set the working dir to /usr/src/svc (which now has our code from .) so commands are executed in the container using the code from our local machines!
 
We set that command to be "npm i && npm run dev". More specifically, to use bash to call that command. In this case, we are installing the npm dependencies into the blank container, and just running it in dev mode.
 
Changes in your local system are then synced with the volume in the container, causing any `watch` statements to trigger.
 
And that’s all there is to it!
 
If you're astute, you may notice that we could actually break this task into multiple steps because our local file system keeps the state between the steps.
 
Let's not worry about that for now though!
 
We are far from done with our orchestration journey!
See You Tomorrow,
Patrick “knows something” Scott