Check out a free preview of the full Complete Intro to Containers (feat. Docker) course

The "Dockerfiles Preamble" Lesson is part of the full, Complete Intro to Containers (feat. Docker) course featured in this preview video. Here's what you'd learn in this lesson:

Brian demonstrates how to create a Dockerfile, adds a series of instructions in the Dockerfile that will give information about how the container should run, and how to tag a container and run it.


Transcript from the "Dockerfiles Preamble" Lesson

>> Let's get into intro to Dockerfiles, so, so far everything that we've been focused on with regards to Docker has been on running existing containers, right? Which again, for engineers and developers, it's probably most of what you'll be doing with containers, right? But it's also I think, useful to know how to build containers, there's a bunch of different ways to do it.

Let's call it the most common and my opinion best way of doing it is with Dockerfiles. So there's actually like a file format called Dockerfile and Docker reads this and then it uses that to build containers for you. So let's just jump right into it and start building something, all right?

So somewhere on your computer I'm gonna go into, let's go into personal, and I'm gonna make a directory called intro-to-containers, okay? I'm gonna change directory into intro-to-containers, I'm going to open my VS code into intro-to-containers. So right now I have just an empty directory that we're gonna start making some projects together, and again, there is a GitHub repo out there that I've created.

GitHub btholt projects for complete intro-to-containers, this exists out there, this has all of the files that I'm about to do, it also has like the truancy groups and all those like it has those as a shell file. So for example, we're about to do Dockerfiles, so as you may imagine, there's a directory called Dockerfile, click on that.

And on behold there's a Docker file in there, right? So if you get behind or if you don't feel like typing them or something like that, it's all there, and I try to make it pretty self evident what goes where, right? So if I go here into intro to Dockerfiles, right?

This is Dockerfile, I try to call it the same thing so that if you go over here it's also called Dockerfile. So again, I'm gonna be using Visual Studio code, again, I work on it, so I like it, I also think it's a really great editor, so you should definitely use it but you also don't have to.

I will just be very sad, so, I'm just gonna make all my projects in here, I'm gonna make a directory called dockerfile, cd into dockerfile. And here, now that we have a directory, Intro-to-Containers, so you can see here I have a dockerfile directory, create a new file in here and it's gonna be called Dockerfile.

And I get a nice little, well right there, so we have a Dockerfile, right? So what we're going to create here is we're going to create a file that Docker is going to read, and it's going to use that to build a container for us, right? So it's a series of instructions, right?

Do this, then do this, then do this, then do this, it's very procedural in that particular way. And literally each line is called an instruction, right? That's why I say, use instructions, because that's literally what it is, so we're gonna make like the most basic node, Dockerfile ever.

So, the first thing you need to start out with is a base container, so you say, FROM, I get nice auto-completion, thanks VS code, pat myself on the back. I didn't do it so I don't know why I'm doing that, FROM, and then you start with some base level container.

So we're gonna start with one of them that we've already been using, so I'm gonna say, FROM node:12-stretch So it knows it's gonna go out to Docker Hub, it's gonna find our node stretch container, and that is the starting point for this, right? So we know that this has node installed in it, we know that it has npm installed on it.

We know that it has some other features like they've already created a node user for us there's a bunch of stuff in there, right? Bunch of goodness I'm going to suggest like if you're doing a node container, right? Like a node project, start with something like this, right?

It doesn't necessarily have to be this one, there are other ones out there, I think, Node Source makes one. There's another company that I'm just blanking on the name but there's a bunch of them that make really good containers. Okay, and then the next thing in here, I'm just gonna tell it to do something whenever it starts up, right?

So I'm gonna say, CMD, and then you tell it what to do when it starts up, and you give it an array of things, right? So in this case, I'm gonna say, node, we want it to run node, then we're gonna give it the flag of -e. And now we're gonna say, run console.log, we have to escape these.

There we go. So -e just means immediately execute this string of code right here, so it's actually feeding this in as if it was like the file that node's gonna run for you, right? So as you might imagine, this is just gonna run hi. So, just to show you, if I say node -e, Then I do that here.

Hopefully that's unsurprising what that was supposed to do, right? That's what the -e does, right? Just wanted to show you that, because most people probably don't execute their code that way, and I can't see why not. I'm just kidding, it's a terrible idea, don't do that [LAUGH] all right, so that's it, right?

This is probably the most basic node application you could write in a dockerfile. Now, if you remember, if you just run node stretch directly, it just drops into the ripple, right? So it has its own CMD in there, so that's how CMD works, it takes the last one that it found, right?

So this is the last CMD that it finds so it executes this one, it overwrote the one that was previously there, right? So if I have one underneath here that says, I don't know, right, it will do this last one, now, vs codes gonna say, you have CMD in here twice.

Why? Why would you do that to yourself? Right? So thanks VS code, but we'll just get rid of that line and we'll do it like this, all right, so I'm gonna open my CRI here. And I mean this particular file, and I'm gonna say docker build, and just tell where the docker file is, as soon as you need the dockerfile you can tell it something else if you need to.

Let me say docker build., dot mean right here, right? And look for the Docker file in this directory. Okay, so it's gonna say FROM node:12-stretch, most of us probably still have that on our computer, right? So it'll immediately do that, and then it builds another layer on top of that, which is this command that we do and then it built this container right here with this name.

So I'm gonna say docker run-it, or actually we don't even have to do the it, you can say docker run that. And there you go, we just ran our first container that we've created. And I feel like this was really important for everyone to see, probably the best container ever, definitely the best container ever, all right.

How do you feel about that? Makes sense? Good so far? Cool.
>> CMG is nine, zero, it's not required for dockerfile, but it's a useful thing, otherwise, it's going to default to whatever.
>> Whatever the previous from is, right? And you can make containers that are like are designed to have execute, right?

Cuz I can still do Docker run this and I can do LS, right? And it'll overwrite that, that's CMD in there, right? That's all that this does right here, is it overrides whatever the CMD is, so you can build containers that are designed to have commands filtered into them, right?

So it make sense? Okay, cool. So it's annoying that I have to say number here, right? Like it'd be better if there was like name for it, so let's do that, so docker build. And again, the order here is quite important, we're gonna do -- tag my-node app.

Now it's gonna be instant cuz it's the exact same Dockerfile so everything already exists. It still is caching all those layers for you, right? So it doesn't redo the same thing. And so now I have my-node-app: latest, which it automatically puts that tag on there for us. That it all just works.

>> Do we have to specify the version number or is it always gonna be latest?
>> If you don't specify it, It will give you latest, if you do specify it then it wiil.
>> Is there a good practice for that?
>> You should version your containers, yeah.

But as you can see tags are the wild west, right? You can name them whatever you want and like lots people have various different strategies. But I guess the key there is, we just wanna be obvious about what people are getting, right? That's what they expect. So, let's actually even do that right now, well, just to show you, docker run my-node-app, This now works right?

But let's say I did this again and we're gonna build it and I'm gonna put :1, right? So this is the tag, then I successfully tag this as my-node-app:1. Now let's go change this, so it says, let's go back to rofl because that was enlightening as well. Philosophy according to Brian, and we're going to put in there 2 now instead of 1.

So now I can come in here and say docker run my-node-app: 1, and I'll get omg hi lol and if I do 2, I'll get rofl, so that's like the most basic intro-to-dockerfiles, right? That's showing you how to tag them, how to build them, and the most basic set of instructions, right?

All of them are gonna have a FROM, most of us are going to be building our own base images and don't ask me how to, cuz I've never done it myself. I've never needed to, right? I've never needed to build my own Ubuntu. Canonical is much better building Ubuntu that I am, just like mildly better than I am, that's, that's a joke, Canonical makes Ubuntu I think they're a lot better at it than I am.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now