
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:00 Docker Compose Watch.
00:00:03 As its name suggests, Docker Compose Watch listens to our changes and does something like rebuilding our app, rerunning the container,
00:00:13 and more.
00:00:14 It's a new feature that automatically updates our service containers when you work.
00:00:20 So what specific things can we do?
00:00:23 With Docker Compose watch, we can do three main things.
00:00:28 First of all, we can sync.
00:00:30 The sync operation moves changed files from our computer to the right places in the container, making sure that everything stays up to date in real time.
00:00:42 This is handy when we're working on any app because it lets us instantly see any changes we make while the app is running.
00:00:51 The second thing Docker Compose Watch can do is rebuild.
00:00:56 The rebuild process starts with the creation of new container images and then it updates the services.
00:01:03 This is beneficial when rolling out changes to applications in production, guaranteeing the most recent version of the code is in operation.
00:01:13 And finally, it can perform something known as a sync restart.
00:01:17 The sync restart operation merges the sync and rebuild processes.
00:01:22 It begins by syncing modifications from the host file system to the container paths and then restarting the container.
00:01:30 This is beneficial during the development and testing of applications, ensuring that the most recent code version is active with immediate reflection of
00:01:40 changes in the running application.
00:01:42 And in simple terms, Docker Compose FileWatch is a cool tool that keeps our cooking ingredients up to date while we're in the kitchen.
00:01:51 To make sure it works properly, we need to tell it how to build each meal.
00:01:56 Of course, by defining the build section in our Compose YAML file.
00:02:01 This way, when we tweak a recipe or make changes to our application, Docker Compose FileWatch knows how to update the meal,
00:02:10 or in this case, the service container.
00:02:13 To see it in action, I have created a basic Mearn project.
00:02:17 So first, download the starter code from below this course, then rename it from starter to just Mearn Docker.
00:02:26 and you can see that this is your typical full-snack application.
00:02:30 It has the front-end, which is a React application, and a back-end, including a database.
00:02:36 Now, I'm going to teach you how to Dockerize it.
00:02:39 As you can see, we're Dockerizing everything from vanilla files over to React, Vite, Myrn, and later on, even Next.js.
00:02:48 I want to fulfill the promise of this video, and that is to teach you how to Dockerize any application.
00:02:55 So let's start creating our first Docker files.
00:02:58 You know the drill, don't you?
00:03:00 I will begin by creating a new Docker file for the front-end repository.
00:03:06 And here, we can essentially paste everything we already had within the React project, because this is not going to change much.
00:03:13 So let's copy it and paste it right here.
00:03:16 Now, just to make sure that this is a bit clearer and simpler to understand, we can also remove the comments, as now we know what most of these commands do.
00:03:25 So let's remove all of the comments and then we're going to have a much cleaner working environment.
00:03:31 There we go.
00:03:32 And in this case, as you already know, doing this ad group ad user, it's just an extra step to make to add more safety to our container.
00:03:41 but it's not necessary.
00:03:43 So in this case, we can even comment out these two commands as well as these three commands.
00:03:50 So that leaves us with something like this.
00:03:52 Get the from image, set the working directory, copy it, run it, copy the entire app that got installed after running npm install,
00:04:01 expose it, and run it.
00:04:03 This is a simple Docker file for our React application, and now we have it within our frontend directory.
00:04:10 Don't forget that we can also add a .dockerignore, which is going to just ignore node underscore modules.
00:04:19 And this entire Docker file, we also have to have it for the backend because it's going to be another container.
00:04:25 So here we can create a new file called Docker file and paste everything we have here.
00:04:32 We can modify it slightly though, because this time we want to expose it on a different endpoint, such as 8,000. And we also are going to run it by running
00:04:42 npm start, not npm run dev.
00:04:45 That's it.
00:04:46 We can also add a .dockerignore and add the node modules because we want to ignore them on the backend side as well.
00:04:55 So now we have everything we need besides one thing.
00:04:59 One thing that ties those two services together.
00:05:02 And that, my friends, is the compose.yml file.
00:05:07 This allows us to specify everything we want to do with this specific Docker Compose application.
00:05:13 And I really took my time to comment this one file in its entirety so you can know exactly what each line does.
00:05:22 So below this course, you can find a complete Compose YAML file for the Merin application.
00:05:28 Copy it and paste it here.
00:05:30 It's about 100 lines long, but it only has about 10 to 15 runnable lines.
00:05:35 Everything else is just comments.
00:05:38 But I wanted to go over the comments with you so we can fully understand how to create a bit of a more complicated YAML file that runs three different services.
00:05:48 Web, which is our front-end application, API, which is our backend, and the database at the same time.
00:05:56 So let's dive deeper into this together.
00:05:59 First, we have to specify the version of Docker Compose.
00:06:03 This is not a version of Docker.
00:06:05 This is just a version of the Docker Compose file we're using.
00:06:08 In this case, 3.8 is fine.
00:06:11 Or if you're using some newer Compose features, then you want to bump it up according to the documentation.
00:06:17 Next and most important step is to define the services and containers to be run.
00:06:23 You do that by saying services, and then you define individual services.
00:06:27 In this case, we're defining the frontend service.
00:06:30 You can use any name, but a standard naming convention is to use web for the frontend.
00:06:36 So as we move to this file, I'm going to remove the comments to show you that indeed it is much simpler than it looks like with all of those comments.
00:06:44 We're going to dive deep into web soon, but for now I have collapsed it for you to see the general structure.
00:06:51 Then we define the API or the service container, and then we define the DB service.
00:06:57 Finally, we define the volumes to be used by the services, and here we create a new volume of a name anime, as this app is going to be about showing anime shows.
00:07:08 So looking at this from a high-level overview, we have the version, we have the services, and we have the volumes.
00:07:16 So now, let's dive deeper into each one of the services, starting with web.
00:07:22 First, we need to use depends on command to specify that service depends on another service.
00:07:30 In this case, we specify that the web depends on the API service.
00:07:35 This means that the API service will be started before the web service.
00:07:40 Okay, that's important because to be able to use our front-end application, we need to be able to have the API loaded.
00:07:48 Then, we specify the build context for the web service.
00:07:52 What this means is simply, hey, tell me where the Dockerfile for this service is located.
00:07:57 In this case, it is in dot slash frontend.
00:08:01 Then, we specify which ports to expose.
00:08:04 The first number is the port on the host machine, and the second one is the port inside the container, and we use a concept known as port mapping.
00:08:13 Then you can specify any environment variables.
00:08:16 This is pretty simple.
00:08:17 We simply expose the Veed API URL to localhost 8000. And then everything below is for the Docker Compose watch mode.
00:08:26 Anything mentioned under develop will be watched for changes by Docker Compose watch, and it will perform the action that's mentioned here.
00:08:36 So we say develop, and then we specify the files to watch for changes.
00:08:41 We watch for path frontend package JSON, and then rebuild the container if there are any changes.
00:08:47 Similarly, we watch for package lock JSON, and then perform the action of rebuild whenever something changes.
00:08:55 We also want to listen for the changes in the frontend directory, and then we simply call the sync action with this one.
00:09:02 And this is it for the web service.
00:09:04 Diving into the API, it's similar.
00:09:07 We defined that the API service depends on the database service.
00:09:11 We specify the build context for the API service.
00:09:14 We specify the ports to expose and do port mapping.
00:09:18 We specify the environment variables, in this case, the DB URL.
00:09:23 And finally, we establish the Docker Compose watch mode for the API service by specifying the files to watch for changes.
00:09:32 Same thing as before in the package.json and package.log.json, and then watches for changes and then syncs it across the entire application.
00:09:42 And finally, we have the database.
00:09:45 Here, we want to specify the image we want to use for the DB service from the Docker Hub.
00:09:51 If we have a custom image, we can specify that in this format.
00:09:55 In the above two services, we're using the build context to build the image for the service from the Docker file.
00:10:02 So we specify the build as dot slash frontend.
00:10:05 or build is dot slash backend.
00:10:08 This is interesting.
00:10:09 So we're not referring to existing images, rather, we build our own images from Dockerfile as we learned before.
00:10:16 But in this case, we are using image from the Docker Hub, so we specify it as image mongo add latest.
00:10:23 You can find the name and the tag.
00:10:25 And of course, all of this is available on the Docker Hub.
00:10:28 You can just explore the official images.
00:10:30 So we use it.
00:10:32 We specify the ports and do port mapping.
00:10:36 And generally, you want to put the ports to your MongoDB Atlas here.
00:10:39 But for demo purposes, we can use a local MongoDB instance.
00:10:44 and usually MongoDB runs on port 27017, so we're exposing that port and mapping it to the port inside the container.
00:10:52 How would you test this out locally to see if the database is live?
00:10:55 Well, you can use a tool called MongoDB Compass.
00:10:58 Finally, we specify the volumes to mount for the DB service.
00:11:02 In this case, we want to mount the volume named anime inside the container at data.db directory.
00:11:09 This is done so that the data inside of the MongoDB container is persisted even if the container is stopped.
00:11:17 And this is it.
00:11:18 This is how you create your first YAML compose file.
00:11:22 It's not that hard, is it?
00:11:24 It's not that easy either.
00:11:25 This is your first time, but trust me, you will get better.
00:11:28 But this is a YAML file for already a pretty big application with three separate services.
00:11:34 You can try building your own that is much simpler.
00:11:36 And as a matter of fact, we have already done that in the last project where we have a really simple, just a web service in here.
00:11:44 So now we have stepped up our game a bit and we're doing it for a complicated app to show you the beauty of Docker Compose File Watch.
00:11:52 So, remember, we're building three different images and containers through one file and one command.
00:12:00 That's power of Docker Compose.
00:12:02 And on top of that, we're using Docker Compose FileWatch to automatically build and run these containers if we make any changes to the application.
00:12:13 So, let's open up our terminal cd into murn-docker and run sudo docker compose up and press enter.
00:12:26 enter your password, and see the magic happen.
00:12:30 It's going to run all the services one by one.
00:12:34 Notice that first it created our DB image and container.
00:12:38 Then it's going to start working on the API, and we can see that here.
00:12:43 And finally, it's going to move over to our web application exactly as we have specified in our YAML file.
00:12:51 So let's leave it do its thing.
00:12:54 There we go.
00:12:55 After about a minute, we can see that the process has finished by this long log file right here.
00:13:02 Don't worry, it's not an error.
00:13:04 Rather, you can see that it successfully containerized all three different applications, the DB, the API, and the web, and attach them together.
00:13:15 If we go back to Docker Desktop, we can see that right here.
00:13:19 If we go to Docker Desktop, we can see that right here.
00:13:23 We have the Myrn Docker Web, Myrn Docker API, and Mongo.
00:13:28 We also have three different containers under Myrn Docker right here, DB, API, and Web.
00:13:36 And we also have the specified volumes.
00:13:39 So now that we have this running, let's open up our browser and navigate to localhost 5173. There we go.
00:13:48 We have a fully functional marine application running on your device locally without you having to spin up the database,
00:13:57 the front end, in the back end, and inputting all of these environment variables manually.
00:14:02 It just works.
00:14:04 That's the power of Docker.
00:14:06 What we have here is a simple application where you can share your favorite anime.
00:14:11 So go to Share, enter the name.
00:14:14 I'm going to do something like My Hero Academia.
00:14:17 You can also enter the link and you can also enter a description.
00:14:22 Finally, click Submit.
00:14:24 That's it.
00:14:25 If you refresh, you can notice that it stays there and this entry actually got added to our database.
00:14:32 Before Docker, we would have to have two or three terminals open running front and back in the database at the same time.
00:14:39 Now it's just one command and we have our app running in real time.
00:14:44 But now let's try to make some changes.
00:14:47 If I go right here and navigate to our front end part of our application, as that's the easiest to notice, we can go to app.jsx and right in our nav bar,
00:14:57 let's try to add a new link by duplicating this one and say something like popular.
00:15:05 If we save it and go back and reload, nothing changes.
00:15:10 So how can we ensure that the updates happen automatically and in real time?
00:15:16 Back in our code, we can open up a terminal and then split it to create a new one alongside it.
00:15:23 There, we can run the command sudo docker compose watch.
00:15:29 We're finally getting to the watch part.
00:15:31 If you press enter and enter your password, you'll see that something will start to happening.
00:15:38 It looks like it's starting with the watch configuration.
00:15:41 So now, if I save this file right here with popular included, Go back to the browser and reload.
00:15:48 Indeed, Popular is there.
00:15:50 And you can see that if I save the file, something happens here.
00:15:54 There's an update happening in real time.
00:15:56 So if I change it, save it, and go back, it's updated in real time.
00:16:02 Now, let's remove it.
00:16:04 And let's try to test whether this works for the backend as well.
00:16:09 We can do a quick test by installing a simple package called colors.js.
00:16:14 That's just MPMI colors, and it allows you to change the colors in your terminal.
00:16:20 With this, we'll very easily be able to see whether the package got installed or not.
00:16:25 So back in our code, we can navigate to our package JSON of the backend part.
00:16:32 And using our terminal, we can install the package.
00:16:35 So let's split the terminal one more time.
00:16:38 CD into backend.
00:16:40 And then let's run npm install or npm i callers.
00:16:45 This is going to add it.
00:16:47 We can kill this terminal in the middle.
00:16:49 And immediately you can see that something started happening on that watch part.
00:16:55 It looks like it's listening to it and rebuilding the entire application with this project installed.
00:17:01 That's great.
00:17:04 Let's also explore the code a bit.
00:17:06 Right here in the index, you can see that we are enabling this callers package coming from callers.
00:17:13 And we are also logging it out in a rainbow of caller whenever we go to localhost 8000. So back in our browser, let's simply re-navigate to localhost 8000.
00:17:26 We get a hello world here, but we're more interested in this hello world here, because this one means that the package got successfully installed.
00:17:37 There we have it.
00:17:38 Without a refresh, rebuild or rerun, our application works in real time with the help of Docker Compose Watch.