Docker For Beginners — Part 2
What is a Dockerfile, Image and Container?
* This article continues from Docker For Beginners article; for ease of following, I highly recommend starting by reading Docker For Beginners, which is where we begin as part 1.
Dockerfile
A Dockerfile is a text file containing a list of instructions/commands executed successively to create a Docker Image. Docker can build docker images automatically by reading the instructions, essentially a list of command-line interface (CLI) instructions from this Dockerfile.
Docker Image
Docker Image is a read-only template that contains the application code, dependencies and a set of instructions for creating a docker Container that can run on the docker platform. The image is run to create a container in which the application runs, and you can create as many containers as you wish from a single image.
Docker Container
A Docker Container is a running instance of a Docker Image. It is an Application sandbox, where a packaged executable unit of software and its libraries and dependencies is run. It can be run anywhere on a desktop, in traditional IT, or in the cloud and users can interact with the container and adjust its settings and conditions using docker commands.
Docker images can be created by using one of two methods:
- Interactive: We start a container from an existing Docker image, manually assign container environment variables to the image, and save the image's state as our new image.
- Dockerfile: Creating a Dockerfile provides the instructions/commands for building a Docker image.
For real-world, enterprise-grade container deployments, the Dockerfile methodology is the preferred way. It is a more systematic, flexible, and efficient method of creating Docker images, and it is the key to compact, dependable, and secure container environments. In this article, we will do our hands-on using this Dockerfile method to containerize a NodeJs application.
Here is what you need to have installed on your laptop to follow along with the Hands-On. Install NodeJs, Docker and VS Code.
- NodeJs — This is to be able to build and run NodeJs application.
- Docker — To be able to Containerize application (build images, run Containers etc).
- Visual Studio Code — This is my preferred code editor, but you can use whatever you have available.
Hands-On!✍
Creating Application
First, we must create a simple NodeJs application, something very basic, which we will Containerize. Here is a walkthrough;
mkdir docker && cd docker
npm init -y
npm install express
- Create a docker folder where all the code will reside. All the CMD commands in this tutorial article should be run in this docker folder.
- Initialize our NodeJs application. It will create a package.json file in this docker folder.
- Install the necessary dependencies needed for the application. For our application, we’ll use Express as our dependency. Run
npm install express
to install Express. That should auto-create a node_modules folder and a package-lock.json file. - Create an index.js file in the docker folder. This index.js should contain a simple NodeJs application server like the one shown below or similar.
We now have our project. Let's run it locally before we containerize it.
node index.js
Run node index
on the terminal, this should log 'Server is listening at http://localhost:3000' as shown below. You can also test this on the browser at http://localhost:3000. The browser should display 'Hello World!'.
Containerizing Application
Now, let's get docker HANDS ON!
- Create a Dockerfile file in the docker folder. This Dockerfile contains instructions or commands that Docker reads to build our image when we instruct it to build an image from this Dockerfile. The Dockerfile has no file extension. Copy the commands/instructions into your Dockerfile in it and save it.
- Create a .dockerignore file. This file will contain the list of files and folders the docker should ignore when copying the application code (files and folders) onto the docker image. For this application, the .dockerignore file should have the below content:
node_modules
Build an image
- Instruct Docker to build an image named node_app. Run the
docker build -t node_app .
- The
-t
optional tag gives the image a name, the.
tells Docker to look for the Dockerfile in the current directory where this command is being run. If you had your Dockerfile in a different path, you'd have to use a-f
flag to provide that file path.
docker build -t node_app .
Run an image
- Instruct Docker to run the node_app image we previously built. This builds a container or a running instance of the docker image.
docker run --name node_app -p 4000:3000 node_app
docker run --name node_app -p 4000:3000 node_app
Let's look at the above command in detail;
--name node_app
This is used to give the name to the container that will run from the image. In this case, the container is named node_app.
Notice that our Container has the same name as our Image name. That’s fine since one is an Image and the other is a Container, so they don’t conflict.
-p 4000:3000
This is known as port mapping, making the processes/applications inside the container available from the outside. Port 4000
is where the application will be accessible outside the container, which is also the port exposed in the Dockerfile. And port 3000
is the port the application runs inside the container; in our index.js, it is passed to the server to listen to this port 3000
node_app
This is the name of the image from which the container (running instance of the image) will be created. When we built the docker image, we used the -t
tag to give the image a name. So the name given to the image is what we are providing to the docker run command. *It's the best practice to give images and containers a name when working with them.
You should see a similar output after running the docker run command as in the below screenshot.
We can see that our container is running. The NodeJs application also seems to be running, as seen in the logs. But let’s test this on the browser this time at http://localhost:4000. ‘Hello World!’ should be displayed as seen below. The application is now accessible on port 4000.
We have successfully built a simple NodeJs application, and we’ve containerized this application and are now able to run it in Docker. To stop the running container, use the docker stop node_app
command, and you can re-run the container with docker start node_app
10 useful Docker commands
Informational
docker ps
List all running containers. Add the -a flag to get a list of the stopped containers.docker logs
List the logs from a running container.docker image ls
List all locally stored images.
Container Management
docker create <Image_Name>
Create a container without starting it.docker run <Image_Name>
Create and start a container.docker start <Container_Name>
Start running a container.docker stop <Container_Name>
Stop a running container.docker rm <Container_Name>
Delete a container that isn’t running. Use the — force flag to delete a running container.docker rmi <Image_Name>
Remove an image.docker pull <Image_Name>
Pull an image from a registry.docker push <Image_Name>
Push an image to a registry
There is quite a lot to explore with docker, and we can’t explore all there is in one article, but I hope you found this helpful and fun to read. Thank you for reading.🙌🏾