
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.
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.
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 Let's Dockerize our first React application.
00:00:03 I'm going to do that by quickly spinning up a simple React project by running the command npm create vt add latest and then react-docker as the folder name.
00:00:16 If you press Enter, it's going to ask you which flavor of JavaScript you want.
00:00:21 In this case, let's go with React.
00:00:23 Sure, we can use TypeScript.
00:00:25 And we can now CD into React-docker.
00:00:29 And we won't run any npm install or npm run dev because the dependencies will be installed within our Dockerized container.
00:00:38 So with that said, now, if we clear it, we are within React Docker, and you can see our new React application right here.
00:00:46 So as the last time you already know the drill, we need to create a new file called Docker file.
00:00:52 As you can see, it automatically gets this icon.
00:00:55 And it's going to be quite similar to the original Docker file that we had, but this time I want to go into more depth about each of these commands so
00:01:03 you know exactly what they do.
00:01:06 And because of that, below this course, you can find a complete Docker file for our React Docker application.
00:01:13 Copy it and paste it here.
00:01:16 Once you do that, you should be able to see something that looks like this.
00:01:20 It seems like there's a lot of stuff, but there really isn't.
00:01:23 It's just a couple of commands, but I wanted to take my time to deeply explain all of the commands we're using right here.
00:01:31 So let's go over all of that together.
00:01:35 First, we need to set the base image to create the image for React app.
00:01:40 And we are setting it up from Node 20 Alpine.
00:01:44 It's just a version 20 of Node.
00:01:46 You can use any other version you want.
00:01:48 And in these courses, I want to teach you how to think for yourself, not necessarily just replicate what I'm doing here.
00:01:55 So if you hover over the command, you can see exactly what it does.
00:01:59 Set the base image to use for subsequent instructions.
00:02:03 From must be the first instruction in a Docker file.
00:02:06 And you can see a couple of examples.
00:02:08 You can use a from base image or you can even add a tag or a digest.
00:02:13 In this case, we're adding a tag of a specific version, but it's not necessary.
00:02:18 And if you click online documentation, you can find even more instructions on exactly how you can use this command.
00:02:25 Next, we have to play with permissions a bit.
00:02:28 Now, I know that these couple of commands could be a bit confusing, but we're doing it to protect our new container from bad actors and users wanting to
00:02:37 do something bad with it.
00:02:39 So, because of that, we create a new user with permissions only to run the app.
00:02:45 The .s is used to create a system user, and .g is used to add that user to a group.
00:02:52 This is done to avoid running the app as a root user that has access to everything.
00:02:58 That way, any vulnerability in the app can be exploited to gain access to the whole system.
00:03:03 This is definitely not mandatory, but it's definitely a good practice to run the app as a non-root user, which is exactly what we're doing here.
00:03:11 We're creating a system user, adding it to the user group, And then we set the user to run the app, user app.
00:03:19 And you can see more information about right here.
00:03:21 Set the username to use when running the image.
00:03:25 Next, we set the working directory to forward slash app.
00:03:28 And then we copy the package JSON and package log JSON to the working directory.
00:03:34 This is done before copying the rest of the files to take advantage of Docker's cache.
00:03:40 If the package.json and package.log.json files haven't changed, Docker will use the cache dependencies.
00:03:46 So copy files or folders from source to destination in the images file system.
00:03:54 So first you specify what you want to copy from the source, and then you provide a path where you want to paste it to.
00:04:01 Next, sometimes the ownership of the files in the working system is changed to root, and thus the app can't access the files and throws an error,
00:04:10 e-access permission denied.
00:04:12 To avoid this, change the ownership of the files to the root user.
00:04:17 So we're just changing it back from what we did above.
00:04:19 Then we change the ownership of the app directory to the app user by running a new command, in this case chown, where we specify which user and group and
00:04:30 directory we're changing the access to.
00:04:32 And then we change the user back to the app user.
00:04:35 And once again, if these commands are not 100% clear, no worries, this is just about playing with user permissions to not let bad actors play with our container.
00:04:44 Finally, we install dependencies, copy the rest of the files to the working directory, expose the port 5173 to tell Docker that the container listens on
00:04:54 that specified network, and then we run the app.
00:04:57 If you want to learn about any of these commands, hover over it, you can already get a lot of info, and then go to online documentation if you need even more.
00:05:06 With that said, that is our Docker file.
00:05:09 Another great practice that we can do is just go right here and create another file similar to .gitignore.
00:05:16 This time it's called .docker-ignore.
00:05:20 And here you can add node underscore modules just to simply exclude it from Docker because we don't really need it in our node modules on our GitHub.
00:05:28 We don't need it anywhere, not even in Docker.
00:05:32 Docker is playing with our package JSON and package log JSON and then rebuilds it when it needs to.
00:05:38 Now, finally, once we have our Docker file, we are ready to build it.
00:05:43 We can do that by opening up a new terminal, navigating to React Docker, and we can build it by running the command Docker build-t for tag,
00:05:53 which we can leave as default, react-docker, which is the name of the image, and then dot to indicate that it's in the current directory.
00:06:02 And finally, press Enter.
00:06:04 This is going to build out the image, but we already know that an image is not too much on its own.
00:06:11 To use the image, we have to actually run it.
00:06:14 So let's run it by running the command Docker run react-docker and press enter.
00:06:21 As you can see, it built out all of the packages needed to run our app and it seems to be running on localhost 5173. But if we open it up.
00:06:31 It looks like this site isn't showing, even though we specified that expose endpoint right here, saying that we're listening on 5173. So why is it not working?
00:06:43 Well, first, we need to understand that expose does only one job, and it's to inform Docker that the container should listen to that specific exposed port
00:06:53 in runtime.
00:06:54 That does make sense, but then why then work?
00:06:57 Well, it's because we know on which port the Docker container will listen to.
00:07:01 Docker knows it, and so does the container, but someone is missing that information.
00:07:07 Any guesses?
00:07:09 Well, it's the host.
00:07:10 It's the main computer we're using to run it.
00:07:13 As we know, containers run in isolated environments, and by default, they don't expose their ports to the host machine or anyone else.
00:07:23 This means that even if a process inside the container is listening on a specific port, the port is not accessible from outside the container.
00:07:32 And to make our host machine aware of that, we have to utilize a concept known as port mapping.
00:07:39 It's a concept in Docker that allows us to map ports between the Docker container and the host machine.
00:07:45 It's exactly what we want to do.
00:07:48 So to do that, let's kill our entire terminal by pressing this trash icon, reopen it, re-navigate to react-docker, and let's run the same command,
00:07:59 docker run, and then we're gonna add a P flag right here, and say map 5173 in our container to 5173 on our host machine,
00:08:10 and then specify which image do we wanna run, and press enter.
00:08:15 Now, as you can see, it seems to be good, but if I run it, same thing happens again.
00:08:22 It's not Docker's fault, but it's something that we missed.
00:08:26 It's Vite.
00:08:27 If you read the logs right here, it's going to say, use –host to expose.
00:08:33 So we have to expose that port for Vite too.
00:08:37 So let's modify our package JSON by going right here, and adding the –host to expose our dev environment.
00:08:47 And now again, we'll have to stop everything, kill our terminal, reopen it, re-navigate to React Docker, and then run the image again.
00:08:57 Which makes you wonder, wouldn't it be great if Docker does it on its own whenever we make some file changes?
00:09:04 And the answer is yes, definitely.
00:09:06 And Docker heard us.
00:09:08 Later in the course, I'll teach you how to use the latest Docker features that allow us to automatically build images and save us from all of this hassle.
00:09:18 But I first want to teach you how to do it manually to understand how cool Docker Compose is, which I'm going to teach you later on.
00:09:26 So let's just rerun the same command.
00:09:30 And now we get an error.
00:09:32 This means that something is already connected to that port.
00:09:36 And this indeed is true if you check out our containers or images.
00:09:41 We have accumulated a large number of images.
00:09:44 So let's do a quick practice on how to clear out all of our images or containers.
00:09:50 Back in our terminal, we can run a command docker ps, which is going to give us a list of all of the current containers alongside their IDs,
00:10:00 images, created status and more, as well as in which ports are they listening on.
00:10:05 This is for all the active running containers.
00:10:09 And if we want to get absolutely all containers, we can run docker ps-a.
00:10:15 And here you can see absolutely all containers that we have.
00:10:19 That's a lot.
00:10:19 Now the question is, how do we stop a specific container?
00:10:23 Well, we can stop it by running docker stop and then use the name or the ID of a specific container.
00:10:31 You can use the first three digits of the container ID or you can use the entire name.
00:10:36 So let's use C3D.
00:10:38 C3D.
00:10:40 And if you get back the same command, it means that it successfully stopped it.
00:10:45 If we go back to containers, you can see that the C3D is no longer running.
00:10:50 But now, let's say we have accumulated a large number of containers, which we indeed have, both the images and containers.
00:10:58 So how can we get rid of all of the inactive containers we have created so far?
00:11:03 Well, we can do that by running Docker container prune.
00:11:07 If you run that, it's going to say, this will remove all stopped containers.
00:11:11 So let's press Y and that's fine.
00:11:14 We only had one that was stopped that we manually stopped and it pruned it.
00:11:19 But you can also use the command DockerRM to remove a specific container by name or its ID.
00:11:26 So let's try with this one, AA7.
00:11:30 DockerRM, AA7, and press Enter.
00:11:34 Here we get a response saying that we cannot stop a running container.
00:11:39 Of course, you could always use the dash dash force and that's going to kill it.
00:11:44 we can verify right here.
00:11:46 These commands are great, and it's always great to know your way around the CLI.
00:11:51 But nowadays, we also have Docker Desktop, which allows us to play with it within a graphical user interface, which makes things so much simpler.
00:12:00 You can simply use the stop action to stop the container, or you can use the delete action to delete a container.
00:12:07 It is that easy.
00:12:09 Similarly, you can do that for images by selecting it and deleting all images.
00:12:15 And you can follow my process of deleting everything right now.
00:12:18 I just want to ensure that we have a clean working environment before we build out our React example one more time.
00:12:25 And while we're here, if you have any volumes, feel free to delete those as well.
00:12:30 There we go.
00:12:32 So moving back, we want to first build out our image.
00:12:36 And now let's repeat how to do that.
00:12:38 You simply have to run docker build dash t, the name of the image, and then dot.
00:12:44 This is going to build out the image.
00:12:47 After you do that, we have to run it with port mapping included.
00:12:51 So that's going to be docker run dash p, map the ports, and then the name of the container you want to run.
00:12:59 And press Enter.
00:13:01 It's going to run it and you can see a bit of a difference right now here.
00:13:04 It's exposed to the network.
00:13:06 And if you try to run localhost 5173, you can see that this time it actually works.
00:13:14 That's great.
00:13:15 But now if we go back to our code, go to source app and change this VEAT and react to something like Docker is awesome and save it.
00:13:31 Back on our local host, you can see that it didn't make any changes.
00:13:36 That's very unfortunate.
00:13:37 We hope that this container could somehow stay up to date with what we are developing.
00:13:43 Otherwise, it would be such a pain to constantly rebuild containers with new changes.
00:13:49 This happens because when we built the Docker image and run the container, the code is then copied into that container.
00:13:57 You can see all the files right here, and they're not gonna change.
00:14:01 So even if you go right here to App and then Source and then App.tsx, right-click it and click Edit File, you'll be able to see that here it still says
00:14:12 Vite plus React.
00:14:14 So what can we do?
00:14:16 Well, we'll have to further adjust our command.
00:14:18 So let's simply stop our active container so we can then rerun a new one on the same port.
00:14:24 Let's go back to our Visual Studio code, clear it, make sure that you're in the React-docker folder.
00:14:31 and we need to run the same command, then we have to also add a string sign, dollar sign, PWD, close it, and then say colon forward slash app and close
00:14:44 it like so.
00:14:46 It seems a bit complicated, doesn't it?
00:14:48 What this means is that we tell Docker to mount the current working directory where we run the Docker run command into the app directory inside the container.
00:15:00 This effectively means that our local code is linked to the container and any changes we make locally will be immediately reflected inside the running container.
00:15:11 This tiny pwd represents the current working directory over here.
00:15:16 It executes in the runtime to provide the current working directory path.
00:15:20 And V, V stands for volume.
00:15:23 That's because we're creating a volume that's going to keep track of all of those changes.
00:15:27 Remember that we talked about volumes before?
00:15:29 They try to ensure that we always have our data stored somewhere.
00:15:33 But before you go ahead and press enter, there's one more additional flag that we have to add to this command.
00:15:40 And that is yet another dash V, but this time, forward slash app, forward slash node underscore modules.
00:15:48 Why are we doing this?
00:15:50 Well, we have to create a new volume for the node modules directory within the container.
00:15:56 We do this to ensure that the volume mount is available in its container.
00:16:01 So now when we run the container, it will use the existing node modules from the named volume and any changes to the dependencies won't require a reinstall
00:16:11 when starting the container.
00:16:12 This is particularly useful in development scenarios where you frequently start and stop containers during code changes.
00:16:20 So let's run it.
00:16:22 It's running on localhost 5173. Docker is indeed awesome, but now the question is, if we change it, what's going to happen?
00:16:33 So we go here and say something like Docker is awesome, but also add a couple of whales at the end, press Save, and then you can see PMVT Update Source
00:16:45 App TSX.
00:16:46 And now if we run it, we have a couple of whales right here.
00:16:50 There we go.
00:16:51 So whenever you change something, you'll see the result instantly in the UI.
00:16:56 That's amazing.
00:16:58 And even if we go back to our Docker desktop, you can see that now we have a volume that keeps track of these changes.
00:17:05 And if you go under containers, go to our active container, go to files, and then let's go to app.
00:17:14 source, app.tsx, and edit, you can see that the changes are also reflected right here.
00:17:20 So that's it.
00:17:22 You have successfully learned how to Dockerize a front-end application.
00:17:27 Not many developers can do that, but you, you're just getting started.
00:17:32 Now that we have created our Docker image, let me teach you how to publish it.