-
Notifications
You must be signed in to change notification settings - Fork 0
Docker
In this section we will see everything related to Docker, from the installation of Docker in our local machine to the creation of images from a Dockerfile and the creation of docker-compose files for the deployment of our containers.
The idea behind Docker is to create light and portable containers for the software applications that can be executed in any machine with Docker installed, independently of the operating system that the machine is working with, facilitating also the deployments.
Docker allows me to put into a container everything that my application needs in order to be executed. So, I can take this container to any machine with Docker installed and execute my application with no need of doing anything else. I will execute mi application from the Docker container, and inside of it I will find all the libraries and things that my application needs in order to work correctly.
The first thing that we need in order to create and launch our Docker images is installing Docker's application from its web page, available in the following link. Once we have the file downloaded, we will make double click on it to execute the installer. Just follow the steps in the wizard installer until the installation is finished.
Now we have Docker installed in our machine, but if we try to execute it the Docker server would not be able to connect as we need to install a Linux subsystem in our computer. For this we will follow this steps:
Open PowerShell as administrator and execute the following order:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
Open PowerShell as administrator and execute:
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Restart the machine to complete the WSL installation and the WSL2 update.
-
Download the latest version: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
-
Execute the update package downloaded in the previous step. (Double click on it to execute the package. Elevated permits will be asked. Select "Yes" to approve the installation).
Open PowerShell as administrator and execute the following order to establish the WSL 2 version as the predefined when installing a new Linux distribution:
wsl --set-default-version 2
-
Open Microsoft Store and select your favorite Linux distribution.
-
In the distribution page, select "Get".
-
Start the distribution, you will have to create a username and a password for the new Linux distribution.
Once the Linux distribution is installed, simply restart the Docker application and you will be able to see that the server is now "Running".
Now that we have Docker installed in our machine and it works correctly, we are going to start creating the images of our application.
In order to create this images we are going to use some files called "Dockerfiles" which we will need to create. We will need to create a Dockerfile for the Angular side of our application and another Dockerfile for the Java side. We will be starting with the fron-end part.
First, what we need to do is place ourselves in the angular directory of our project.
C:\...\workspaces\main\jumpthequeue\angular
Here, we are going to create a new file called Dockerfile, without any extension. Inside C:\...\worspaces\main\jumpthequeue\angular\Dockerfile
we will add the following code:
FROM node:10-alpine as build-step
RUN mkdir -p /app
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
RUN npm run build
#NGINX
FROM nginx:latest
COPY --from=build-step /app/dist/angular /usr/share/nginx/html
Now we are going to explain what each of these orders do:
-
FROM
Specifies the Docker image that we are going to use (node:10-alpine
). -
RUN
Executes the specified. In this case:mkdir -p /app
(create a new directory). -
WORKDIR
Specifies the directory where we are going to work. In this case the directory that we have just created. -
COPY
Executes the copy order. In our case we are copying the filepackage.json
from the application into the new work directory. -
RUN
Executes the ordernpm install
in order to install the application dependencies. -
COPY
Executes the order of copying everything that is the actual directory into the new directory. -
RUN
Executes the ordernpm run build
. Which creates a folder calleddist
with all the compiled classes of our application. -
FROM
Specifies that we are now going to use the imagenginx:latest
(as it is the server that we will use to launch our application). -
COPY
Copies all the code in the folder/app/dist/angular
into the folder where the nginx web application are stored.
Now that we have our Dockerfile done, the following step is to build our Docker image. For doing this we will need to be inside the directory where the Dockerfile is located and execute the following order in our terminal:
docker build -t jump-the-queue/angular .
ℹ️ The -t option in the order specifies how you do you want to name the image.
Once the order finishes its execution, we can check that the image has been created successfully in the "Images" tab inside our Docker application:
ℹ️ We can also check the Docker images by executing the order:
docker images
.
Now it is time to create the Dockerfile for our back-end side. First of all we will go into the directory where our Java application is located C:\...\worspaces\main\jumpthequeue\java
and create, as we did before, the Dockerfile. This time the Dockerfile will look a bit different, inside the Dockerfile we will write:
FROM maven:3.6-jdk-11 AS build
WORKDIR /app
COPY jtqj/ /app
RUN mvn clean install
FROM adoptopenjdk/openjdk11:jre-11.0.4_11-alpine
WORKDIR /app
COPY --from=build /app/server/target/jtqj-server-bootified.war /app/jumpthequeue.war
ENTRYPOINT ["java","-jar","/app/jumpthequeue.war"]
EXPOSE 8081
What this Dockerfile does is:
-
FROM
Specifies the image that we are going to use (maven:3.6-jdk-11
). -
WORKDIR
We specify the working directory (app
). -
COPY
We copy everything insidejtqj/
into the working directory. -
RUN
We execute the ordermvn clean install
to build our application. -
FROM
We specify that we are now going to use the imageadoptopenjdk/openjdk11:jre-11.0.4_11-alpine
. -
WORKDIR
We specify the working directory. -
COPY
We copy thewar
file created when executing he ordermvn clean install
into the working directory. -
ENTRYPOINT
We execute the Java application that we have just copied. -
EXPOSE
We indicate in which port of our computer the application will be executed.
Now, as we did before with the Angular side, we will execute the Docker order to build our image:
docker build -t jump-the-queue/java .
Once it is finished, we can check that the image was correctly created:
After creating the images for both parts of our application we are going to create the corresponding Docker containers in order to launch our application. Inside our machines terminal we will execute the following orders:
docker run --name jump-the-queue-angular -p 80:80 -d jump-the-queue/angular
docker run --name jump-the-queue-java -p 8081:8080 -d jump-the-queue/java
What this does is creating a container based on the image that we specify at the end of the order. The --name
option is for setting the name of our container, the -p
option is for exposing the ports where our application will be launched and the -d
option is for running our containers in the background.
Once the execution is finished we can see that our containers are correctly built in our Docker application or executing the order: docker container ls
.
Now to check that everything is working correctly we can access our application in our web browser in the following urls:
http://localhost:80
for the Angular side.
http://localhost:8081/jumpthequeue
for the Java side.
What we are going to create now is a reverse proxy using a "docker-compose.yml" file. This will allow us to build and launch both containers at the same time and make them accessible in the same port.
For making this, we will place ourselves in the main directory of our application (C:\...\workspaces\main\jumpthequeue
) and we will create a file called "docker-compose.yml". Inside this file we will add the following code:
version: '3'
services:
reverse-proxy:
build: 'reverse-proxy/'
container_name: 'jtq_reverse_proxy'
image: jump-the-queue/reverse-proxy:latest
ports:
- '80:80'
- '443:80'
networks:
- jump-the-queue
depends_on:
- java
- angular
angular:
build: 'angular/'
container_name: 'jtq_angular'
image: jump-the-queue/angular:latest
networks:
- jump-the-queue
java:
build: 'java/'
container_name: 'jtq_java'
image: jump-the-queue/java:latest
networks:
- jump-the-queue
networks:
jump-the-queue:
driver: bridge
What we are doing here is telling Docker that we want to create three services (containers), one for our angular part, one for our java part and one named "reverse-proxy" which is going to depend on the other two services and is going to specify the ports where we want to launch our application. All of these services will be connected to the same network that we have create called "jump-the-queue".
Before executing this file, we need to create first a Dockerfile for our reverse-proxy service. Inside the main directory of our application we will create a new folder called "reverse-proxy" where we are going to add the following files:
- Dockerfile:
FROM nginx:latest
COPY nginx.conf /etc/nginx/conf.d/default.conf
A Dockerfile which uses the image nginx:latest
(as it is going to be our server) and a COPY
instruction which is going to copy a file named nginx.conf
into the configuration folder of our nginx.
- nginx.conf:
server {
server_name _;
root /usr/share/nginx/html;
location / {
proxy_pass http://angular:80;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /api {
proxy_pass http://java:8081/jumpthequeue;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded_Port $server_port;
}
}
In this file what we specify is that when the user searches for the url http://localhost
the Angular part of our app should show up and if the user searches for http://localhost/api
the Java part of our app should show up.
Now that we have all the files prepared lets get into launching our reverse proxy. Inside the directory where we created the docker-compose file (C:\...\workspaces\main\jumpthequeue
) we will execute the following order:
docker-compose up -d
ℹ️ Just as mentioned before the -d option is for running the container in the background.
Once the order finishes its execution we can check that a new container with the three services is made:
Now we are able to access our application just by entering http://localhost
for the Angular part and http://localhost/api
for the Java part, without the need of specifying any port.
The last thing that we will see about Docker is how to save our images into files and how we can upload again this files into Docker.
For saving our images in .tar
files what we will do is, first of all place ourselves in the directory where we want to save them and then we will execute the following order:
docker save -o angular-image.tar jump-the-queue/angular
(For the Angular image).
docker save -o java-image.tar jump-the-queue/java
(For the Java image).
docker save -o reverse-proxy-image.tar jump-the-queue/reverse-proxy
(For the reverse proxy image).
We can check in the directory where we executed this instruction that our .tar
files with our images have been created.
Now, for loading our files again into our Docker we will execute the following order in the directory where our .tar
files are located, but first we will delete from our Docker the images that we have created in order to assure that the loading is done correctly.
docker load -i angular-image.tar
(For the Angular image).
docker load -i java-image.tar
(For the Java image).
docker load -i reverse-proxy-image.tar
(For the reverse-proxy image).
Once the execution of the instructions is finished, we can check inside our Docker application that the images have been successfully loaded.
Next Chapter: SonarQube