- Introduction and Application Architecture
- Setting up the React Application
- Setting up the Spring WebApplication
- Setting up the Python Application
- Container-ization of the Services
- Container-ization of everything else
- Introduction to Kubernetes
- Kubernetes in Practice – Pods
- Kubernetes in Practice – Services
- Kubernetes in Practice – Deployments
- Kubernetes and everything else in Practice
- Kubernetes Volumes – in Practice
Kubernetes is a container orchestrator, or how you are more likely to read about it, Kubernetes does Container Orchestration, a term that we will read about in upcoming articles, but now without further due let’s create Containers Images for our Services.
Containerizing the React Application (Docker intro)
A Dockerfile contains all the instructions needed to build a container. And it starts with a base image and follows up with a sequence of instructions on how to build a container image, that fits your needs. Before we get started defining the Dockerfile, let’s remember the steps we took to serve static files with nginx:
- Build the static files (npm run build)
- Startup the nginx server
- Copy the contents of the build folder from your sa-frontend project to nginx/html.
In the next section, you will notice parallels on how creating a Container is similar to what we did during local React setup.
Defining the Dockerfile for SA-Frontend
The instructions in the Dockerfile for the SA-Frontend is only a two-step task, and that is because the Nginx Team provided us with a base image, which we will use to build on top of. The two steps are:
- Start from the base Nginx Image
- Copy the sa-frontend/build directory to the containers nginx/html directory.
Converted into a Dockerfile it looks like this:
FROM nginx
COPY build /usr/share/nginx/html
Isn’t it amazing, it’s even humanly readable, let’s recapitulate:
Start from the nginx image (whatever the guys did over there) and copy our build directory to the nginx/html directory in the image. That’s it! And how do I know where to copy the build files? Because it was documented in the nginx image.
The Dockerfile defines how to build the container image, in the next sections we will build and push the image to the Container Registry (DockerHub).
Building and Pushing the container
Before we can push our image we need a Container Registry to host our images. Docker Hub is a free cloud container service that we will use for this demonstration. You have two tasks before continuing:
- Register to the Docker Hub.
- Login by executing the below command in your Terminal:
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
After completing the above tasks navigate to the directory sa-frontend and execute the below command (replace $DOCKER_ID_USER with your docker hub user)
$ docker build -f Dockerfile -t $DOCKER_ID_USER/sentiment-analysis-frontend .
We can drop -f Dockerfile
because we are already in the directory containing the Dockerfile.
To push the image, use the docker push command:
$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend
Verify in your docker hub repository that the image was pushed successfully.
Running the container
Now the image in $DOCKER_USER_ID/sentiment-analysis-frontend
can be pulled and run by anyone. To pull:
$ docker pull $DOCKER_USER_ID/sentiment-analysis-frontend
To run:
$ docker run -d -p 80:80 $DOCKER_ID_USER/sentiment-analysis-frontend
The 80:80 is confusing, let’s elaborate it:
- The first 80 is the port of the host (i.e. my computer)
- The second 80 stands for the container port to which the calls should be forwarded.
It maps from <hostPort> to <containerPort> meaning that calls to host port 80 should be mapped to the port 80 of the container, as shown in figure 1.
Because the port was run in the host (your computer) in port 80 it should be accessible on the localhost:80, or if you do not have native docker support you can open the application in <docker-machine ip>:80.
To find your docker-machine ip execute docker-machine ip
😉 If you set up everything correctly then you should be able to access the react application in that endpoint.
The Dockerignore
We saw earlier that building the image for SA-Frontend was slow. That was the case because of the huge build context that had to be sent to the Docker Deamon. In more detail, the build context represents all the data in the directory of the Dockerfile that will be needed to build the image. And in our case, the SA Frontend included the following folders:
sa-frontend: | .dockerignore | Dockerfile | package.json | README.md +---build +---node_modules +---public \---src
But the only data we need is in the build folder, then uploading anything else will be a waste of time and we can improve our build time by dropping the other directories, and that’s where .dockerignore
comes into play, for you it will be familiar because it’s like .gitignore
, i.e add all directories that you want to ignore in the .dockerignore file, as shown below:
node_modules src public
And another important thing is that the .dockerignore file should be in the same folder as the Dockerfile. (i.e. it should be in the build context).
Now building the image takes only seconds.
Conclusion
We learned about the Dockerfile, how to use it to build an image, and the commands to push it to the Docker registry. Additionally, we investigated on how to reduce the number of files sent to the build context by ignoring useless files. In the next article, we will build and push the image for the Java Application and the Python Application.
I encourage you to go through the next article where we will cover containerizing the two applications, a couple of more docker features, and in the end testing that everything works together.
If you enjoyed the article, please share and comment below!