How Docker Makes Your Life Easier. Say hello to productivity.

Get started with Docker and see how it can revolutionize your web development workflow.

What is Docker? Imagine you have a big lunchbox called Docker. Inside this box, you can put smaller containers, each with its own job to do. These containers are like little workers, and they only know how to do one thing really well.

The Docker approach is all about keeping these containers small and focused, like giving each worker a specific task to do. This way, they don't get confused or waste time trying to do things they're not good at.

When you run a Docker container, you're basically giving a specific job to one of these workers. And just like in real life, if you need another worker to do a different job, you can easily get a new container for that task. This makes things efficient and easy to manage, just like having a team of specialized workers in your big box of Docker.

Also, the cool thing about Docker is that it makes sure your web application works the same way no matter where it's running. Whether it's on your computer, a friend's computer, or a big server, Docker keeps everything consistent so there are no surprises. You can add Apache config files, such as those found in sites-available, to the Docker image of your app to configure subdomains. To avoid configuring the web server twice, add the "COPY" and "RUN" commands to your Dockerfile. This way, the configuration is included in the image and applied when the container is started.

In this article, I'll teach you about Docker and how it can change the way you do things. By learning Docker, you can make your work more efficient and organized. It's a valuable skill that can open up new opportunities in the world of technology.

In this article, we will:

  • We'll start by installing Docker.
  • We'll take a special folder called /dist from our React boilerplate project and use it to create a Docker image. This image contains everything our app needs to run, like its code and settings.
  • Once we have our Docker image, we'll use it to run a Docker container. Think of a container as a small, self-contained package that contains our app. We'll then be able to see our web app in the browser.
  • We'll also learn a few Docker command-line interface (CLI) commands. These commands help us manage our Docker containers and images.
  • We'll learn how to see the contents of a Docker image. This can help us understand what's inside and how it works.
  • Finally, I'll briefly touch on Docker Machine and Docker Swarm.

Let's get Docker installed! But before we do that, we need to prepare our system (I use Ubuntu). This involves updating the package index to ensure we have the latest information about available packages. We also need to install some additional packages that Docker requires to function properly. Next, we'll add Docker's official GPG key to verify the integrity of the packages we download. After adding the GPG key, we'll set up the Docker stable repository that is suitable for production use. It allows us to easily download and install Docker using the apt package manager.

sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update

Now we can install Docker CE (Community Edition):

sudo apt-get install docker-ce
docker info

Verify that Docker is installed correctly by running the hello-world container:

sudo docker run hello-world

Now, let's take the /dist folder and server.js from one of my previous articles, and update the package.json to ensure the Docker will install the modules we need for production (Express & React).

{
    "name": "whatsupworld",
    "version": "1.0.0",
    "keywords": [],
    "author": "",
    "license": "MIT",
    "dependencies": {
    "express": "^4.18.3",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
    }
}

In the same folder, where we have server.js and package.json, we need to create a file named Dockerfile (no file extension) with the following content:

    FROM node:10
    WORKDIR /dist
    COPY package*.json ./
    RUN npm install
    COPY . .
    EXPOSE 3000
    CMD ["node", "server.js"]

Check "node -v" and update the above file with the appropriate Node version (I have v10.19.0 on my VM).

Create your Docker image:

docker build -t my-react-app-image .

To see all docker images:

docker images -a

The result:

REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
my-react-app-image   latest    af05e728c1ef   10 seconds ago   928MB

Now, let's run the Docker container:

docker run -d --name my-react-app-container -p 3000:3000 my-react-app-image

This command will start a container in the background (-d), give it a name (--name), and map port 3000 on your host machine to port 3000 in the container (-p).

Don't forget the name!! Otherwise, the Docker will give your container a silly name like "stoic_elbakyan" or "vibrant_bouman".

To run your Docker image and bind it to the IP address of your VM (for instance, 192.168.161.20), you need to use the -p flag to specify the port mapping. Alternatively, you can use a hostname instead of an IP address when running a Docker container and binding it to a specific port. Assuming your Node.js application listens on port 9001 (as specified in your server.js file), you would run the following command:

docker run -d --name my-react-app-container -p 192.168.161.20:9001:9001 my-react-app-image

If you open the web browser, you'll see:

A few useful Docker CLI commands:

docker stop my-react-app-container
docker rm my-react-app-container

To check if a Docker container is running:

docker ps -a

The result:

CONTAINER ID   IMAGE                COMMAND                  CREATED          STATUS          PORTS                                     NAMES
20ed89903cbc   my-react-app-image   "docker-entrypoint.s…"   16 seconds ago   Up 15 seconds   3000/tcp, 192.168.161.20:9001->9001/tcp   my-react-app-container

To see what is inside a Docker image, you can use the docker run command with the --rm flag to run a temporary container from the image and explore its contents:

docker run --rm -it my-react-app-image /bin/bash

Once you're inside the image (you'll see you are inside of the /dist folder), you can explore its filesystem using standard Linux command:

ls -la

Updating the app is also pretty straight forward. To update the web app with the new changes, you first need to stop the old version of your app that's currently running. Then, you can use the new Docker image you created to start a new version of your app. You can read my article "CI/CD Made Easy. A step-by-step simple guide." and automate these steps using CI/CD (Continuous Integration/Continuous Deployment) pipeline like GitHub Actions.

Now, I want to say a few words about Docker Machine and Docker Swarm. Of course, you don't necessarily need Docker Machine or Docker Swarm if you're comfortable using commands like "docker run", "docker stop", "docker rm", and other Docker CLI commands to set up and manage your Docker environment. You can stick to using these commands. These commands are sufficient for basic Docker operations, such as running and managing containers on your local machine.

Docker Machine is more useful when you need to set up Docker on multiple machines or on remote servers, as it simplifies the process of creating and managing Docker hosts. If you're only working with Docker on your local Ubuntu machine (if this is your host), you can manage everything with the Docker CLI (Command Line Interface) without needing Docker Machine.

Similarly, Docker Swarm is helpful for managing clusters of Docker hosts and orchestrating containers across them. If you're not working with a large-scale application that requires container orchestration, you can manage your containers using basic Docker commands on your Linux machine.

Good luck!
May all your endeavors be successful, and may your code always run smoothly.
Best Regards,
Artem

407