Wiki source code of Dockerising the UGS Tool

Last modified by Jan Rhebergen on 2022/01/24 15:56

Hide last authors
Jan Rhebergen 1.1 1 (% class="wikigeneratedid" id="HManual-DockerizingtheUGSToolwebapplication" %)
2 Dockerising a web application makes it easy to move it across systems, just wrap it inside a Docker image and run it in a container.
3
4 [[__Docker__>>url:https://docs.docker.com/]] is a system to create images which can then be run in containers. You can think of docker images as super lightweight Virtual Machines that can be run on many platforms (in this image containers are running VMs). Once you build a docker image and run it somewhere you will get the same thing running everywhere. Once we manage to build a Docker image locally that we can run as a container successfully we know that it will also run on AWS, GCP, Portainer or whatever else a company might be using.
5
6 In this manual the Dockerising of the UGS Tool web application is explained. The application consists of frontend and backend. The front-end has been developed using HTML, CSS and javascript/jQuery. The back-end has been developed using Nodejs. SQLite database to store the data that is located in the back-end. Before we start, make sure Docker is installed on your machine. This can be download here: [[__https:~~/~~/www.docker.com/products/docker-desktop__>>url:https://www.docker.com/products/docker-desktop]]
7
8 == Create a Dockerfile - Backend (Server-side) ==
9
10 First, open the code of the web application in an IDE of choice, I am using InteliJ IDEA for this. Then we need a Dockerfile. In this manual we will start with Dockerising the backend. (Make sure the backend server of your application is running). Create a Dockerfile by right-clicking on your server folder, click on ‘new file’ and type Dockerfile.
11
12 [[image:Manual - Dockerizing a web application_html_aa12b83c2937dd33.png||height="215" width="451"]]
13
14 And rename this to Dockerfile, see example:
15
16 [[image:Manual - Dockerizing a web application_html_ba5d39609a6f9ddf.png||height="32" width="226"]]
17
18 == Explanation of the Dockerfile - backend (Server-side) ==
19
20 Open the Dockerfile. Within this file the following information is specified:
21
22 [[image:Manual - Dockerizing a web application_html_5eabb4c26a8ac118.png||height="217" width="423"]]
23
24 FROM: Which node version the application is using.
25 WORKDIR: To create a directory to hold the application code inside the image, this will be the working directory for your application.
26 COPY: This is used to copy the files/node package/dependencies your application needs{{footnote}}If {{{package.json}}} file is not present yet, follow the steps of ‘Create the Node.js app’ at: [[__https:~~/~~/nodejs.org/en/docs/guides/nodejs-docker-webapp/__>>url:https://nodejs.org/en/docs/guides/nodejs-docker-webapp/]]{{/footnote}}.
27 RUN: This is to install your app dependencies using the npm binary.
28 CMD: define the command to run your app using CMD which defines your runtime. Here we will use nodemon server.js to start the server{{footnote}}To create {{{server.js}}} follow the steps of ‘Create the Node.js app’ at: [[__https:~~/~~/nodejs.org/en/docs/guides/nodejs-docker-webapp/__>>url:https://nodejs.org/en/docs/guides/nodejs-docker-webapp/]]{{/footnote}}
29 EXPOSE: The app binds to port 8081 (in this situation, but can vary) so the EXPOSE instruction is used to have it mapped by the docker daemon.
30
31 === Building the image ===
32
33 Go to the directory that has the Dockerfile (In the terminal type {{{ls}}} and {{{cd}}} to navigate to the directory of the Dockerfile) then run the following command to build the Docker image~:
34
35 {{{docker build -t ugs-back-end .}}}
36
37 The {{{-t}}} flag lets you tag your image so it's easier to find later using the docker images command. The {{{.}}} (dot/period) in the end means copy all in from the same directory that we’re in.
38
39 To check if the image has been created, use the following command:
40
41 {{{docker images}}}
42
43 === Run the image ===
44
45 Running your image with the following command. The -p flag redirects a public port to a private port inside the container. Run the image you previously built, see example:
46
47 {{{docker run -p 8181:8082 --name ugs-back-end ugs-back-end}}}
48
49 To publish a port for our container, the {{{--publish}}} flag ({{{-p}}} for short) is used on the docker run command. The format of the {{{--publish}}} command is {{{[host port]:[container port]}}}. So if we wanted to expose port {{{8082}}} inside the container to port {{{8181}}} outside the container, we would pass {{{8181:8082}}} to the {{{--publish}}} flag.
50
51 Source: [[__https:~~/~~/docs.docker.com/language/nodejs/run-containers/__>>url:https://docs.docker.com/language/nodejs/run-containers/]]
52
53 As seen above, in this application it is specified as {{{8181:8082}}}. Docker mapped the {{{8082}}} port inside of the container to the port {{{8181}}} on the machine.
54
55 To test the application, get the port of your app that Docker mapped, by using this command:
56
57 {{{docker ps}}}
58
59 == Create a Dockerfile - Frontend (Client-side) ==
60
61 Now we can dockerize the frontend. Create a Dockerfile by right click on your front end (scr file) folder, click on ‘new file’ and type Dockerfile.
62
63 [[image:Manual - Dockerizing a web application_html_19bed3dfae1afbe7.png||height="49" width="507"]]
64
65 And rename this to Dockerfile, see example:
66
67 [[image:Manual - Dockerizing a web application_html_ba5d39609a6f9ddf.png||height="32" width="226"]]
68
69 == Explanation of the Dockerfile - Frontend (Client-side) ==
70
71 Open the Dockerfile. Within this file the following information is specified:
72
73 [[image:Screenshot Client-side Dockerfile.png]]
74
75
76
77 ==== What’s nginx? ====
78
79 Nginx (pronounced "engine-x") is an open source reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer, HTTP cache, and a web server (origin server).
80
81 Source: [[__https:~~/~~/hub.docker.com/_/nginx__>>url:https://hub.docker.com/_/nginx]]
82
83 FROM: This will pull the nginx:1.15.8-alpine image to our local machine and then build our custom image on top of it.
84 WORKDIR: To create a directory to hold the application code inside the image, this will be the working directory for your application.
85 COPY: To copy the ./nginx.conf into the /etc/nginx/nginx.conf directory.
86 COPY: To copy all the .html/.css/.png/.svg/.js file into the /usr/share/nginx/html directory inside the container overwriting the default index.html file provided by nginx:1.15.8-alpine image.
87
88 ==== Creating nginx.conf ====
89
90 If you want to run a static website you need to create a {{{nginx.conf}}} file. This file you can copy it as it is, but make sure that all your files are in the {{{/usr/share/nginx/html/}}} directory, that is shown in the Dockerfile, we’ve copied all htm, css, javascript etc into the {{{/usr/share/nginx/html/}}}
91
92 Sure you can copy them the way you want, but you need then to configure your {{{nginx.conf}}} file properly as it fits the way you copied your files in Dockerfile. Last thing is to indicate which file you want to get retrieved once your server is started, that is done by indicating which file you want in the location index scope. In this case we’re setting up the {{{map.html}}} as an index file. The source code is given below:
93
94
95 {{code language="none"}}
96 user nginx;
97 worker_processes 1;
98 error_log /var/log/nginx/error.log warn;
99 pid /var/run/nginx.pid;
100
101 events {
102 worker_connections 1024;
103 }
104
105 http {
106 include /etc/nginx/mime.types;
107 default_type application/octet-stream;
108 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
109 '$status $body_bytes_sent "$http_referer" '
110 '"$http_user_agent" "$http_x_forwarded_for"';
111 access_log /var/log/nginx/access.log main;
112 server {
113 listen 80;
114 location = /status {
115 access_log off;
116 default_type text/plain;
117 add_header Content-Type text/plain;
118 return 200 "alive";
119 }
120 location / {
121 gzip off;
122 root /usr/share/nginx/html/;
123 index map.html;
124 }
125 location ~* \.(js|jpg|png|css|svg)$ {
126 root /usr/share/nginx/html/;
127 }
128 }
129
130 sendfile on;
131 keepalive_timeout 65;
132 }
133 {{/code}}
134
135 === Building the image ===
136
137 Go to the directory that has the Dockerfile (In the terminal type ls and cd to navigate to the directory of the Dockerfile) then run the following command to build the Docker image~:
138
139 {{{docker build -t ugs-front-end .}}}
140
141 === Run the image ===
142
143 Running your image with the following command. The -p flag redirects a public port to a private port inside the container. Run the image you previously built, see example:
144
145 {{{docker run -it -p 8081:80 --name ugs-front-end ugs-front-end}}}
146
147
148 === Overview ===
149
150 This is an overview on how the client-side communicates with the server-side, each side has a Docker image that runs inside a container. Below each Docker image, the Docker command is specified to run inside a container.
151
152 [[image:UGS Docker overzicht.png||height="568" width="787"]]
153
154 == Extra Docker commands ==
155
156 * To remove an image, the following command can be used, The -f flag means force:
157 {{{docker rmi -f (image id}}}
158 * Save a docker image as “{{{.tar}}}” file:
159 {{{docker save -o (the tar file name.tar) (image name/directory)}}}
160 * To load a docker image from a tar file:{{footnote}}**NB:** If there is already a container, by using this command we can run the container.{{/footnote}}
161 {{{docker load -i (file.tar)}}}
162 * To start a container:
163 {{{docker start (container name/ container id)}}}
164 * To stop a container:
165 {{{docker stop (container name/ container id)}}}
166
167 {{putFootnotes/}}