Subtitles section Play video
>> SPEAKER 1: Hello and welcome to this complete, Docker course,
by the end of this course,
we'll have a deep understanding of all the main concepts
and also a great big picture overview of how
Docker is used in the whole software development process.
The course is a mix of animated theoretic explanations,
but also hands on demos for you to follow along.
So get your first hands on experience and confidence
using Docker in your projects.
So let's quickly go through the topics
I'll cover in this course.
We will start with the basic concepts of what Docker actually
is and what problems it solves.
Also will understand the difference between
Docker and virtual machine. And after installing Docker,
we will go through all the main documents to start
and stop containers, debugging containers, etc..
After that,
we'll see how to use Docker in practice
by going through a complete workflow with a demo project.
So first we'll see how to develop
locally with containers.
Then we'll run multiple containers or services with Docker
Compose, we'll build our own Docker image with Dockerfile
and will push that built image into a private
docker repository on AWS and finally will deploy our
containerized application. Last but not least,
we look at how to persist data in Docker,
learning the different volume types and afterwards configure
persistance for our demo project.
If you get stuck anywhere,
just comment under the video and I will try my
best to answer your questions. Also,
you can join the private tech world.
We're not a community group on Facebook,
which is there to exchange your knowledge
with others and connect with them,
if you like the course by the end of the video.
Be sure to subscribe to my channel for more
related content. So let's get started.
So we'll talk about
what a container
is and what problems it solves.
We will also look at a container repository,
which is basically a storage for containers.
We'll see how a container can actually make
the development process much easier and more efficient
and also how they solve some of the problems
that we have in the deployment process of applications.
So let's dive right into it. What a container is,
a container is a way to package applications with everything
they need inside of the package,
including the dependencies and all the configuration necessary.
And that package is portable,
just like any other artifact is in.
That package can be easily shared and moved around
between a development team or development
and operations team.
And that portability of containers plus everything
packaged in one isolated environment gives it some
of the advantages that makes development
and deployment process more efficient.
And we'll see some of the examples of how
that works in later slides, so as I mentioned,
containers are portable,
so there must be some kind of a storage for those
containers so that you can share them and move them around.
So containers leave in a container repository.
This is a special type of storage for containers.
Many companies have their own private repositories where
the host or the way they store all the containers
and this will look something like this where
you you can push all of the containers that you have.
But there is also a public repository for docker
containers where you can browse and probably
find any application container that you want.
So let's head over to the browser and see
how that looks like.
So if I hear search for a Docker,
which is the name of the public repository for Docker,
I will see this official web. So here, if you scroll down,
you see that they're.
More than a hundred thousand container images
of different applications hosted or stored
in this repository.
So here you see just some of the examples.
And for every application,
there is this official docker container or container image.
But if you are looking for something else,
you can search it here.
And I see there is an official image for, let's say, Jenkins',
but there's also a lot of non official images or container
images that developers or for or even
from Jenkins' itself, they actually store it here.
So public repository is where you usually get started
when you're using or when you're starting
to use the containers where you can find any
application image.
So now let's see how container's improved
the development process by specific examples,
how did we develop applications before the containers?
Usually when you have a team of developers
working on some application,
you would have to install most of the services on your
operating system directly. Right. For example,
you you're developing some JavaScript
application and you need to be cool and ready for messaging.
And every developer in the team would then have
to go and install the binaries of those services and.
Configure them and run them on their local development
environment and depending on which operating
system they're using,
the installation process will look actually different.
Also, another thing with installing services
like this is that you have multiple steps of installation.
So you have a couple of commands that you have to execute.
And the chances of something going wrong and error
happening is actually pretty high
because of the number of steps required to install
each service.
And this approach or this process of setting
up a new environment can actually be pretty tedious,
depending on how complex your application is.
For example,
if you have 10 services that your application is using,
then you would have to do that 10 times on each
operating system environment.
So now let's see how containers solve some of these
problems with containers.
You actually do not have to install any of the services
directly on your operating system because the container
is its own isolated operating system layer
with Linux based image.
As we saw in the previous slides,
you have everything packaged in one isolated environment.
So you have the postgresql with the specific version
packaged with a configuration in the start script
inside of one container. So as the developer,
you have to go and look for the binaries to download
on your machine,
but rather you just go ahead and check out
the container repository to find that specific
container and download on your local machine.
And the download step is just one docker command
which fetches the container and starts it at the same time.
And regardless of which operating
system you're on, the command,
the doc recommend for starting the container
will not be different. It will be the exactly the same.
So we have 10 applications that your JavaScript
application uses and depends on.
You would just have to run 10 docker commands for each
container and that will be it.
Which makes the setting up your local development environment
actually much easier and much more efficient
than the previous version. Also,
as we saw in the demonstration before,
you can actually have different versions of the same
application running on your local environment
without having any conflict.
So now let's see how container's can improve
the deployment process before the containers,
a traditional deployment process will look like this.
Development team will produce artifacts together with a set
of instructions of how to actually install
and configure those artifacts on the server.
So you would have a jar file or something
similar for your application. And in addition,
you would have some kind of a database service or some
other service also with a set of instructions of how
to configure and set it up on the server.
So development team would give those artifacts
over to the operations team and the operations team will
handle setting up the environment to deploy
those applications. Now,
the problem with this kind of approach is that,
first of all,
you need to configure everything and install
everything directly on the operating system,
which we saw in the previous example that could actually
lead to conflicts with dependency version
and multiple services running on the same host.
In other problems that could arise
from this kind of process is when there
is misunderstanding between the development team
and operations because everything
is in a textual guide as instructions.
So there could be cases where developers forget
to mention some important point about configuration.
Or maybe when operations team misinterpreted some of those
instructions and when that fails,
the operations team has to go back to the developers
and ask for more details.
And this could lead to some back and forth
communication until the application
is successfully deployed on the server with containers.
This process is actually simplified because, no,
you have the developers and operations working
in one team to package the whole configuration
dependencies inside the application,
just as we saw previously.
And since it's already encapsulated in one single
environment and you're going to have to configure any
of this directly on the server.
So the only thing you need to do is run a docker command
that pulls that container image that you've stored somewhere
in the repository and then run it. This is,
of course, a simplified version,
but that makes exactly the problem that we saw
on the previous slide much more easier.
No environmental configuration needed on the server.
The only thing, of course,
you need to do is you have to install and set up
the DOCA runtime on the server before you will be able to run.
Container's there, but that's just one time effort.
Now that you know
what a container concept is,
let's look at what a container is technically.
So technically container is made up of images.
So we have layers of stacked images on top of each other.
And at the base of most of the containers,
you would have a Linux based image,
which is either Alpina with a specific version
or it could be some other Linux distribution.
And it's important for those base images to be small.
That's why most of them are actually Alpine,
because that will make sure that the containers
stay small in size,
which is one of the advantages of using container.
So on top of the base image,
you would have application image and
this is a simplified diagram.
Usually you would have these intermediate images
that will lead up to the actual application image that is going
to run in the container. And of course, on top of that,
you will have all this configuration data. So, no,
I think it's time to dove into a practical example
of how you can actually use a docker container and how
it looks like when you install it and downloaded and run
it on your local machine.
So to give you a bit of an idea of how this works,
let's head over to Docker Hub and search
for Posterous Keywell.
So here,
which is a doctor official image,
I can see some of the versions and let's say I'm looking
specifically for older version. I don't know, nine,
six something. So I'm going to pull that one.
So this is a doc repository so that I can actually go
ahead and pull the containers from the repository directly.
And because it's a public repository,
I don't have to log in to it.
I don't have to provide any authentication
credentials or anything.
I can just get started with a simple document
without doing or configuring anything to access Docker Hub.
So on my terminal, I can just do Dr.. Paul,
I can even do a run and then just copy
the the image name,
and if I don't specify any version,
it will just give me the latest. But I want a specific version.
So I'm just I'm going to go with nine point six, actually,
just to demonstrate so I can provide the version
like this with a column and I can start. Right. So,
as you see, the first line says, unable to find image locally,
so it knows that he has to go to Dr.
Hub and pull it from there. And the next line says,
pulling from Library Posterous.
And here you see a lot of hashes that says downloading.
And the this is what I mentioned earlier,
which is docker containers or any
containers are made up of layers. Right.
You have the image layer,
you have the application layers and so on.
So what what do you see here are actually all those layers
that are separately downloading from the Docker
hub on my machine. Right.
The advantage of splitting those applications in layers
is that actually, for example,
if the image changes or I have to download a newer
version of Posterous,
what happens is that the layers there are the same
between those two applications.
Two versions of Posterous will not be downloaded again,
but only those layers that are different. So,
for example,
now it's going to take around 10 or 15 minutes to download
this one image because I don't have any posterous locally.
But if I were to download the next version,
it will take a little bit less time because some layers
already exist on my local machine.
So now you see that it's already logging because it this comment
that I read here,
the doctor run with the container
name and version,
it fetches or it pulls the in the container,
but it also starts it.
So it executes the start script right away
as soon as it downloads it.
And here you see the output of this starting
of the application.
So it just gives some output about starting the server
and doing some configuration stuff.
And here you see database system is ready to accept
connections and launch it started.
So now let's open the new tab and see with Dr. Pascaline.
You can actually see all the running containers.
So here you see that postcrisis nine six
is running and it actually says image.
So this is another important thing to understand when we're
talking about containers, there are two technical terms,
image and a container.
And a lot of people confuse those two, I think.
And there is actually a very easy distinction
between the two. So images,
the actual package that we saw in one of those previous slides.
So the application package,
together with the configuration and the dependencies
and all these things,
this is actually the artifact that is movable
around is actually the image.
Container is when I pull that image on my local machine
and I actually started so the application inside
actually starts that creates the container environment.
So if it's not running, basically it's an image.
It's just an artifact that's lying around if I started
and actually run it on my machine.
It is a container. So that is the distinction.
So here it says the active running containers
with a container ID image that it's running
from and some entry commands that it executes
and some other status information.
So this means that PostgreSQL is now
running on my local machine. Simple as that,
if I were now to need, let's say,
another version of Posterous to run at the same
time on my local machine, I could just go ahead and say,
let's go back and let's say I want to have nine point six
and ten point ten running at the same time on my
local machine. I would just do run Posterous.
And run again, it doesn't find it locally,
so it pushes and this is what I actually
explained to you earlier,
because it's the same application,
but with just a different version.
Some of the layers of the image are the same.
So I don't have to fetch those again because they are already
on my machine and it just fetches the layers
that are different.
So that saves a little bit of time.
And I think it's it could be actually good advantage.
So now we'll wait
for other image layers to load
so that we have the second.
Postcrisis version running
and now you see I have
Posterous nine point six
running in this command
line tab and I have
Postgres version ten point
ten running in the next one.
So I have to postcrisis with different versions
and running and I can actually output them here.
If both of them running and there's no
conflict between those two,
I can actually run any number of applications with different
versions maybe of the same application with no
problem at all.
And we are going to go through how to use those
containers in your application and the port
configuration and some of the other configuration
stuff later in this tutorial when we do a deep dove.
But this is just for you to get the first visual image of how
docker containers actually work, how they look like,
and how easily you can actually start them on your
local machine without having to implement a specific version
of Posterous application and do all the configuration yourself.
When I first started learning, Doctor,
after understanding some of the main concepts,
my first question was, OK,
so what is the difference between Docker and an Oracle
virtual books, for example?
And the difference is quite simple, I think.
And in the short video, I'm going to cover exactly that.
And I'm going to show you the difference by explaining
how DOCA works on an operating system level and then comparing
it to how virtual machine works. So let's get started.
In order to understand how Docker works
on the operating system level,
let's first look at how operating system is made up.
So operating systems have two layers operating system kernel
in the applications layer. So as you see in this diagram,
the kernel is the part that communicates
with the hardware components like CPU and memory,
et cetera,
and the applications run on the kernel layer.
So they are based on the kernel. So for example,
you will know Linux operating system and there are lots
of distributions of Linux out there.
There's Bonta and Debian and there is Linux meaned, etc.
There are hundreds of distributions.
They all look different.
So the graphical user interface is different.
The file system is maybe different.
So a lot of applications that you use are different
because even though they use the same Linux kernel,
they use different or they implement different
applications on top of that kernel. So, as you know,
Docker and virtual machine,
they're both virtualization tools.
So the question here is what parts of the operating
system they virtualize?
So Docker virtualize is the application layer.
So when you download a docker image,
it actually contains the applications layer
of the operating system and some other
applications installed on top of it.
And it uses the kernel of the host because it doesn't
have its own kernel,
the virtual box or the virtual machine,
on the other hand,
has the applications layer and its own kernel.
So it virtualize is the complete operating system,
which means that when you download a virtual
machine image on your host, it doesn't use your host kernel.
It puts up its own.
So what is this difference between Docker and virtual
machine actually mean? So first of all,
the size of Docker images are much smaller
because they just have to implement one layer.
So Docker images are usually a couple of megabytes.
Virtual machine images, on the other hand,
can be a couple of gigabytes large.
A second one is the speed so you can run and start
docker containers much faster than the VMS
because they every time you start them,
you they have to put the operating system kernel
and the applications on top of it.
The third difference is compatibility,
so you can run a virtual machine image of any
operating system on any other operating system host,
but you can't do that with Docker.
So what is the problem exactly?
Let's say you have a Windows operating system
with a kernel and some applications and you want
to run Linux based Docker image on that Windows host.
The problem here is that a Linux based,
her image might not be compatible
with the Windows kernel,
and this is actually true for the Windows
versions below 10 and also for the older Mac versions,
which if you have seen how to install Docker
on different operating systems,
you see that the first step is to check whether your hosts
can actually run Docker natively,
which basically means is the kernel compatible
with the Docker images? So in that case,
a workaround is that you install a technology
called Docker Toolbox,
which abstracts away the kernel to make
it possible for your hosts to run different docker images.
So in this video,
I will show you how to install DOCA on different
operating systems,
the installation will differ not only based
on the operating system,
but also the version of the operating system.
So you can actually watch this video selectively,
depending on which OS and the version
of the OS you have.
I will show you how to find out which installation step
applies to you in the before installing section,
which is the first one. So once you find that out,
you can actually directly skip to that part of the video.
Where I explain that into details,
I will put the minute locations of each part
in the description part of the video.
And also I will put all the links that I use
in the video, in the description,
so that you can easily access them. Also,
if you have any questions during the video
or if you get stuck installing the docker
on your system,
please post a question or problem in the comments
section so that I can get back to you and help
you proceed,
or maybe someone from the community will.
So with that said, let's dove right into it.
So if you want to install Tucker,
you can actually Google it and you get an official
documentation of Docker.
It's important to note that there are two
editions of Tucker.
There is a community and enterprise
editions for us to begin with.
Community additions will be just fine in the Docker
community edition tape there.
There is a list of operating systems
and distributions in order to install Docker. So,
for example, if we start with Menck,
we can click in here and we see the documentation
of how to install it on Mac,
which is actually one of the easiest.
But we'll see some other ones as well.
So before you install
her on your
Mac or Windows computer,
they are prerequisites to be considered.
So for Mac and Windows,
there has to be some criteria of the operating
system and the hardware met in order to support
running docker.
If you have Mac go through the system requirements
to see if you're a Mac version is actually supporting Docker.
If you have Windows,
then you can go to the Windows tab and look at
the system requirements there or what to know
before you install. For example,
one thing to note is that Docker natively
runs only on Windows 10.
So if you have a Windows version,
which is less than 10,
then Docker cannot run natively on your computer.
So if your computer doesn't meet the requirements to run Docker,
there is a workaround for that, which is called Docker Toolbox.
That of Docker.
You basically just have to install a tool box
that will become a sort of a bridge between your
operating system and the docker,
and that will enable you to run on your legacy computer.
So if that applies to you,
then skip ahead in this video to the part where
I explain how to install Docker toolbox on Mac and on Windows.
So let's install Dr. for Formic, as you see here,
there are two channels that you can download
the binaries from or the application from.
We will go with the stable channel.
And other thing to consider,
if you have an older version of make the software
or the hardware,
please go through the system requirements to see if you can
actually install Docker.
So here there is a detailed description of what make
version you need to be able to run Docker and also
you need at least four gigabytes of RAM
and by installing Docker you will actually have
the whole package of it, which is a docker engine,
which is important or which is necessary to run
the containers on your laptop, the Docker command line client,
which will enable you to execute some documents Docker composed.
If you don't know it yet, don't worry about it.
But it's just technology to orchestrate if you have
multiple containers and some other stuff that we're not
going to need in this tutorial.
But you will have everything in a package installed.
So go ahead and download the stable version. Well,
I already have Docker installed from the channel,
so I won't be installing it again.
But it shouldn't matter because the steps
of installation are the same for both.
So once the Doctor DMC file is downloaded,
you just double click on it and it will pop up
this window just like the doctor well up
into the applications and it will be installed on your
Mac is the next step.
You will see doctor installed in your applications.
So you can just go ahead and. Started.
So as you see,
the doctor sign or icon is starting here,
if you click on it,
you see the status that doctor is running.
And you can configure some preferences and check the Docker
version and so on.
And if you want to stop Dakara or Quited on your mic,
you can just do it from here.
And important maybe interesting note here
is that if let's say you download or install
Docker and you have more than one
accounts on your laptop.
You'll actually get some errors or conflicts
if you run occur at the same time or multiple accounts.
So what I do, for example,
is that if I switch to another account where
I'm also going to need Docker, I quit it from here.
And then I started from other accounts
so that I don't get any errors.
So that may be something you need to consider if you use
multiple accounts.
So let's see how
to install windows, the first step,
as I mentioned before,
is to go to that before you install section and to see
that your operating system and your computer meets all
the criteria to run Docker natively.
So if you are installing DOCA for the first time,
don't worry about most of these parts
like Docker Toolbox and Docker Machine.
There are two things that are important.
One is to double check that your Windows version
is compatible for Docker and the second one is to have
virtualization enabled. Virtualization is by default,
always enabled other than you manually disabled it.
So if you're unsure,
then you can check it by going to the task manager performance
CPU tab and here you can see the status
of the virtualization.
So once you have checked that and made sure that these
two prerequisites are met,
then you can scroll up and download the Windows
installer for from the stable channel.
Once the installer is downloaded,
you can just click on it and follow
the installation wizard to install Windows once
the installation is completed.
You have to explicitly start Docker because it's not
going to start automatically. So for that,
you can just go and search for the doctor
for Windows app on your windows.
Just click on it and you will see that Dr.
Weil Aykan starting. And if you click on that icon,
you can actually see the status that says
stalker is now up and running.
So this is basically it for the installation.
Now let's see how
to install Tucker on different
Linux distributions,
and this is where things get a little bit more complicated.
So first of all,
you see that in the menu on the on the left,
you see that four different Linux distributions,
the installation steps will differ. But also,
for example,
if we just click on Bonta for the guide,
you can see that in the prerequisites section,
there is also differentiation between the versions of the same
Linux distribution.
And there may be some even more complicated scenarios
where the combination of the version
of the distribution and the architecture
it's running in also makes some difference
into how to set up Docker on that specific environment.
Because of that,
I can't go through a docker installation process of every
Linux environment because they're just
too many combinations. So instead,
what we'll do is just go through a general overview
of the steps and configuration process to get Docker
running on your Linux environment.
And you can just adjust it then for your
specific set up.
So these are some general steps to follow in order
to install Dakara on your Linux Linux environment.
First of all,
you have to go through the operating system
requirements part on the relevant Linux
distribution that applies for you.
A second step in the documentation
to is to install old versions. However,
if it's the first time you installing Docker,
then you don't have to worry about that.
You also don't have to worry about the supported storage
drivers and you can skip ahead to the part of installing
Docker community addition.
So for any Linux distribution here,
the steps will be or the options for installing
Docker will be the same.
So first option is basically to set up a repository
and download the docker from and install
it from the repository.
The second option is to install the packages manually. However,
I wouldn't recommend it,
and I think the documentation doesn't recommend it either,
because then you will have to do a lot of steps
of the installation in the maintenance
of the versions manually. So I wouldn't do that.
The third one is just for the testing purposes.
It may be enough for the development
purposes as well, but I would still not do it,
which is basically just downloading some
automated scripts that will install and set up
Docker on your Linux environment. However,
again, I wouldn't go with it.
I would actually just do the first option,
which is just downloading the docker from the repository.
So in order to install Docker using the first option,
which is downloading it from the Dockers repositories,
you have two main steps.
So the first one is to set up the repository,
which differs a little bit depending
on which distribution you have,
and then install the democracy from that repository.
So from Ubuntu and deepen the steps for setting up
the repository are generally just updating your package,
then setting up in connection with the repository and adding
the Ducker's official GPG key, which only wanto in Debian need.
You don't have to do these steps for scintillation fedora there.
You have to install the required packages
in the last step for setting up the repository
is basically setting up the stable repository of Docker,
which we saw previously on the overview
that there are two channels which is a stable and edge here.
You always have to set up the stable repository,
optionally you can also set up the edge repository.
But I would just do stable this time.
And here also something to notice.
Depending on the architecture,
you have to actually set it or you have to set
that as a parameter when you set up the repository.
So if you have, for example, a different architecture,
you can use those steps to display the correct
comen for it.
And I guess that applies to other Linux
distributions as well. Like, for example,
here you also have the second tab where you see
a separate come in for it.
So these steps should actually set up the repository.
So as a next step,
you can then install the democracy
from those repositories.
So installing DOCA from the set up repository
is actually pretty straightforward,
those steps are same for or similar to all
the distributions,
basically just update the package
and then you just say install Toker C. So this command will
just download the latest version.
If you want to install a specific one,
which you will need to do in a production environment,
then you can just provide a version like this.
You just say Toker minus C equals some specific versions.
And using this command,
you can actually look up what versions are available
in that repository that you just and with this command,
actually Docker will be installed on your Linux
environment and then you can just
verify using pseudo docker run Hello World,
which is this demo image of Docker.
You can verify that DOCA is running and this will start.
Hello, world docker container on your environment.
So as I mentioned previously,
for environments that do not support running docker natively,
there is an workaround which is called Docker Toolbox.
So Docker Toolbox is basically an installer for Docker
environment set up on those systems.
So this is how to install Dr. Toolbox on your Mac,
this is the whole package that comes
with the installation of Dr. Toolbox,
which is basically the Docker command line Docker machine. Dr.
Campos, basically all the packages that we saw
in the native installation. And on top of that,
you also get the Oracle virtual box.
So in order to install the toolbox,
it's actually pretty straightforward.
On this website,
you can go to the toolbox releases.
We have a list of latest releases.
You just take the latest release.
And here you see to Essence, this one is for Windows,
obviously, and you just download the package for Mac.
And once it's downloaded,
you just click on it and go through the installation wizard.
Leave all the options by default as they are,
do not change anything.
And after the installation you can just validate
the installation is successful and you can actually run docker.
So after seeing the installation with successful screen,
just go and look up in your launch pad QuickStart
terminal and once you open it,
you should be able to run documents and you can
just try to run Hello World,
which should just start up or bring up this hill
world docker container on your environment.
So now let's see
how to install Dr. Toolbox and Windows,
here's to you that you get the whole package
of Toker Technologies with a toolbox
which are basically the same package which you get
on the native Docker installation.
And on top of that, you get Oracle VM Virtual Box,
which is the tool that enables Docker to
run on an older system.
So before you install the toolbox,
you have to make sure that you meet some
of the preconditions. Number one,
you have to make sure your Windows system supports
virtualization and that virtualization
must be enabled.
Otherwise DOCA docker won't start.
So depending on which Windows version you have,
looking up or checking the virtualization
status will be different.
So I used to suggest you Google it and look it up
of how to find the virtualization status
to see that it's enabled once you have that checked.
Also make sure that your Windows operating
system is 64 bits.
So if those two criteria are met,
then you can go ahead and install the doctor toolbox.
The place where you see the releases
or they release artifacts is toolbox releases link here,
which I have open.
So it's basically a list of the releases.
You just take the latest one, which has two artifacts.
This is the one for Windows.
You just download this executable file,
click on it and go through the installation
wizard once the installation is completed there.
Just a couple of steps here.
You can verify that Docker was installed
or the toolbox was installed by just looking up
the Docker QuickStart terminal on your windows
that it must be installed.
And once you click on it and open it,
you should be able to run documents in the terminal.
So the basic docker recommend that you can test
will be Docker Run Halo World,
which will just fetch this basic docker container
from the public registry and run it on your computer.
If that command is successful,
it means that Docker was successfully installed
on your computer and now you can proceed with the tutorial.
So in this video,
I'm going to show you some basic documents
at the beginning,
I'm going to explain what the difference
between container and images,
because that's something a lot of people confuse.
Then very quickly go through version and take
and then show you a demo of how to use the basic documents,
commands that will be enough to pull an image
locally to start a container,
to configure a container and even debug the container.
So with that said, let's get started.
So what is the difference between container and image,
mostly people use those terms interchangeably,
but actually there is a fine difference
between the two to see. Theoretically,
teener is just the part of a container runtime.
So container is the running environment for an image.
So as you see in this graphic,
the application image that runs the application
could be Postgres redis. Some other application needs,
let's say,
a file system where it can save the log files or where you can
store some configuration files.
It also needs the environmental configuration like environmental
variables and so on.
So all this environmental stuff are provided
by container and container also has a port that is binded to it,
which makes it possible to talk to the application
which is running inside of a container.
And of course,
it should be noted here that the file system
is virtual in container.
So the container has its own abstraction
of an operating system,
including the file system and the environment,
which is of course different from the file system
and environment of the host machine.
So in order to see the difference between
container and image in action,
let's head over to the Docker hub and find, for example,
a 3D image.
Another thing is that Docker hub,
all the artifacts that are in the Docker
hub are images.
So we're not talking about containers here.
All of these things are images, Docker, official image.
So we're going to go ahead and pull a 3D image out
of the Docker hub to my laptop.
So you see the different layers of the image
are downloaded.
And this will take
a couple of minutes.
So once the download is complete,
I can check all the existing images on my
laptop using Docker images come in.
So I see I have two images,
Redis and Postgres with text images and so on.
Another important aspect of images
is that they have tags or versions. So,
for example, if we go back to the dog cup,
each one,
each image that you look up in the Docker hub will
have many different versions.
The latest is always the one that you get
when you don't specify the version. Of course,
if you have a dependency on a specific version,
you can actually choose the version you want
and specified and you can select one from here.
So this is what you see here.
The tag is basically the version of the image.
So I just downloaded the latest and I can also
see the size of the image. So now to this point,
we have only worked with images,
there is no container involved and there is no redis running.
So now let's say I need redis running so that my
application can connect to it.
I'll have to create a container of that 3D image
that will make it possible to connect
to the reddish application.
And I can do it by running the red image.
So if I say docker run credits.
This will actually start the image in a container,
so as I said before,
container is a running environment of an image.
So now if I open a new tab and the doctor says I will
get stares of all the running docker containers so I can see
the container release is running with a container ID based
on the image of redness and some other information about it,
for example, the port that it's running on.
And so.
So as you see here, the doctor run ready to come in,
will start the race container in the terminal
in an attached mode. So, for example,
if I were to terminate this with the control see
you see the redis application stops
and the container will be stopped as well.
So if I do dock trips again,
I see that no container is running.
So there is an option for Docker Run command
that makes it able makes it possible to run
the container in a detached mode and that is minus deep.
So if I do run minus redis.
I will just get the idea of the container
is an output and the container will stop running.
So if we check again. Yes,
I see the container with ID starting with eight three eight,
which is the same thing here is running.
So this is how you can start it in the detached mode now.
For example,
if you would want to restart a container
because I don't know,
some application crushed inside or some error happened.
So you want to restart it, you would need the container ID.
So just the first part of it, not the whole string.
And you can simply say, Docker,
stop idea of the container and that will
stop the container.
I think running if you want to start it again,
you can use the same ID to start the game.
So let's say you stop
docker container at the end of the day,
you go home, you come back the next day,
open your laptop and you want to restart the stalled container.
Right. So if you do is there it's, uh,
the output is empty. You don't see any containers.
So what you can do alternative to just looking up your history.
Menlyn History is you can do Docker P. S minus A, which will
show you all the containers which are running
or not running.
So here you see the container idea again
and you can restarted.
OK, so let's try another thing,
let's say you have two parallel applications
that both use Redis, but in different versions,
so you would need to redis containers with different image
versions running on your laptop. Right, at different times maybe,
or at the same time. So here we have the latest one,
which is redis five zero six.
And let's head over to the Docker hub
and select version.
Let's say you need version four point. Oh,
so remember the first time that we download
the reddest image we did Dr. Paul Radice. However,
if you run Docker,
if you use a docker run with Redis image and the tech,
which was four point o, it will pull the image
and start the container right away after it.
So it does two commands basically in one.
So it's docker,
pull that docker start in one command.
So if I do this it says it can find the image locally.
So it goes and pulls the image from the repository
to my laptop.
And again,
we see some leaders are downloaded and the container
is started right away, and no, if I do, yes,
you see that I have two races running.
So this is where it gets interesting. Now,
how do you actually use any container that you just started?
So in this output,
we you also see the ports section,
which specifies on which port the container is listening
to the incoming requests.
So both containers open the same port,
which is what was specified in the image. So.
In the logs of the container,
you can see the information running boats and loan
Port six three seven nine.
So how does that actually work and how do we not
have conflicts while both are running on the same port?
So to explain that,
let's head over to our slide and see how this works is,
you know,
container is just the virtual environment
running on your host.
And you can have multiple containers running
simultaneously on your host, which is your laptop, PC,
whatever you're working on.
And your laptop has certain ports available that you can
open for certain applications.
So how it works is that you need to create
a so-called binding between a port that your laptop,
your host machine has and the container. So,
for example,
in the first container part here,
you see container is listening on Port 5000
and you find your laptop's port.
Five thousand to that containers.
Now you will have conflict if you open to five
thousand ports on your host because you will get a message.
The port is already bound or is already in use.
You can do that.
However, you can have two containers,
as you see in the second and third containers are both
listening and port three thousand,
which is absolutely OK as long as you're buying
them to two different ports from your host machine.
So once the port binding between the host
and the container is already done,
you can actually connect to the running container
using the port of the host. So in this example,
you you would have some F localhost and then the port
of the host and the host then will know how
to forward the request to the container
using the port binding. So if we head back here,
you see that containers have their ports and they're
running on the same one. However,
we haven't made any binding between my laptop's
ports and the container port. And because of that,
the container is basically unreachable by any application.
So I won't be able to use it.
So the way we actually do that is by specifying
the binding of the ports during the run command.
So I'm going to break this and check that there
is just one container running. No, I'm going to.
Stop the other one as well so we can start them anew. OK,
so we see both containers are here.
So now we want to start them using the binding between
the host and the container ports.
But again, we have to it.
So we need to bind them to two different ports on my laptop.
So the way to do it is you do run
and you specify with minus P, the port of the host.
That's the first one. So let's go with 6000.
It doesn't really matter in this case,
and the second one is the port that you're binding this to,
which is the container port.
So we know the container port will be six three seven nine.
And this is where we find our.
So my laptop's port six thousand two.
And if I do this this year.
So, you know, if the groups.
That's actually clean
this mess again here
you see the binding here. All right,
so your laptop's six thousand port is bound to the containers,
six three seven nine.
So now let's do another thing and let's
start it in a detached mode like this. Let's check again.
It's running again and no,
I want to start the second container,
it's clear this again.
So here you see it created
a bunch of containers because, uh,
when I specified different options with the port binding,
it actually created new containers.
That's why you see a couple of more here.
So I'm going to copy the image name with the take for, uh oh,
minus P. So, for example, if I were to do this, no.
And I would try to run the other red
is the second red is container with the same
ports on my laptop,
I would get an error saying port is already
allocated so I can do six thousand one and run it again.
I'll run it in detached mode so that I won't see port.
And if I go over here and say, yes,
I see that I have two different ready
versions running,
both of them bound to different ports on my
laptop and the containers themselves listening to request
on the same port.
So so far,
we have seen a couple of basic documents,
we have seen Doctor Pool,
which pulls the image from the repository
to local environment. We also saw run,
which basically combines pool and start,
pulls the image if it's not locally available
and then starts it right away. Then we saw a start and stop,
which makes it possible to restart the container
if you made some changes and you want to create
a new version,
which makes it possible to restart a container
if you need to.
We also saw Docker run with options.
The one option that we saw was D minus D,
which is detach so you can run the container detached mode
so you can use a terminal again,
minus P allows you to bind port of your host to the container.
So very important to remember minus P,
then comes the port of your host and then comes
the port of your container or whatever
it might be. We also saw the cops,
the cops minus a which basically gives you all
the containers no matter if they're running
currently or not. We also saw the images,
which gives you all the images that you have locally. So,
for example,
if after a couple of months you decide to clean up
your space and get rid of some stale images,
you can actually check them,
check the list and then go through them and delete them.
You can do the same with stale docker
containers that you don't use anymore
or you don't need any more. You can also get rid of them.
So the final part of the Docker basic commands
are commands for troubleshooting,
which are very, very useful.
If something goes wrong in the container,
you want to see the logs of the container
or you want to actually get inside of container,
get the terminal and execute some comments on it.
So let's see. Yes,
we have two containers running right now.
We don't have any output. We don't see any locks here.
So let's say something happens.
Your application cannot connect to redis and you don't
know what's happening. So ideally,
you would want to see what logs redis container is producing.
Right. The way to do that is very easy.
You just say docker logs and you specify the container
ID and you see the logs.
You can also do the logs if you don't want
to remember the container idea or to decrypt all the time,
you can remember the name of the container and you can
get the logs using the name.
So a little side note here as we're talking about
the names of the containers, so here it is. You see,
when a container is created,
you just get some random name like this so you can name your
containers as you want using another option
of the docker run,
which might be pretty useful sometimes if you don't want
to work with the container IDs and you just want
to remember the names or if you just want
to differentiate between the containers. So,
for example,
let's create a new container from readies
for that old image using a different name that we choose.
So I'm going to stop this container and I'm
going to create a new one from the same image.
So let's run it in the detached mode that's open the port.
I was in one, two,
six three seven nine and gave the name
to the container and let's call it since it's the older version,
let's call it redis older.
And we need to specify the image. So remember,
this will create a new container since we're running
the Docker Run comment again.
So if we execute this and check again,
we see the readies for the old image based
container is created, which is fresh, new,
you can see,
and it created in the name is already
older and we can do the same for
the other container so that we kind of know
which container is what. So to stop this one
and I will use the same comment here,
this will be the latest and I will call this latest
and since find another port.
So I'm going to run it and let's see.
So here I have two containers running now. I know.
Redis older ladies later. So, for example,
if the older version has some problems,
I can just do locks right this older and I can
get my locks.
So in other very useful command in debugging
is Docker exec.
So what we can do with Docker exec is we can actually get
the terminal of a running container.
So let's check again.
We have two containers running and let's say there
is some problem with the latest redis latest container.
And I want to get a terminal of the container and do it,
maybe navigate a directory inside,
check the log file or maybe check the configuration
file or print out the environmental
variables or whatever. So in order to do that,
we use Docker Exit Command with minus T, which stands
for Interactive Terminal.
Then I specify the container ID and I say. So I get the.
And here you see that the the cursor changed.
So I'm inside of the container as a user.
And here if I say this is empty,
I can also print out which directory I am.
I can go to the home directory, see what's there.
So I have my virtual file system inside
of a container and here I can navigate the different
directories and I can check stuff.
I can also print all the environmental
variables to see that something is set correctly
and do all kinds of stuff here.
And this could be really useful if you have a container
with some complex configuration or if,
for example,
you are running your own application that you wrote
in a container and you have some complex configuration
there or some kind of setup,
and you want to validate that everything is correctly
set in order to exit the terminal just to exit
and you're out.
You can also do the same using the name again
if you don't want to work with the IDs and you just
want to remember the names of the container
to make it easier,
you can do it with the name as well.
Same thing since most of the container images
are based on some lightweight Linux distributions,
you won't have much of the Linux commands
or applications installed here. For example,
you wouldn't have Kerl or some other stuff.
So you were a little bit more limited in that sense.
So you can execute a lot of stuff
from the docker containers for most of the debugging work.
Um, it should be actually enough.
So the final part to review the difference
between stock run in Docker Start,
which might be confusing for some people,
let's revisit them. So basically,
Docker Run is where you create a new container from an image.
So Docker Run will take an image with a specific
version or just latest.
Right as option or as an attribute
with Docker Start. You're not working with images,
but rather with containers. So for example, as we saw,
the Koran has a lot of options.
You specify with minus 30 and minus P, the port binding,
and then you have this name of the container
and all the stuff.
So basically you tell Docker at the beginning
what kind of container with what attributes
name and so on to create from a specific image.
But once the container is created and you can
see that using the command, for example, here,
the last one that we created,
and if you stop it and you want to restarted,
you just need to use the command to start and specify
the container ID.
And when you started the container will retain
all the attributes that we defined when creating
the container using Docker Run.
So Docker Run is to create a new container.
Docker Start is to restart a stopped container.
So once you've learned
the basic concepts
and understood how it works,
it's important to see how the is actually
used in practice.
So in software development workflow,
you will know you have these classical steps of development
and continuous delivery or continuous integration
and then eventually gets deployed on some environment
or it could be a test environment,
develop environment.
So it's important to see how Docteur actually
integrates in all those steps. So in the next couple of videos,
I'm going to concentrate exactly on that.
So we're going to see some overview of the flow
and then we're going to zoom in on different parts
and see how Dockray is actually used in those individual steps.
So let's consider
a simplified scenario where
you're developing a JavaScript
application on your laptop,
right on your local development environment,
your JavaScript application uses and mongered TB database,
and instead of installing it on your laptop,
you download a docker container from the Docker hub.
So you connect your JavaScript application with the Monga DB
and you start developing.
So now let's say you develop the application first version
of the application locally and now you want to test
it or you want to deploy it on the development
environment where a tester in your team is going to test
it so you can meet your JavaScript application in Ghiz
or in some other version control system that will trigger
a continuous integration.
Jenkins builds or whatever you have configured
and jenkins' build will produce artifacts from your application.
So first you will build your JavaScript application
and then create a docker image out of that JavaScript artifact.
Right. So what happens to this Docker image once
it gets created by Jenkins build?
It gets pushed to a private Tulka repository,
so usually in a company you would have a private
repository because you don't want
other people to have access to your images.
So you push it there.
And now is the next step could be configured on Jenkins'
or some other scripts or tools.
That Docker image has to be deployed
on a development server.
So you have a development server that pulls the image
from the private repository,
your JavaScript application image,
and then pulls the monga déby that your JavaScript
application depends on from a Docker hub.
And now you have two containers, one,
your custom container and a publicly available Mongar,
the B container running on dev server,
and they talk to each other. You have to configure it.
Of course,
they talk and communicate to each other and run as an app.
So now if Testor, for example,
or another developer logs in to a deaf server,
they be they will be able to test the application.
So this is a simplified workflow,
how DOCA will work in a real life development
process in the next few years.
I'm going to show you hands on demo of how to actually
do all of this in practice.
So in this video,
we are going to look at some practical example
of how to use Docker in a local development process.
So what are we going to do is simple demo
of a JavaScript A.I.S application
in the backend to simulate local development process.
And then we're going to connected to a docker
container with the TO database in it. So let's get started.
So in this video,
we're going to see how to work with docker containers
when developing applications.
So the first step will be is we going to develop
a very simple UI backend application using JavaScript,
very simple HTML structure and no JS in the backend.
And in order to integrate all of this in the database,
we are going to use a docker container of a monga to be
database and also to make working
with the mongered to be much easier so we don't have
to execute commands in the terminal.
We're going to deploy a docker container of a Monga UI,
which is called the Mongar Express,
where we can see the database structure and all
the updates that our application is making
in the database.
So this development setup
should give you an idea of how
docker containers are actually
used in the development process.
So I've already
prepared some very
simple JavaScript application, so in order to see the code,
basically we have this index HTML that is very simple
code and we have some JavaScript here and we're
using Noge inspection that just serves that index HTML file
and listens on page three thousand.
So we have the server running here in the backend and we have
the UI that looks like this.
So basically it's just the user profile page with some user
information and user can edit their
profiles or if I, for example,
change the name here and if I change the email
address and do changes like this,
I can save my profile and I have my updates here.
However, if I refresh the page,
of course the changes will be lost because
it's just JavaScript. No.
So there's no persistent component in this application.
So in order to have this,
which is actually how real life applications work,
you'll know that you need to integrate
the application with a database. So using that example,
I will try to showcase you how you can actually use
the docker containers to make the development process easier
by just pulling one of the databases
and attaching it or connecting it to the application.
So in this case,
we're going to go with the monga to be
application and in addition to Monga to be container,
we're going to also deploy a Monga DP UI,
which is its own container. It's called Mango Express,
where we can manage or see the database insights
and updates from our application much easier.
So now let's see how that all works.
So in order to get started,
let's go to Docker Hub and find our Mungindi image.
Here, let's go to Mongul. And we have to be here.
And the Mongar Express,
which is another container that we're going
to use for the UI. So first,
let's pull the monga to be official image.
So I already have
them going to be later,
so pulling doesn't take longer on my laptop,
but you're going to need a couple of seconds,
probably in the next one we're going to pull
is the Talk Express, which I also have, I believe.
So let's see. Yes, it's also first,
so if I check locally, I have to be and express images,
so the next step is to run both mango and mango express
containers in order to make the Mungindi database
available for application and also to connect
the Mongar express with the Mongo DB container.
So let's do that.
The connection between those two first.
In order to do that,
we have to understand another doctor concept doctor network,
so how it works is that it creates its
isolated doctor network.
Where the containers are running in.
So when I deploy two containers in the same
token network,
in this case Mango and Mango Express,
they can talk to each other using just the container
name without localhost port, no, etc.
just the container name because they're in the same network.
And the applications that run outside of Docker
like our No Jars,
which just runs from node server,
is going to connect to them from outside or from the host
using local host and the port. No.
So later when we package our application into its
own docker image,
what we're going to have is a game docking network
with Monga to be container Mongar express container.
And we're going to have a notice application which we wrote,
including the index,
HTML and JavaScript for Fronton in its own docker container.
And it's going to connect to the Monga DB in the browser,
which is running on the host.
But outside the Docker network is going to connect to our
JavaScript application again using hostname
and the port number.
So Docker by default already provides some networks.
So if we say Docker network,
unless we can already see this auto
generated Docker networks,
so we have four of them with different
names and the drivers,
we're not going to go into details here,
but what are we going to do is create its own network
for the mongered to be in the Mongo Express and we're
going to call it mobile network. So let's do this right away.
I'm going to say Docker Network create and we are going
to call it Mongul network.
So now if I do a network
else again,
I see my doctor network has been created.
So now in order to make our Mongar to be container
in the Mongar express container run in this Mongan network,
we have to provide this network option
when we run the container in the dock around.
So let's start with the Mongul,
so we all know that DOCA run is the come in to start
a container from an image, right? So we have to run Mongul,
which is the basic DOCA run comment. However,
in this case,
we want to specify a couple of things.
As you learn from the previous videos,
you have to specify something called port.
So we need to open a port of Mongar to be the default
port of what would it be is twenty seven
thousand seventeen.
So we'll take that port actually for both
host and container.
So Monga will run this port inside of a container
and we open the same port on the host.
So that will take care of the port.
Then we will run it in a detached mode.
In addition to that,
there are a couple of things that we can specify
when starting up the container.
And these are environmental variables of the Mongar to be.
Let's see,
in the official image description,
you actually have a couple of documentation
about how to use the image,
which is very helpful to kind of understand what kind
of configuration you can apply to it.
Here you see some environmental variables.
So basically on startup,
you can define what the root username and the password
will be,
which is very handy because we're going
to need those two for the Express to connect
to the monga.
And you can also specify the any database.
We're just going to provide the username and password
because we can create the database
from the Mongo Express UI later. So let's do that.
And the way you can specify the environmental
variables you can actually see here as well is by just.
Let's copy this one. So here you say environment,
a variable,
that's what the minus E flag stands
for and what username will say, I mean, and another variable,
which is the password will be just password.
So in this way,
we can actually overwrite what the default
username and password will be.
So two more things that we need to configure
in this command are container name because we're going
to need that container name to connect
with the Monga Express. So we'll call this one Mongo DB,
let's say.
And another one we need is the network that we created,
which was called Mongo Network.
So in order to make this command a little bit more
structured on multiple lines. So it's C.
So it's more readable.
So basically all these options or all these flags that we set
to go one more time through them,
it's going to start in detached mode.
We are opening the port on the host username
and password that we want to be to use in the startup process.
We're going to rewrite or overwrite the name
of the container and this container
is going to run in a Mongo network and this should actually
start the container.
OK, so if you want to see whether it was successful,
we can lock the container and see what's happening inside.
So as we see Mongar was started and everything
actually looks good,
waiting for connections on board.
Twenty seven thousand seventeen. OK,
so now let's start Mongar Express one Monga Express
to connect to the running Mahmoudi container on startup.
And here we have an example of how to run it.
And here we have a list of environmental
variables that we can configure. So let's quickly look at them.
Username, password. We don't need them. However,
we need the admin username and password of the monga
to be this is actually what we overwrote
with admin and password.
So we are going to use them because experts will need some
username password to authenticate with the monga
to be interconnected.
The port is by default the correct one.
So we don't need to change that. And this is an important part.
This is the going to be server, right. So basically,
this is the container name that experts will use
to connect to the docker.
And because they're running in the same network,
only because of that, this configuration will work.
If I didn't if I hadn't specified
the network,
then I could have I could specify the name
correct name here of the container,
but it wouldn't work. So with that said,
let's actually create the Docker Run
command for Xpress as well.
So let's clear the history and let's start. So again,
we run detached mode and let's see what parameters we need.
So first of all, port, let's say,
what is the default port that the Express runs on?
That's 80 81. So we'll take that.
So basically,
it's going to run on our laptop on Port 80, 81.
The next option would be. These two and remember,
environmental variables need to be specified with minus EHP,
and this is the username of Monga Debe admin,
which is admin,
because we specified it when we started the ongoing
going to be container. This is the password.
Let's set this one as well.
Don't forget the network minus minus net Wango Network.
We have the name.
We can also call it Mongul Express.
And let's see what else
we might need here. Yes, this is an important one.
And our container name, let's actually see it again, Dr.
Pierce, the one running,
it's called mongered to be that's the container
name and this is what we need to specify here.
So I'm going to write this here. And finally,
the image is called Mongar Express.
I'm just going to copy this one here.
And that is it's so basically with these commands,
Mongar Express should be able to connect to
the to be container. So that's right.
And just to make sure,
let's log the container and see what's happening there.
Waiting for Mongo DB Welcome to my Express.
It looks like it connected successfully.
It says here database connected and the Mongar Express
is available at Port eighty eighty one.
So let's check the Mongar Express
out at the port. Eighty, eighty one. So actually,
let's close this tabs. You don't need them anymore.
And here if I say localhost one,
I should be able to see the Monga Express.
So these are the databases that already exist by default
in Wango or which are created on startup and using the UI,
we can create our own database. As we saw previously.
We could have specified environmental variable.
You need to be on mongered to be stored up
and that would have created a new database. However,
it does matter.
We will just create a database name here.
So we will call it user account database.
So let's create one.
And now we can actually use it or connect
to this database from no JS. So let's see how that works.
So now we have the mongered
to be container in the Mongar
express container running,
so let's check that we have both of them.
We'll have to connect not just with the database.
So the way to do it is usually to give
a protocol of the database and the Ghauri
and the UI for the database would be localhost and the port
that it's accessible at.
I already went ahead and prepared the code
for Narges.
So basically we are going to use a Mongul client here,
which is a node module, and using that model client,
we are connecting to the Mungindi database.
So this is the protocol.
The host and the port that we just saw
that the Mogador be listening at and username and password
of the route user Mongar to be. Of course,
usually you wouldn't put the password here or not use
an admin or route username password to connect
to a database.
But this is just a demonstration purposes
and these are username and password that we set
as environmental variables when we created
the Docker Mongar container. So. They check that.
So this is the Mongkut to be, uh,
Container Command and this is the user name,
root and root password that we specified.
And this is what we are going to use in the code. As I said,
for demonstration purposes,
I will write the password directly here.
So then we connect to the database.
So I also went ahead and in the Mongo Express
user account database and inside that I created
a collection which is like a table in my
secret world called users.
So here I connect to a user account database and I query
the collection users and this is a card requests.
So I'm just fetching something from the database
and this is update request. Same thing.
I connect to the database using the same
you or I and the database name and I update or insert
something in the collection. So let's see how all that works.
So let's head over to the UI. So in the user's collection,
there is no data. It's empty.
So we're going to refresh it and edit the data.
So I'm going to write here some and updated and refresh.
We see that a new insert was made.
So this is the update profile section here.
So all this was executed. It connected to the Mungindi be.
And now we have one entry,
which is email coding name that we changed.
So if I'm going to refresh it now,
I fetched a newly inserted user data in the UI
and displayed it here. And also,
if you want to see what the monga,
the big container actually logs during this process,
we can actually look at the logs.
So I'm going to say yes and log using the container ID.
So let's say if I wanted to see just the last part of it,
because I want to see what the last activity was,
I can also let's clear this and I can also do
tail so I can just display the last part of it.
Or if I wanted, I could also stream the logs.
So I'll clear this again and I will say stream
the logs so I won't have to do the logs all the time.
So if I make a line here, for example,
to mark the lost logs, I can refresh it.
Let's make some other changes.
Let's change it and save profile.
So I'm going to see some activity here as well.
So these connections are new.
And he also says received collect metadata.
And this is where the node JS request comes
in with the notice and its version.
And at the end of each communication,
there is an end connection because we end
the database connection at the end.
So we see that also in the logs, so, for example,
something wasn't working properly,
you could always check them in the logs here.
So with that,
I have a fully functional Java application,
which has a persistance in the Mongered database,
and we also have Mongar UI,
both of them running in a Docker container.
So this would be some unrealistic example of how
local development using docker containers
would look like.
So in the last video
we created and started
to docker containers
among to and among Express,
and these are the comments that we used to make it happen,
right? The first we created a network where these two
containers can talk to each other using just the container
name and no host port, etc. is necessary for that.
And then we actually ran to dock, run,
commence with all the options and environmental variables,
etc. said no.
This way of starting containers all the time is a little bit
tedious and you don't want to execute this wrong
commands all the time on the mainline terminal,
especially if you have a bunch of docker containers to run.
You probably want to automated or just
make it a little bit easier.
And there is a tool that that makes running
multiple docker containers with all
this configuration much easier than with docker run commands.
And that is Docker Campo's.
If you already know Doc Campos and you were wondering
why is it useful and what it actually does,
then bear with me in the next slide.
I'm going to explain that.
So this is a doctor run command of the mongered
to be executed previously. So basically with Dr.
Campos file, what we can do is we can.
Take the whole comment with its configuration and map
it into a file so that we have a structured comment.
So if you have, let's say,
10 containers that you want to run for your
application and they all need to talk to each other
and interact with each other,
you can basically write all the run commands for each
container in a structured way in the dock who can
post and we'll see how that structure
actually looks like. So on the right side,
in the Docker composed example,
the first two takes are always there, right?
Version three,
that's the latest version of the compose and compose.
And then we have the services.
This is where the container list goes.
So the first one is mongered to be and that MEPs
actually to the container name. Right.
This is going to be a part of container name
when Docker creates a container out
of this configuration blueprint.
The next one is actually the image, right,
so we need to know which image that container
is going to be built from. And of course,
you can specify a version take here next to the name.
The next one is port.
So we can also specify which ports is going to be open.
First one is on the host and the second one after
the column is on the container. So the port maybe is there.
And of course,
the environmental variables can be also
mapped in the dock or compose.
And this is how actually the structure of Docker
compose looks like, for one specific comments.
Let's actually see the second container come
in for Mongar Express that we executed
and how to map that. So now again,
we have a document command for Mongar Express
and let's see how we can make it into a dock to compose.
So, as I said,
services will list the containers that we want
to create. And again,
names Mongo Express will never map to the container name.
The next one will be the image again.
You can edtech here.
If you want to be have a specific one,
then you have the ports, 80 to eighty 80.
And then you have all the environmental
variables again. Under the environment,
and this is how the Ducker compose will look like,
so basically the composed,
it's just a structured way to contain very
normal common documents. And of course,
it's going to be easier for you to edit the file
if you want to change some variables or if you want
to change the ports.
If you want to add some new options to the run, come in,
so to say.
And maybe you already noticed the network configuration is not
there in the docker compose.
So this Mongo network that we created,
we don't have to do it in a docker compose.
We go to the next slide because we have the same
concept here.
We have containers that will talk to each other
using just the container name.
So what Docker Compose will do is actually take care
of creating a common network for these containers
so we don't have to create the network
and specify in which network these containers will run in.
And we're going to see that in action right away.
So let's actually
create a docker compose file,
so I'm going to paste all my contents here
and this is exactly what we saw on the slides
and I'm going to save it is a Mongo demo and we see
the highlighting as well.
Be very aware of the invitation they have to be correct.
So this is the least of all the containers
on the same level.
And then each container has its configuration inside that.
So now, compared to Docker run commands,
it will be very easy for me to go here and change
this environment variables or add some
new configuration options, et cetera.
So here again for demonstration,
we actually saved the Doctor Campos in the code.
So it's part of the application code.
So now that we have a doc who can post file,
the question is how do I use it or how do I start
the containers using that?
So let's go to the come in line and start
docker containers using this Docker Campos file.
So the way to use it is using Docker Campos. Comment now,
if you've installed Dakkar on your laptop,
it usually gets installed with the TOKU
compose packaged inside,
so you should have both darker and darker compose
commands installed as a package.
So Dogra composed command takes an argument,
which is the file.
So I'm going to specify which file I want to execute.
And in my case, it's called Mongo Yamal.
And at the end I want to say what I want to do
with this file. In this case, the command is up,
which will start all the containers
which are in the Mongul Yamal.
So let's actually check before that.
There are no containers for money.
So I don't have anything running here and I'm going
to start those two containers.
OK, so there are a couple of interesting things
here in this output, so let's crawl all the way up.
So we've talked about Dr Network and how we created our own
network at the beginning to run the containers inside.
And I said the Dr. Campos takes care of it.
And here we see the output where he actually created
a network called My App Default.
This is the name of the network and it's going
to run those two containers.
These are actually the names of the containers
that compose created.
This is what we specified and it just
added prefix and suffix to it.
And he created those two containers in that network.
So if I actually go here and do doctor network,
as I see the my default is here.
So that's one important thing.
And the other one is the logs of those containers
actually mixed because we are starting
both at the same time. As you see,
the Mongar Express has to wait for Mongar DB
to start because it needs to establish a connection.
So we here see the logs. Some are going to be starting.
We still get Conexion refuse because it's not started
completely and some were here when mongered the be is started
and listening for connections,
Mongar Express is able to connect to it.
So this is something that you can also do with Dr.
Campos when you have two containers that where one
depends on another one starting,
you can actually configure this waiting
logic in the composed. OK,
so now let's see actually that the docker
containers are running. So we have both of them here.
You see the container names that Dr. Campos gave them.
And one thing here to note is that the Mongar Express
actually started on Port Eddie. Eighty one inside the container.
So we can see that here.
So we are opening a port on my laptop that actually
forwards the request to container at port
eighty eighty one just so that you don't get confused
because was it on the slides.
So now that we have restarted the containers,
let's actually check the first one,
which is Mongar Express.
So it's running on 80, 80 in the previous example,
we created a database in the collection,
which is gone because we restart the container.
This is actually another very important concept
of containers to understand when you restart the container,
everything that you configured in that containers
application is gone. So data is lost.
So to say there is no data persistance
in the containers itself. Of course,
that is very inconvenient.
You want to have some persistence,
especially when you're working with the database.
And there is a concept where you're going to learn later
called volumes that makes it possible to have persistency
between the container restarts. OK,
so let's actually create the database again
because we need it.
And inside the database we had actually
users collection.
Let's create that one as well and that is empty.
Now let's actually start our application.
And there you go.
So now if I were to modify this one here and update,
I should see the updated entry here.
So the connectivity with Mongar to be works.
So now what do I do it if I want to stop those containers,
of course, I could go there and say,
Doctor, stop and I can provide all the IDs as we did
previously or with Dr. Campos. It's actually easier I can do.
Dr. Campos again.
Specify the file and instead of up,
I'm going to say down and that will go through all
the containers and shut them all.
And in addition to removing the containers or stopping
them removing the containers, it also removes the network.
So the next time we restarted, it's going to recreate,
so let's actually check that the network
allows that default. My default network is gone.
And when I do up.
See, it gets recreated,
that should give you a good idea of what Dr.
composes and how to use it. The next,
we're going to build our own Docker image from our
no JavaScript application.
So now let's consider
the following scenario,
you have developed an application feature,
you have tested it,
and now you're ready to deploy it right to deployed,
your application should be packaged into its
own docker container.
So this means that we are going to build in Docker image
from our JavaScript Noge spec in application
and prepare it to be deployed on some environment to review
this diagram that we saw at the beginning of the tutorial.
So we have developed a JavaScript application.
We have used the Monga be docker container to use it,
and now it's time to commit it to the right. In this case,
we're going to simulate these steps on the local environment.
But still,
I'm going to show you how these steps actually work.
So after you have a continuous integration that runs.
So the question is,
what does actually Jenkins' do with this application
when it builds the application so that JavaScript
application using the NPM build, etc.,
it packages it then in a Docker image.
And then pushes it into a repository,
so we're going to actually simulate what Jenkins does
with their application and how it actually
packages it into a Docker image on the local environment.
So I'm going to do all this on my laptop,
but it's basically the same thing that Jenkins will do.
And then on later said we can actually push the built
image into a docker repository.
In order to build a docker
image from an application,
we basically have to copy the contents of that application
into the Docker file.
It could be an artifact that we built in our case.
We just have three files so we can copy them
directly in the image and we're going to configure it.
In order to do that,
we're going to use a blueprint for building images,
which is called a docker file.
So let's actually see what is a docker file and how
it actually looks like. So as I mentioned,
Docker file is a blueprint for creating Docker images.
A Syntex of Docker file is super simple.
So the first line of every docker file is from image.
So whatever image you are building,
you always want to base it on another image.
In our case,
we have a JavaScript application with no JS backend,
so we are going to need a node inside of our
container so that it can run our node application instead
of basing it on a Linux Alpine or some other lower level image,
because then we would have to install node ourselves on it.
So we are taking a ready node image.
And in order to see that, let's actually go to Docker Hub.
And research note here and here,
you see there is a ready node image that we can
base our own image from.
So here we have a lot of different text so we can
actually use one specific one or we can just go
with the latest if we don't specify any take.
So what that actually means basing our own image
on a node image is that we are going to have
node installed inside of our image.
So when we start a container and we actually
get a terminal of the container,
we can see that node command is available
because there is node installed there.
This is what from Node actually gives us.
So the next one is we can configure
environmental variables inside or docker file now is you know,
we have already done this in the using the Docker
anchorman's or the docker compose.
So this will be just an alternative
to defining environmental variables in a docker composed,
for example,
I would say it's better to define
the environmental variables externally
in a Docker compose file because if something changes,
you can actually override it.
You can change the Docker Compose File Incorporated
instead of rebuilding the image. But this is an option.
So this in command basically would translate to setting
the environmental variables inside of the image environment.
The next one is run.
So all this capital case words that you see
from N and Run,
they're basically part of a Syntex of a docker file.
So using run,
basically you can execute any kind of Linux commands.
So you see make directory is a Linux command
that creates a home slash home slash app directory.
Very important to note here,
this director is going to live inside of the container.
So why not start a container from this image?
Slash home slash EP directory will be created inside
of the container and not on my laptop,
not on the host.
So all this commands that you have in Docker file
will apply to the container environment.
None of them will be affecting my host's
environment or my laptop environment.
So we run basically you can execute any
Linux commands that you want.
So that's probably one of the most used ones.
And we also have a copy command. Now,
you would probably ask I can execute a copy comm
in a Linux copy command using run. Yes,
you could. But the difference here is that,
as I said, all these commands end run,
for example.
They apply to they get executed inside
of the container.
The copy command that you see here,
it actually executes on the host.
And you see the first parameter is DOT in the second
parameter is from scholarship. So source and the target.
So I can copy files that I have on my host
inside of that container image. Because if I were to execute,
run Sepi source this nation,
that command would execute inside of the DOKO container,
but I have the Farzat I want to copy on my
host in the last one.
So from an seemed or command is always part of the aircraft.
What command does is basically executes an entry
point Linux command.
So this line with the command actually
translates to node Sergius.
So remember here we actually do node savages,
so we start a node server with node. Yes,
this is exactly what it does, but inside of the container.
So once we copy our jazz and other files
inside of a container,
we can then execute node searches and we are able to do
it because we are basing on the node image
that already has node preinstalled and we are going
to see all of this in action. So another question here.
What is the difference between run ins?
Because I could also say run node server,
which is the difference again, is that CMB is an entry point.
Come in so you can have multiple run
commands with Linux commands, but ACMD just one.
And that marks for Docker file that
this is the command that you want to execute
as an entry point.
So that basically runs the server and that's it.
So now let's actually
create the Docker file,
and just like the Toku Campos file,
Docker file is part of the application code.
So I'm going to create a new file here and I'm going to.
Paste here, the contents. So, again,
we are basing of node image and actually instead
of just having the latest node,
I'm going to specify in node version.
So I'm going to take 13 minus Alpine.
So all this that you see here are text so I can
use any of them as a tick.
So I'm going to say 13 minus Alpine.
Like this,
so this is going to be a specific node image that I'm
going to use as my base image,
let's actually stop here for a moment and take a little
bit of a deep dove on this line.
So since we saw that dogor file is a blueprint
for any Docker image,
that should actually mean that every Docker image
that there is on Docker Hub should be
built on its own Docker file. Right.
So if we actually go to let's actually look at
one of the latest versions, which is 13 minus Alpine.
Let's click inside. And as you see,
this specific image has its own Docker file.
And here, as you see,
we have the same from that we just saw.
And this is what this node official image is based off,
which is a base image, Alpine, three point ten. Right.
And then we have this environmental variable
set and all this Lenos commands using run and some
other environmental variable. And you have this entry point,
which is a script.
So you can also execute the whole Shell script
instead of separate commands. And you have this final comment.
Right. So you don't have to understand any of this.
I just want to demonstrate that every image
is based off another base image. Right.
So in order to actually visually comprehend how these
layers stacking works with images,
let's consider this simplified visualization.
So our own image that we're building up with the version
1.0 is going to be based on a node image
with a specific version.
That's why we're going to specify from Node 13
Alpine in the node 13 alpine image,
as we saw in the Docker file,
is based on Alpine based image with a version three point ten.
That's why it specifies from Alpine three point ten.
So Alpine is lightweight based image
that we install node on top of it.
And then we stole our own application on top of it.
And basically this is how all the images are built.
So now let's go back and complete our Docker file.
So we have the from specified.
We have the environmental variables specified.
And in just a second,
we're going to actually see these commands in action.
So let's copy that. And this is also very important.
Docker file has to be called exactly like that.
You can just give it any name. It is always called Docker File,
starting with a capital D, and that's it.
It's a simple text file, so just save it like this.
And here you can see the highlighting
and this docker icon.
So now that we have
a profile ready,
let's see how to actually use it.
So how do we build an image out of it?
So in order to build an image using Docker file,
we have to provide two parameters.
One is we want to give our image a name in the take,
just like all the other images have.
So we are going to do it using minus T, so we are going
to call our image my app and we're going to give
it a take of 1.0.
The tech could be anything you can even
call it actually version one. It would matter.
So we are going to do one point.
Zero in the second required parameter,
actually is a location of a Docker file,
because we want to tell Docker here,
build an image using this Docker file.
And in this case,
because we're in the same folder as the Docker file,
we're just going to say current directory.
When we execute this,
we're going to see that image is built.
And this is an idea of the image that was built.
Because I already have
a. 13 Alpine on my laptop,
this just used the the one I have lying
around locally for you, if it's the first time,
you will actually see that it's pulling node
image from the Docker hub. So now with the Dockray images,
I can actually see that my images here,
it says created two days ago. I don't know why. But anyways,
so I have the image name, which is this one here,
and I have the name of the image and the take of the image.
So if we go back to this diagram that we saw in the review,
so basically we've gone all these steps or we have
simulated some of the steps.
We've built the Joska application
using a docker containers.
And once the application is ready,
let's say we made the commit and we're we just simulated
what jenkins' server also does.
So what Jenkins does is actually it takes the docker
file that we create.
So we have to commit the Docker file
into the repository with the code.
And Jenkins will then build a Docker image
based on the Docker file.
And what is an important point here is that usually
you don't develop lone, you are in the team,
so other people might want to have access to that.
Up to image of your application that you developed,
it could be a tester maybe who wants to pull
that image and tested locally,
or you want that image to be deployed
on a development server. Right. In order to do that,
you have to actually share the image so it is pushed
into a docker repository. And from there,
either people can take it, for example, a tester,
maybe want to download the image from there and test it locally,
or a development server can actually pull it from their.
So let's actually
just run a container.
I'm just going to say run the image name obviously,
and tick like this. And in this case,
I'm not going to specify any other options
because we just want to see what's going on inside
of the container. So I'm just going to run it. OK,
so the problem is that it can find the Sergius file,
which is actually logical because we're not telling
it to look in the correct directory.
So since we're copying all the resources in this directory,
service is going to be there as well.
And this is another topic.
Whenever you adjust a docker file,
you have to rebuild an image because the old
image cannot be overwritten, so to say.
So what I'm going to do now is actually I'm going to delete
the one that I built.
So I'm going to I'm going to actually take the image.
This is how you delete an image.
But I can delete
it because as it says,
the docker is used by a stopped container.
So if I do Docker s minus a actually let's
go up to my app like this,
I have to first delete the container.
So this is how you delete a container.
It's Docker are M and 170 deleted the container.
I can delete an image.
So the image deletion is RMI like this.
So if I do images now I see my image isn't there. OK,
so we've modified the Docker file,
so let's rebuild it now. So Docker build.
OK.
And let's see the images here. So let's start it again,
so it's my one point zero
and let's run
it and see the problem is fixed
up listening on PT.. Three thousand.
So our app is running. So this one here, my EP 1.0,
first of all,
we can see the logs here like this.
We see that the EP is listening on three thousand.
We know everything is cool to actually just
get a little bit more inside. Let's enter the containers.
Let's get the terminal,
the command line terminal of the container
and look around there.
So I'm going to say Docker Exec Interactive Terminal.
I'm going to specify the container ID and the mesh
like this.
And since being bashed doesn't work,
we can actually try Shell.
So this is something you will also encounter
because some containers to not have Besch installed.
So you have to connect using bean s h. So one of them
has to work always.
So let's see in which rectory we are.
So we are in the root directory and we see our
virtual file system there. And as you see,
the cursor changes as well.
So that means we're inside of a container.
So now let's actually check some of this stuff.
So first of all,
we specified some environmental variables
here in the Docker file.
And this means that these environmental variables
have to be set inside the Docker environment.
So if we do and we actually see the mongered to be user
name on here and I'm going to be password are set
and there are some other environmental
variables automatically said we don't care about that.
So another thing we can check is this directory
because remember, because with this line,
we actually created this from a directory.
So let's see slash home slash app.
And as you can see,
the directory was created and with the next line,
we copied everything in the current folder.
So if we actually go and see Review in Finder.
So this is where the doctor father resides.
So basically copied everything that is inside
of this directory,
so all of this into the container. Now,
we don't actually need to have Dr. File and Dr.
Campos and this other stuff in here,
because the only thing we need are the JavaScript
files or if we build the JavaScript
application artifact, just the artifact.
So let's go ahead and improve there.
So what I'm going to do is I'm going to create an app
directory and I'm going to copy just the files
that I'm going to need for starting an application
instead of a container. So I'm going to take those.
And the images as well,
so all these are just external ones,
we don't need them there and images,
the index extremophile packages and surges and no
modules are inside of it.
So what we can do it now is instead of copying
the whole directory where with the Docker files,
I just want to copy all the contents of EBP folder.
So I'm going to do is I'm going to say copy
all the contents. And again,
because we modify it a docker file,
we need to recreate the image in order to leave
the Docker container terminal. You can actually exit.
So now we are on the host again. So if I do docker images again,
I have to first delete the container and then image.
But in order to delete the container,
I have to first stop it.
So now I can remove the container and now I can
actually remove the image that the container was based on.
And let's check again.
So let's actually execute that build.
Come in again.
So now that we have
the image built, let's actually run it.
So I'm going to say my app 1.0 and of course,
I could have executed with a minus D in a detached mode.
It doesn't matter now. And if I do it or yes,
I see my image continue running and all that's
actually enter the container again. So, team.
And as we learned, it was in age and again,
we're going to see the home EP and here we just have
the contents of EP directory,
so no unnecessary doctor file look recomposed etc files,
which is actually how it's supposed to be.
Or as I said,
because I just had a couple of files here,
I copied all of them.
But usually if have this huge application
you would want to compress them and package them
into an artifact and then copy that artifact
into a docker image container. OK, but as I said,
this was just for demonstration purposes,
because I just wanted to show you how you can
actually started as a container and actually look inside.
And in this case, we improved a couple of things.
But usually we would start this container
from a docker composed as well,
together with all the other docker images
that the application uses.
And it's also doesn't have any ports open.
So this is just for demonstration purposes.
So this video,
we're going to create a private repository
for darker images on A.W.
s.E.C Are there many more options for DOCA registries,
among them, Nix's and Digital Ocean,
so we can see how to create a registry there,
build and tag an image so that we can push
them into that repository.
And in order to push the images into a private repository,
you first have to log in to that repository.
So let's see how it all works.
So the first step
is to actually create a private
repository for Docker.
It's also called Docker Registry. In this case,
we're going to do it on. Yes. So let's see.
So I already have
an account on FWC,
so the service that we're going to use is called a plastic
container registry.
So you see our local container registry.
And because I don't have a repository there, yes,
I am presenting with the screen,
so in order to create a repository.
Click on Get Started.
And here we have a repository name and we're
actually going to name it the name of the application
that we have.
So I'm actually going to name it my app.
This is the domain of the registry from. Yes.
And this is the repository name,
which is the same as my image name.
And don't worry about the other stuff right now
and just create a repository. It's as simple as that. Now,
one thing I think specific to Amazon Container Service
is that here you create a docker repository per image.
So you don't have a repository we have where you can actually
push multiple images of different applications,
but rather for each image you have its own
repository and you go inside of the repository here.
It's empty now,
but what you store in a repository
are the different tags or different
versions of the same image.
So this is how the Amazon Container Service
actually works.
There are other Docker registries
that work differently. For example,
we create a repository and you can just throw all
of your container images inside of that one repository.
So I think this is more or less specific for us.
So anyways,
we have a repository which is called my EBP,
and let's actually see how we can push the image
that we have locally.
So actually check that once more.
So we want to push this image here into that repository.
So how do we do that? If you click on this one,
the view push comments will be highlighted.
This is different for each registry.
But basically what you need to do in order
to push an image into a repository
are two things. One,
you have to login into the private
repository because you have to authenticate yourself.
So if you're pushing from your local laptop
or local environment,
you have to tell that private repository, hey,
I have access to it. This is my credentials.
If Docker image is built and pushed from a jenkins' server,
then you have to give jenkins' credentials to login
into the repository.
So Tocal login is always the first step
that you need to do. So here. A.W.
is actually provides a docker login come in for it years
so it doesn't say docker login,
but in the background it uses one.
So I'm going
to execute the slogan come
in for us DOCA repository,
so in the background it uses actually Docker
login to authenticate.
So in order to be able to execute that,
you need to have a command line interface
in the credentials configured for it.
So if you don't,
I'm going to put a link to the guide of how to do
that in the description.
I have configured both of them so I can execute this command
and I should be logged in successfully
to the Docker repository.
So now I have authenticated myself
to the Docker repository here.
So I'm able to push the image that I have
locally to that repository. But before I do that,
it is one step I need to do. So I've already built my image,
so that's fine. And now I have to take my image.
And if this come in here,
looks a little bit too complicated
for you or too strange,
let's actually go and look at images NameA
concepts in Docker repositories.
So this is the naming
in doctor registries. This is how it works,
the first part of the image name,
the image full name is the registry domain.
So there is the host port, et cetera,
slash repository or image name and the tag. Now,
you may be wondering,
every time we were pulling an image out of Docker Hub,
we actually never had this complex
long name of the image. Right.
So when we were pulling an image,
it looked like this Dr.
Paul Mongul for pointing to the thing is with Docker Hub,
we're actually able to pull an image
with a shorthand without having to specify a registry domain.
But this command here is actually a shorthand
for this command.
What actually gets executed in the background
when we say Dr. Paul Mongul is Dr. Paul,
the registry domain. So Dr.
IOPS library is a registry domain.
Then you have the image name and then you have the tag.
So because we were working with Docker Hub,
we were able to use a shortcut,
so to say in a private registries,
we can just skip that part because there's no
default configuration for it. So in our case in us,
you see are what were you going to do?
Is we going to execute Docker,
pull the full registry domain of the repository?
This is what we're going to see here and a take
and this is how it just generates the Docker
registry name.
That's why we see this long image name with the tag here.
And we have to take our image like this.
So let's go back and take a look at our images,
our image that we built again in under the repository.
It says my app. Now,
the problem is we can just push an image with this name
because when we say Docker, push my app like this,
Docker would know to which repository we're
trying to push it by default.
It will actually assume we're trying to push to Docker Hub,
but it's not going to work, obviously,
because we want to push it to AWEX.
So in order to tell Docker, you know what,
I want this image to be pushed to a repository
with the name my app, we have to take the image.
So we have to include that information in the name
of the image.
And that is why we have to take the image tag
basically means that we are renaming our image
to include the repository domain or the address
in the name. OK, and A.W. has already gives us.
The come in that we can execute,
we want to use the specific version,
so I'm going to use 1.0 and both.
So what this is going to do is it's going to rename
this is what tech does my app 1.0.
This is what we have locally.
This is what the name is to this one here.
So let's execute that and let's see what the outcome is.
And as you see,
it took the image that we had made a copy
and renamed it into this one.
So these two are identical images.
They're just called in a different way.
And now when we go back, we see the doctor push come in.
So basically,
this thing here is the same as Docker push and name
of the image and the take.
So this push command will tell Docker,
you know what, I want to take the image.
We take 1.0 and push it into a repository
at this address. So when I execute this command,
see the push command will actually push those layers
of the docker image one by one.
This is the same thing as when we are pulling it.
We also pulled the images layer by layer
and this is what happens in the reverse
direction when we push it.
So this is also going to take a little bit.
so the push come in was complete and we should be able to see
that image in the repository now.
So if I go inside. See,
I have image tag with one point zero.
This is our tag here and. Pushed a time to digest,
which is the unique hash of that image and the image
your eye. Which is, again,
the name of the image using the the repository address,
image, name or repository name in this case and the tech.
So now let's say I made some
changes in the Docker file, you know,
let's say I renamed this home from Slash to know that.
Like this,
or what could also lead to needs to recreate
an image is obviously when I change
something in the code red. So, you know,
let's say I were to delete this line because I don't want
to console log to me in my code.
And now I have a different
version
of the application where I have
changes in the application.
So now I want to have those changes in the new Docker image.
So now let's build a new Docker image out of it.
So Docker built let's call it my app
with a version one point one and a path to a doctor file.
And I have a second image,
which is called my EP with version one point one.
So now, again,
because I want to push this to a repository,
I have to rename it to include the repository
address inside of it. So I'm going to do Dr. Teg.
The first parameter is the image that I want to rename,
and the second one is the name of that image, a new name.
So it's going to be the same as the previous one
because the repository name and the address is the same.
Remember, we have one repository for one image,
but for different versions.
So we're building a version one point one,
so it should end up in the same repository.
So now here we have one point one.
And if I take that and images, I have a second image here.
So I'm going to copy that and I'm going to do Dr.
Built.
And do not forget the tech,
it's important because it's part of the complete name, sorry,
it's Toker Push.
And now some
of the leaders that I already
pushed are they're only the ones
that changed are being pushed,
so to say and also know that I just have to do Dr.
Log-in once at the beginning and then I can.
Pull and push images from this repository as many
times as I once saw, Dr. Logan is done once.
So now that is complete. Let's actually reload this.
So my repository now has two versions.
So this is pretty practical. If you are, for example,
testing with different versions and you want to have
a history of those image tags, if you want to, for example,
test a previous version. And I think in A.W.
as the repository repository has a capacity
of holding up to 1000 image versions. So, for example,
my app here,
you can have a thousand different tags
of the same image. OK, so now again,
to compare it to the initial diagram that we saw
for this complete flow,
that's actually switched back to it quickly.
So here what we did is basically simulate how
Jenkins would push an image to a Docker repository.
So whatever we did on our laptop will be
the same commands, execute it on a doctor,
on the Jenkins server. And again,
Jenkins user or Jenkins server user has to have
credentials to the Docker repository to execute
Docker login. Depending on the registry,
a repository configuration will look different.
And Jenkins and its tag the image and then push
it to the repository. And this is how it's done.
And the next step, of course,
we need to use that image that is lying now
in the repository and we going to see how
it's pulled from that repository. And again,
we're going to do it on the local environment.
But it's the same thing.
That's a development server or any other
environment will actually execute.
So in this video,
we're going to see how to deploy an application
that we built into a Docker image,
so after you package your application
in a docker image and save it in the private repository,
you need to somehow deployed on a development
server or integration server or whatever other environment.
And we're going to use Docker Campos to deploy
that application.
So let's imagine we have logged into a development server
and we want to run our image that we just
pushed the repository.
So our my image and the mongered to be image,
both the database and the Mongar express
on the development server so that my app image will be
pulled from private repository of the in the to go
containers will be pulled from the Docker hub.
So let's see actually how that would work.
So usually again,
you have developed your application,
you're done with it and you have created your own docker image.
Right now,
in order to start an application on development server,
you would need all the containers that make up
that application environment.
So we have to be in Mongar Express already.
So what we are going to do is here we are going to add
a new container in the list,
which is going to be our own image.
So let's go ahead and copy the image from our repository.
So let's actually use the 1.0.
So, again,
remember we said that this image name
is a shortcut for having a doctor thought I ordered
thought library slash Mongul with like a specific version.
So instead of that,
because we are pulling these images from a Docker hub,
we can actually skip that repository domain
in front of the images. But here,
because we are pulling it from a private repository.
So if we were to specify our image like this,
Docker will think that our image resides on Docker Hub.
So we try to pull it from Docker Hub.
And of course,
it won't find it because we have to tell Docker,
go and look at this repository with this repost
store name in this take. And of course,
in order to be able to pull this image or the docker
composed to be able to pull this image,
the environment,
where you executing this docker compost
file has to be logged into a document repository.
So here is the development server has to pull the image
from the repository.
What we would need to do on the development server
is actually do a log in before we execute the docker compose.
And obviously,
you don't need a doctor log in for backup.
Those Mongar images will be pulled freely. OK,
so the next thing that we have to configure
are the ports because obviously want to open the ports.
If we go back,
we see that our application runs on Port three thousand,
so the port of the container or where the container
is listening on is three thousand.
And here we can open the port on the host machine.
So it's going to be three thousand to three thousand.
We have actually the environment variables
inside of the Docker file,
but obviously we could have configured them in the dock
or compose just like this. So it's an alternative.
So this will be a complete docker compose file
that will be used on a development server
to deploy all the all the applications inside. So,
again, if we're trying to simulate a development
server that the first step will be to do the doctor log in.
In this case,
you have this on command for logging into the repository,
which I have done already in this terminal.
So the next step is to have the Docker compose file
available on this development server because we have
to execute the Docker compose file because we're
simulating here.
The way I would do it is I'm going to create
a Mongo file in the current directory where I am.
I'm going to copy this.
And safe,
so now I have my mango yaml file and now we can start
all three containers using Dr. Campo's comment and it's F up.
And here we see that it started
on Three Thousand and Monga, to be an expert,
started as well.
So let's check the game now.
And here we saw the database
is lost every time we recreate
a container and of course,
that's some good and we're going to learn how to preserve
the database data when the container
restarts using docker volumes in the later tutorials,
because this is not an ideal state. OK,
so now that we have a database and a collection,
let's actually refresh in our application works as well.
Let's check.
Awesome. So our application works,
let's refresh this one as well,
and there is actually one thing that I needed
to change in the code to connect not just with Mongo DB.
So let's actually go and look at that.
These are my handlers, you know,
just where I connect to the Monga Déby database
so that your eyes are the same.
And what I changed here is that it was a localhost before,
so instead of localhost,
I changed it to Monga DB because this actually
is a name of the container or of the service
that we specify here.
So this actually leads back to the doctor network in how Dr.
Campos takes care of it.
Is that in the your eye or when I connect one
application in a container with another
one in another container,
I don't have to use this localhost anymore.
Actually, I wouldn't even need to use the port even
because I have all that information.
So the hostname and the port number in that configuration.
So my application will be able to connect Monga to be
using the service name. And because of that,
you don't have to specify here a local
host and the port number,
which is actually even more advantaged when you consider
using docker containers to run all of your applications
because it makes the connectivity
between them even more easier.
And that actually
concludes the this diagram
that we saw previously,
we have gone through all of the steps where we saw how
to develop JavaScript application locally
with docker containers.
Then we saw how to build them into an image just
like a continuous integration build will do it.
Then we pushed it into a private repository
and we simulated a development server
where we pulled the image from private repository.
In the other images from the Docker Hop,
where we started the whole application setup with our own
application in the two Mongul applications
using a Docker campus,
which is how you would deploy an application on a Web
server so that no testers or other developers will be
able to access the development server
and actually try out the application
that you just deployed.
Or you can also use it for DIMOS.
So in this video, we're going to learn about Dr.
Volumes in a nutshell, Dr. Volumes are used for data,
persistence in doctor. So, for example,
if you have databases or other stateful applications,
you would want to use Dr. Volumes for that.
So what are the specific use cases when you need
doctor volumes?
So a container runs on a host that said we have
a database container and a container
has a virtual file system where the data
is usually stored.
But here there is no persistence,
so if I were to remove the container or stop
it and restart the container,
then the data in this virtual file system is gone.
And it starts from a fresh state,
which is obviously not very practical because I want
to save the changes that my application is making
in the database, and that's where I need volumes.
So what are the Docker volumes exactly? So on a host,
we have a physical file system. Right.
And the way volumes work is that we plug
the physical file system. Perth. Could be a folder, a directory,
and we plug it into the containers
file system. So in simple terms,
a directory folder on a host file system is mounted
into a directory of folder in the virtual
file system of Docker.
So what happens is that when a container
writes to its file system,
it gets replicated or automatically written
on the host file system directory and vice versa.
So if I were to change something on the host
file system,
it automatically appears in the container as well.
So that's why when a container restarts,
even if it starts from a fresh start in its
own virtual file system,
it gets the data automatically from that from the host
because the data is still there.
And that's how data is populated on the up
of a container every time you restart. Now,
there are different types of docker volumes
and so different ways of creating them.
Usually the way to create Docker volumes
is using Docker Run Command.
So in the document there's an option called minus V,
and this is where we define the connection
or the reference between the host directory
and the container directory.
And this type of volume definition is called
host volume.
And the main characteristic of this one
is that you decide where on the host file
system that references made.
So which folder on the host file system
you mount into the container.
So the second type is where you create a volume just
by referencing the container directory
so you don't specify which directory on the host
should be mounted.
But that's taking care of the docker itself.
So that directory is, first of all,
automatically created by Docker under the Varly Docker volumes.
So for each container there will be a folder
generated that gets mounted automatically to the container.
And this type of volumes are called anonymous
volumes because you don't have a reference
to this automatically generated folder. Basically,
you just have to know the path.
And the third volume type is actually an improvement
of the anonymous volumes and it specifies the name
of that folder on the host file system
and the name is up to you.
It just to reference the directory and that type
of volumes are called named volumes. So in this case,
compared to anonymous volumes,
you you can actually reference that volume just
by name so you don't have to know exactly the path.
So from these three types,
the mostly used one and the one that you should be
using in a production is actually the named
volumes because there are additional benefits
to letting Docker actually manage those
volume directories on the host.
Now they showed how to create Docker volumes
using Docker run commands.
But if you're using Docker Campo's,
it's actually the same.
So this actually shows how to use volume definition's
in a dark recomposed,
and this is pretty much the same as in Docker run commands.
So we have volume attributes and underneath
you define your volume definition,
just like you would in these miners.
We option and here we use a named volume.
So DBE the data will be the name reference name
that you can just think of. Could be anything and inva.
The my school data is the path in the container.
Then you may have some other containers and at the end.
So on the same level as the services
you would actually list all the volumes
that you have defined.
You define at least the volumes that you want
to mount into the containers.
So if you were to create volumes for different containers,
you would list them all here and on the container level,
then you actually define and which path that specific
volume can be mounted.
And the benefit of that is that you can
actually mount a reference of the same folder on the host
to more than one containers,
and that would be beneficial if those
containers need to share the data. In this case,
you would want the same volume name or reference to two
different containers and you can mold them
into different path inside of the container even.
In this video, we are going to look at Dr.
Volumes in practice,
and this is a simple no just to be application
that we are going to attach the volume to so that we don't
lose the database data every time we restart the container.
So let's head over
to the console and I'm
going to start the Monga
debate with the Campos,
so this is how the campus looks like.
We're going to start the Mongar debate on container
in the Mongul express container so that we have
a UI to it. So I'm going to execute the Dr.
Campos.
Which is going to start to be
in the Mongar express.
So when he started,
I'm going to check that Mongol Express is running
on Port 80 80.
And here we see just the default databases.
So these are just created by default on startup.
And we're going to create our own one for
the No JS application. And inside of that database,
I'm going to create user's collection.
So these are the prerequisites or these are the things that my
Narges application needs. So this one here.
In order to connect to the database, my DP,
this is what we just created,
might be an inside of that to the collection
called users, so they start the application.
Which is running on three
thousand here.
And this is our EP,
which when I read something here.
Will write the changes
to my database. Now, if I were to restart now,
the Hmong would be container. I would lose all this data,
so because of that,
we're going to use named volumes inside
of the Dr Campos file to persist all this data in the Mungindi.
Let's head over to the campus.
So the first step is to define what volumes I'm going to be
using in any of my containers and I'm going to do
that on the services level.
So here I find the list of all the volumes that I'm going
to need in any of my containers.
And since we need data persistency for Monga to be,
we're going to create Mongul data volume here. Now,
this is going to be the name of the volume reference,
but we also need to provide here a driver local.
So the actual storage pairs that we're going to see later,
once it's created,
it is actually created by Tokura itself.
And this is a kind of an information,
additional information for Docker to create
that physical storage on a local file system.
So once we have a name reference to a volume defined,
we can actually use it in the container. So here.
I'm going to say volumes. And here,
I'll define a mapping between the Mongo data
volume that we have on our host,
and the second one will be the path inside of the Mongar
to be container.
It has to be the path where Mongar to explicitly
persist its data. So, for example,
if you check it out online.
You see that the default path where Monga be stores,
its data is data slash,
data slash deep and we can actually check that out.
So if I say Dunkerque s and go inside the container.
It's minus I t.
I can actually see the data deep in here is all the data
that Mongo DB actually holds, but this is, of course,
only the container. So in the container restarts,
the data get regenerated. So nothing persists here.
So this is the path inside of the container,
not on my host that we need to reference in the volumes here.
So we're attaching our volume on the host to data slash data
slash deep inside of a container. So,
for example, for my school,
it's going to be for my school for postgrads.
It's also going to be whateva Leape PostgreSQL data so each
database will have its own.
So you'd have to actually find the right one.
So what this means is that all the data that we just saw here,
all of this will be replicated on a container
stored up on our host on this persistent volume
that we defined here and vice versa,
meaning when a container restarts,
all the data that is here will be
replicated inside of that directory,
inside of a container.
So now that we have defined that,
let's actually restart the document post.
And. We started.
So once we create the data.
And I'm going
to the collection and let's
actually change this one.
All here.
And update it so we have the data here.
So now that we have
the persistent volume defined,
if I were to restart all these containers,
these data should be persisted soon.
The next restart,
I should see the database might be
collection and the entry here. So let's do that.
I'm going to do.
Great, so let's check. See, the database is here,
the collection is here, and the entry has persisted.
So now let's actually see
where the doctor volumes
are located on our
local machine,
and that actually differs between the operating systems,
for example,
on a Windows laptop or a computer,
the path of the Docker volume will be its
program data docker volumes.
The program data Docker folder actually contains all
the other container information.
So you would see other folders in the Docker directory.
Besides the volumes on Linux,
the path is actually for leap volumes,
which is comparable to the Windows pad.
So this is where the docker saves all
this configuration and the data. And on the Mac,
it's also the same one inside of this volumes directory.
You actually have a list of all the volumes that one
or many containers are using,
and each volume has its own hash,
which is or which has to be unique and then slash
underscore data will actually contain all the files and all
the data that is persisted.
Let's head over to the come in line and actually
see the volumes that we persisted for longer.
Now, an interesting note here is that if I were to go
to this path that I just showed you in the presentation,
which is var leave docker,
you see there is no such a directory.
So that could be a little bit confusing.
But the way it works on MK, specifically on Linux,
you would actually have that PEV directly on your host,
but then make it a little bit different.
So basically what happens is that docker for mech
application seems to actually create a Linux VM
in the background and store all the Docker
information or Docker data about the containers and the volumes,
et cetera, inside of that VMS storage.
So if we execute this command here.
So this is actually the physical storage
on my laptop that I have where all the data is stored.
But if I execute this command,
I actually get the terminal of that VM. And inside here,
if I look,
I have a virtual different virtual filesystem.
And I can find that path that I showed you here,
so it's Vare Leap, Dr. See,
so I have all this stock information here.
I have the containers folder and I have
volumes folder. So this is the one we need.
Some of those actually go to the volumes,
and this is a list of volumes that I have
created and this is the one that came from our who compose,
right? This is the name of our F this is this is what Dr.
Campos actually takes as the name.
You can actually take a look here.
So when it's creating these containers,
it depends this name as a prefix.
And then there is Mongo to be in our
volume has the same pattern.
It has the prefix and then mongered data.
This is the name that we defined here.
So now if we look inside of that Monga data
volume directory.
We see that underscore data.
This
would be the anonymous volumes,
so basically here you don't have a name reference,
it's just some random unique ID,
but it's the same kind of directory as this one here.
The difference being that this one has a name.
So it's more it's easier to reference it with a name.
So this is anonymous volume. This is a name volume.
But the contents will be used in the same way.
So here is you see in this underscore data,
we have all the data that Mongered uses.
So this will be where it gets thirtyfold,
databases and the changes that we make
through our application inside.
And if I go inside of the containers. Remember,
this volume is attached to.
Mongo DB and is replicated inside of the container,
underpays data slash Debe,
so if we go inside of the container. Actually,
right here.
Yes.
They should be we'll see
actually the same
kind of data here,
so we have all this index and collection files just
like we did in this one.
So now whenever we make changes to our application,
for example, we change it to Smith and.
This will make the container update its data and that will
cascade into these volumes directory that we have
here so that on the next stop of a container,
when the data SDB is totally empty,
it will actually populate this directory with the data
from this persistent volume so that we will see all
the data that we created through our
application again on startup. And that's how volumes work.
In order to end that screen
session that we just started,
because it doesn't work in this case,
somehow on Mac,
you can actually click on control a key
and then just type Y. And the session will be closed.
So when you do screen Ellis,
you should see actually it's terminating.
Congratulations. You made it to the end.
I hope you learned a lot and got some valuable
knowledge from this course.
Now that you've learned all about containers and technology,
you can start building complex applications with tens
or even hundreds of containers. Of course,
these containers would need to be deployed across multiple
servers in a distributed way.
You can imagine what overhead and headache
it would be to manually manage those hundreds of containers.
So as a next step, you can learn about container,
orchestration, tools and communities in particular,
which is the most popular tool to automate this task.
If you want to learn about communities,
be sure to check out my tutorials on that topic
and subscribe to my channel for more
content on modern day tools. Also,
if you want to stay connected,
you can follow me on social media or join
the private Facebook group. I would love to see you there.
So thank you for watching and see you in the next video.