Complete Intro to Containers (feat. Docker) Containers & Dev Environment
Transcript from the "Containers & Dev Environment" Lesson
>> The last section that we talked about was volumes, okay? And hopefully that was helpful for you, and we're gonna get in today for using containers in your development environments. And I think this is actually one of the most compelling reasons for developer populous at large to learn containers, and that's actually why I put this in here.
[00:00:17] So we're gonna go through two different scenarios. The first one I'm gonna show you how to use dev containers outside of Visual Studio Code, just because I know all of you don't use digital studio code yet. [LAUGH] I'm coming for you. So I'll show you how to do that first.
[00:00:34] And then after that, I'll show you how to do it with Visual Studio Code and how VS Code will actually make that really easy. And then, lastly, we're gonna go over networking before getting into multi container projects. All right, so go ahead and let's go into Using Containers for your Dev Environment.
[00:00:49] That's what we're gonna go into now. So we've kind of explored this idea of it's really difficult when you start at a new company, that it's difficult to get up and running quickly at a new company, right? And so that's where dev containers can be very useful, right?
[00:01:09] It'd be useful if they could just hand you a Docker file and say, hey, here's what our developer environment is. If you just click start here, then everything just spins up and starts working right away, right? That's pretty compelling, right? I remember at one of the startups I worked at before I worked at Reddit, I had to start up a developer environment.
[00:01:29] And it probably took me the better part of two or three weeks just to get everything working right. I'd be in a specific version of the JVM, and then it had to be a specific version of npm to get that version of Angular working. It was a Rube Goldberg machine of human suffering, let's put it that way.
[00:02:00] It can just work for you, okay? So I imagine many of you have probably heard of Hugo. It's a very, very popular static site generator, comparable to Gatsby or Jekyll or something like that. It's great, lots of people use it. I think Frontend Masters uses it on their website, right?
>> Cool, see? So you've already used a Hugo website recently, or maybe currently. [LAUGH] Probably currently, that's cool, right? But I don't know how to set it up. I've never had to set it up for myself, because I'm not a Go developer. I haven't necessarily messed around with it.
[00:02:34] But I'm gonna show you just using containers that we can do all this kind of ourselves. So let's say that you're joining this new team, it's a Hugo team, and your new project is here. So I have a link here and it's gonna link to a GitHub repo, which is on my GitHub.
[00:02:47] And we're gonna set up this project together, despite the fact that many of you, I imagine, don't know how to use Hugo, okay? So we're gonna use this container here called hugo-builder. And I don't know this person necessarily, but they created this container, hugo-builder right here, that allows us to run Hugo inside of a container.
[00:03:13] And we're gonna use bind mounts in a clever way to be able to build our project. Okay, so here, you probably won't see this, but apparently I have some Go vulnerabilities I'm not gonna fix, cuz it's not a real project. [LAUGH] Okay, and so here's the project. And what we're gonna do now is we're gonna run git clone right here.
[00:03:33] So you can go ahead and copy that. And I'm here in my intro-to-containers project. If you look here, I have all the other projects in here, and I'm just gonna say git clone github btholt/hugo-example. Okay, I'm gonna go into hugo-example. And we're gonna say docker run --rm -it --mount.
[00:04:02] To use our bind mounts, I'm gonna say type=bind,source="$(pwd)" like this, so that we can get the current working directory. I'm gonna say target=/src. And then we're gonna say -p 13 13:1313 cuz that's the port that it's gonna be listening on, -u hugo, and then you have to put the name here.
[00:04:44] So, jguyo, like that. /hugo-builder. Again, you can totally just copy this right off of the notes as well. And then we're gonna pin it to a specific version, just to make sure this keeps working, so 0.55. So we've done everything so far. This is gonna drop us into the container, and now we can give it a command for us to run.
[00:05:11] So the command that I want it to run is hugo server, which is gonna be like the development environment, right? hugo server -w --bind=0.0.0.0. So the bind part is so that it's available externally, not just internally, it's the container. So now, hopefully, if we run this. Mine's gonna say can't find this, so it's gonna go out there and pull some of these.
[00:05:40] It looks like it's gonna be maybe 20 megabytes worth of stuff for me. And this already exists here. This is probably something like Ubuntu or Alpine that I already had on my computer, right? And here you go. Now it's running, and it's running on local host 1313. So here is a Hugo website with some random theme, I don't even know what theme it is.
[00:06:13] [LAUGH] Working, right? We got this all up and running with a Go project with Hugo and all that kind of stuff running, with no knowledge of it. Like totally black box of how it's working internally. And if you're a CSS developer or designer or something like that, you can just go in and mess with the CSS and you don't have to really know and understand how Hugo's working under the hood.
[00:06:33] You can let the other team that handles that part of it, just say here's the Docker file. As long as you're in the Docker file, everything just works, right? So I think this is compelling for teams and for your personal projects, right? Like say you have some Bespoke environment that you need to export with your project for it to work.
[00:06:51] You can just set all that stuff up, and then someone can come in and they just run the container and everything works. Yeah?
>> Yeah, that's literally what we do at Frontend Masters. This is how it works.
>> Yeah, we have Hugo and Go, and everything is in a container.
[00:07:06] And so you just build the container and start working.
>> There you go, this is now officially dubbed the Frontend Masters architecture. [LAUGH] I think it's great. And Hugo is a pretty simple example of this. I imagine most people here could set up Hugo on their own. I did make that project, right?
[00:07:26] So it didn't take me that long. But I'm sure you could imagine some very difficult, maybe like JVM sort of thing that's difficult to set up. And all of those things could be combined into a container, or multiple containers, and makes it very easy to share. Do you have a question?
>> So with that approach, if I send somebody the Docker version so they can run locally, is this also mitigating the need to install package? Like when you get a pull down repo like we just cloned this one, usually do a Yarn or npm install. Do we bypass that, just deal with the container route?
>> So I'm gonna show you how to do this with VS Code here in just a second, and it'll take that even a step further. In general, it's good to have fresh dependencies, right, because things are constantly updating. And it's like, maybe it's like, I don't know, let's say, Lodash releases a version that breaks and it's a patch version.
[00:08:20] You wanna catch that in development, right? There's trade offs there that you need to make, I guess. So it can, right, you can totally bake everything into it. But what's cool about this, and coming kinda back to your point, if I come back in here and I look at my Go project here, hugo-example.
[00:08:44] So if I come here. I think, anyway, I can't remember how you do this. But what's great about this is, I'm not actually live editing, right? Because it's using a bind mount that's shared with my host, right? So if I start typing things, it's gonna be modifying the things that are in the container as well, right?
[00:09:07] So it can, it can mitigate that, but you just have to make your decisions of how you want that to work. So actually coming back to the point of dependencies here. If I do an npm install on my local computer and then I bind mount that into Ubuntu to to be run, we still have that issue of native dependencies, right?
[00:09:26] So if I build Node-sass for Mac and then I try and run it in Ubuntu, it's not gonna work, right, cuz it was built for Mac. So we have this kind of issue that we have to bind mount into the container, and then afterwards run npm install. Because it needs to be npm installed within the container.
[00:09:44] So you can burn them in, which is what you suggested. And you just export the container with the dependencies already hard built in. But that kind of sucks a little bit because if I run npm, it's like if I install another dependency afterwards, which is frequently what Node developers are doing, we have the same problem again.
[00:10:01] So there's a couple ways you can do it. If you're doing it this way without Visual Studio Code, the way that I usually do it is I just attach to the running container, and I run npm install for the first time. And then after that, it's usually okay, right?
[00:10:15] You just kinda have to do that every time that you restart up the container. It's annoying, but it works. And moving into Visual Studio Code, which it's just smart enough to say, I'm pretty sure you're gonna need to do an npm install and it just does it for you, so.
[00:10:27] But we'll get there, just a second.