An introduction to Docker using React.js
Open your default command-line client; it is Terminal in my case. Type the following command to create a new development folder and access it.
mkdir dev && cd dev
The command below will run Docker in interactive mode,
-it flags, the Linux Alpine and runs the
sh command. Docker will download the alpine image to your local machine in case you don’t have it.
$ docker run -it alpine sh
You would be presented with alpine’s
sh shell mode if the command ran without an error, which means you’re in a terminal of a Linux running inside a container. It was all accomplished within few seconds. Incredible! You can check the folders and files pulled with the following command
Here’s a screenshot of mine:
You can type
exit in the terminal to exit and stop the container.
Nugget: They built Docker for Linux, but now it is native to Windows as well. However, Mac requires VM running in the background for it to emulate the host. The only thing is, it is much lighter than using Virtual Machines.
So, why did we use Alpine as a Base Docker Image?
Simply put, you want to shrink your Docker images, start services faster and secure your application. Alpine 3.6 Dockerized version weighs a little less than 4MB; it sits at 3.98MB.
You can compare it to other popular Linux distributions:
Amazeballs! Size does matter, and Alpine is about 30x smaller than Ubuntu. Also, you can perform additional tests by downloading the Base Image on a new machine.
$ time docker run --rm -it alpine sh -c "apk add --no-cache gcc" ... real 0m 4.62s user 0m 0.02s sys 0m 0.04s
$ time docker run --rm -it ubuntu sh -c "apt-get update && apt-get install -y gcc" ... real 0m 14.66s user 0m 0.02s sys 0m 0.05s
Alpine is 3x faster than Ubuntu with a 4.62 real life seconds wait time compared to Ubuntu’s 14.66 seconds. It is time too valuable to be wasted just for a programming test.
You can clone/download this project from Github, it is an integral part of the next few steps. The project consists of two folders; one is for a simple server while the other is for a web application. We need to create a Dockerfile in the root of the web application. You can read the Docker documentation for an extended overview.
We need to set a starter image for our application in the Dockerfile. Since it is a React web application, an installed Node.js environment ought to be sufficient. DockerHub has a Node.js image that we can pull.
The command above will start with node:9.8.0 image. It will install Node.js version 9.8.0 on a Linux distribution, in our case, Alpine. The entire Dockerfile commands are:
FROM node:9.8.0 # This command will create a directory called "web-app" inside "usr" in a container RUN mkdir -p /usr/web-app # Set the working directory of our web app to the newly created directory WORKDIR /usr/web-app # Copy all the files from current directory to the new one in the container COPY . /usr/web-app # Install node dependencies RUN npm install # Define a command to execute when the container starts CMD npm start
Now that our Dockerfile is ready to embark on its new adventure. You can go ahead and run the application in a container.
$ cd webapp $ docker build -t web-app .
It is time for a freshly brewed coffee as it will take some time for the Node image to download. The
build in the command above will build the image based on the Dockerfile that’s inside the
-t tags the image with the name
$ docker images
The command will list all the available images,
web-app is the only image listed in our case. Let’s run our new app.
$ docker run -d --name web-app-container -p 3000:3000 web-app
You can now access the app in your default browser by following this URL
http://localhost:3000. By specifying the
d flag in the command, it is running in a non-interactive mode. We named the container with
--name web-app-container and mapped it to a port using
-p in this format
The web app cannot retrieve data from the node service because it is currently not running. Let’s stop the container and create a new Dockerfile for the service.
$ docker ps
The command will list all the containers running, and you can include the
-a flag to list all the containers we have created.
$ docker stop <container-id-listed-on-ps>
Use the following commands to create a new Dockerfile in the root folder of the node service:
FROM node:9.8.0 RUN mkdir -p /usr/node-service WORKDIR /usr/node-service COPY . /usr/node-service RUN npm install CMD npm start
We can now build, run the node service container and reload the web app to see if it’s retrieving any data.
$ cd ../node-service $ docker build -t node-service . $ docker run -d --name node-service-container -p 8080:8080 node-service
Absolute beauty! Your containers are fully functional and can talk to each other. If you want to delete a container or an image, you can use the following commands:
$ docker rm <containerID> # use this for containers $ docker rmi <containerID> # use this for images
Also, if you want to run a container in bash or interactive mode, combine the
-it flag and
bash together in your command. Here’s an example:
$ docker exec -it <containerID> bash
There is still so much to learn, but we have an excellent foundation on how to use Docker for containers. A la prochaine! ✌🏽