We’ve all heard the dreaded words, “But it works on my machine.” Whether simple or complex, dependencies are an integral component of any development environment.
A slightly different version or installation of a dependency can cause drastic issues with your development. That’s where Docker comes in.
Docker facilitates the building and shipping of applications across machines consistently. In today’s article, we’re going to build and use your first Docker image. While it may seem like an unnecessary step for your personal projects, docker is essential for any development team.
What is Docker?
Docker is a platform that enables you to manage your application's development, running, and shipping independent of the infrastructure you are using. Docker uses isolated environments with app-specific dependencies installed to run applications. These isolated environments are known as containers.
Docker gives us the ability to run multiple containers at the same time. Since they are isolated, we don’t need to worry about containers interfering. Thus, Docker containers can simultaneously have different software versions running in different isolated environments. The added benefit is that we don’t need to clutter our host machine with multiple versions of the same software.
Docker containers are built by following pre-written instructions. These instructions are written as part of a Docker image. A Docker image is a template created by the developer, and it contains the application code, libraries, tools, and other dependencies required to run the application inside a Docker container, making the Docker image portable and platform-independent.
Docker images open for public use are available on Docker Hub (https://hub.docker.com/).
Follow the instructions on https://docs.docker.com/engine/install/ to install the Docker engine on your computer. Make sure to check that your machine meets all the requirements. At the same time, we recommend that you sign up here: https://hub.docker.com/signup, to be able to publish your docker images on to Docker hub.
Installing the Docker engine also installs a GUI and Docker CLI. You can use the Docker CLI from your system’s terminal directly. When opened for the first time, the Docker GUI also gives a small tutorial. To use the Docker CLI, we need to learn its basic commands.
Docker commands always take the latest version by default. If you need a different version, you can add a “:<version-number>” after the name.
docker ps - Lists all the containers currently running. Adding the -a attribute also lists the exited containers.
docker pull - To download an image from Docker hub. It takes the image name as a parameter.
docker run - Runs a new container. It takes an image name as a parameter. If an image isn't available locally, it checks the Docker hub repository, downloads, and runs the image.
docker stop - Stops a running container. It takes in the container id or container name as a parameter.
docker start - Starts a stopped container. It takes in the container id or container name as a parameter.
docker build - Builds a new docker image. It takes the image name and version as parameters.
docker images - Lists all images available on the local machine.
docker rm - Removes a container from the containers list. It takes in the container id or container name as a parameter.
docker rmi - Removes a local image from the machine. It takes the image id as a parameter. Make sure to remove all containers related to the image file you are removing.
We can also use the Docker GUI for the above commands, as shown below.
- Opens the web application in the browser.
- Opens the interactive terminal for the container.
- Stops the container.
- Starts/restarts the container.
- Deletes the container.
Building a Docker image
We will build a Docker image for a NodeJs application for our demo. It is a simple To-Do list and will use an Express-based server.
Here’s the code for our project
Before creating the Dockerfile image, we need to test our application locally to ensure it works. You can download the above code and run it locally by running node server.js from the terminal. You should be able to open the webpage in the browser using localhost:3000. Once we are sure the application works fine, we can create our first Docker image like so:
- Create a folder and copy the source files(index.html, script.js, and server.js) and the package.json file inside it.
- The Docker engine needs a Dockerfile containing the steps to build the image to create a Docker image. We need to create this file. You can create this file anywhere on your machine but using the same folder as the source files makes things easier.
- We need to create a new plaintext file and name it Dockerfile. Dockerfile doesn’t have any extension.
- The Dockerfile used to create the demo-app image is available below
- The first line of the Dockerfile instructs the Docker engine to start with the base image of node:17.6-alpine. This image is available on Docker hub. Alpine is a Linux distro small in size that helps keep the resulting image size small.
- Line two changes our working directory to /home/demo_app/ inside the environment. Please note that now the environment is Linux, so we need to follow Linux naming conventions.
- Next, we copy the package.json file from the source files folder to the current working directory. This file will be used in the next step to install the required dependencies.
- Now we run the npm install command, which installs all required dependencies.
- Then we copy all the source files to our working directory.
- Finally, we execute the command node server.js to run our application inside the environment.
5. We run the following command in the terminal to build this Docker image.
docker build -t demo-app:1.0 .
demo-app is the image name, and the version is 1.0
6. We need to run the image to create a Docker container and test our app. Create a Docker container from the image using the following command
docker run -p 3000:3000 --name demo demo-app:1.0
The -p adds a host port which we can use with localhost to access our web application. The —name attribute gives a name to the container and helps us run commands on the container.
If everything goes fine, we can access the web application in our browser using localhost:3000
7. We can see our container details by running docker ps in a separate terminal.
And there you have it! We created a Docker image from scratch and ran a container inside the terminal using that image.
You can even take it a step further and publish it on Docker hub to let other Docker users use it or just to show it off to friends. Similarly, you can build larger applications and use Docker to deploy them online.
Now the next step for a lot of development teams is deploying your application with this image – But most cloud providers make this process extremely difficult. That’s why at Codesphere, we’re building a cloud provider that can run any app you throw at it!