202 Angular App in Docker - chempkovsky/CS82ANGULAR GitHub Wiki
- Read the article
- Before creating
Docker
-file we need a copy ofnginx.conf
of the Nginx-server.- To get the file
- pull the image
docker pull nginx:latest
- run the image
docker run nginx
- List the containers
docker ps
- connect to container
docker exec -it nginx /bin/bash
- Print
/etc/nginx/nginx.conf
-filecat /etc/nginx/nginx.conf
- Print
/etc/nginx/conf.d/default.conf
-filecat /etc/nginx/conf.d/default.conf
- pull the image
- To get the file
- Before creating
Docker
-file we need to modifyassets/app-config.template.json
-file- read the article
- we changed the structure of the
src\assets\app-config.json
-file- The latter requires modifying the
app-config.template.json
file
- The latter requires modifying the
- we changed the structure of the
- read the article
- run the commands
docker pull nginx:latest
docker images
docker run nginx
Click to show the response
C:\Users\yury>docker pull nginx:latest
latest: Pulling from library/nginx
42c077c10790: Pull complete
62c70f376f6a: Pull complete
915cc9bd79c2: Pull complete
75a963e94de0: Pull complete
7b1fab684d70: Pull complete
db24d06d5af4: Pull complete
Digest: sha256:2bcabc23b45489fb0885d69a06ba1d648aeda973fae7bb981bafbb884165e514
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
C:\Users\yury>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
C:\Users\yury>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 0e901e68141f 2 weeks ago 142MB
C:\Users\yury>docker run nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/06/13 12:51:15 [notice] 1#1: using the "epoll" event method
2022/06/13 12:51:15 [notice] 1#1: nginx/1.21.6
2022/06/13 12:51:15 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/06/13 12:51:15 [notice] 1#1: OS: Linux 5.10.102.1-microsoft-standard-WSL2
2022/06/13 12:51:15 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/06/13 12:51:15 [notice] 1#1: start worker processes
2022/06/13 12:51:15 [notice] 1#1: start worker process 31
2022/06/13 12:51:15 [notice] 1#1: start worker process 32
2022/06/13 12:51:15 [notice] 1#1: start worker process 33
2022/06/13 12:51:15 [notice] 1#1: start worker process 34
2022/06/13 12:51:15 [notice] 1#1: start worker process 35
2022/06/13 12:51:15 [notice] 1#1: start worker process 36
2022/06/13 12:51:15 [notice] 1#1: start worker process 37
2022/06/13 12:51:15 [notice] 1#1: start worker process 38
- run the commands
docker ps
docker exec -it 2ba47cad894e /bin/bash
cat /etc/nginx/nginx.conf
cat /etc/nginx/conf.d/default.conf
Click to show the response
C:\Users\yury>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ba47cad894e nginx "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp amazing_chaplygin
C:\Users\yury>docker exec -it 2ba47cad894e /bin/bash
root@2ba47cad894e:/# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
root@2ba47cad894e:/# cat /etc/nginx/conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
root@2ba47cad894e:/# exit
exit
C:\Users\yury>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 0e901e68141f 2 weeks ago 142MB
C:\Users\yury>
- we will create the copy for
/etc/nginx/conf.d/default.conf
- It'll be
nginxdefault.conf
in the angular project - two special paths we will use later:
/usr/share/nginx/html/angular-phonebook/en/
/usr/share/nginx/html/angular-phonebook/ru/
Click to show nginxdefault.conf
# Browser preferred language detection (does NOT require AcceptLanguageModule)
map $http_accept_language $accept_language {
~*^ru ru;
~*^en en;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
# location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
# }
# Fallback to default language if no preference defined by browser
if ($accept_language ~ "^$") {
set $accept_language "en";
}
location /ru/ {
alias /usr/share/nginx/html/angular-phonebook/ru/;
try_files $uri$args $uri$args/ /ru/index.html;
}
location /en/ {
alias /usr/share/nginx/html/angular-phonebook/en/;
try_files $uri$args $uri$args/ /en/index.html;
}
location / {
alias /usr/share/nginx/html/angular-phonebook/$accept_language/;
try_files $uri$args $uri$args/ /$accept_language/index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root /usr/share/nginx/html;
#}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
- we added "divisionLpWebApi", "employeeLpWebApi" and "phoneLpWebApi" in the
app-config.json
file.- the new version of the
app-config.template.json
file will be as follows:
- the new version of the
{
"webApiUrl": "${WA_URL}",
"securityUrl": "${SEC_URL}",
"permissionWebApi": "${PERM_URL}",
"divisionLpWebApi": "${DIVLP_URL}",
"employeeLpWebApi": "${EMPLP_URL}",
"phoneLpWebApi": "${PHNLP_URL}"
}
- we will use two stage assembly
- create
Dockerfile
in the Angular project
Click to show Dockerfile
################################################################
# Build the app in the separate image which is node:latest
################################################################
FROM node:latest as build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm install -g @angular/cli
RUN ng build --configuration=ru --prod --output-path=/dist/angular-phonebook
RUN mv /dist /ru
RUN ng build --configuration=en --prod --output-path=/dist/angular-phonebook
RUN mv /dist /en
################################################################
# Copy form node:latest image into nginx:latest and exec "CMD"
################################################################
FROM nginx:latest as nginxrslt
COPY nginxdefault.conf /etc/nginx/conf.d/default.conf
COPY --from=build /ru/angular-phonebook/ru/ /usr/share/nginx/html/angular-phonebook/ru/
COPY --from=build /en/angular-phonebook/en/ /usr/share/nginx/html/angular-phonebook/en/
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/angular-phonebook/ru/assets/app-config.template.json > /usr/share/nginx/html/angular-phonebook/ru/assets/app-config.json && envsubst < /usr/share/nginx/html/angular-phonebook/en/assets/app-config.template.json > /usr/share/nginx/html/angular-phonebook/en/assets/app-config.json && exec nginx -g 'daemon off;'"]
- The command to create the image
docker build . -f Dockerfile -t angular-phone-book
- run the command
docker run -d -p 90:80 -e PHNLP_URL="http://localhost:5055/" -e EMPLP_URL="http://localhost:5055/" -e DIVLP_URL="http://localhost:5055/" -e WA_URL="http://localhost:5165/" -e SEC_URL="http://localhost:5165/" -e PERM_URL="http://localhost:5165/" angular-phone-book:latest
- Suppose we have more than two locales and our
CMD[...]
command is getting too long- we can simplify Dockerfile and use some features of the Docker swarm
Click to show Dockerfile
################################################################
# Build the app in the separate image which is node:latest
################################################################
FROM node:latest as build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm install -g @angular/cli
RUN ng build --configuration=ru --prod --output-path=/dist/angular-phonebook
RUN mv /dist /ru
RUN ng build --configuration=en --prod --output-path=/dist/angular-phonebook
RUN mv /dist /en
################################################################
# Copy form node:latest image into nginx:latest and exec "CMD"
################################################################
FROM nginx:latest as nginxrslt
## COPY nginxdefault.conf /etc/nginx/conf.d/default.conf
COPY --from=build /ru/angular-phonebook/ru/ /usr/share/nginx/html/angular-phonebook/ru/
COPY --from=build /en/angular-phonebook/en/ /usr/share/nginx/html/angular-phonebook/en/
## CMD ["/bin/sh", "-c", "exec nginx -g 'daemon off;'"]
- In the current folder create the
nginxdefault.conf
file with the following content
Click to show the file
# Browser preferred language detection (does NOT require AcceptLanguageModule)
map $http_accept_language $accept_language {
~*^ru ru;
~*^en en;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
# location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
# }
# Fallback to default language if no preference defined by browser
if ($accept_language ~ "^$") {
set $accept_language "en";
}
location /ru/ {
alias /usr/share/nginx/html/angular-phonebook/ru/;
try_files $uri$args $uri$args/ /ru/index.html;
}
location /en/ {
alias /usr/share/nginx/html/angular-phonebook/en/;
try_files $uri$args $uri$args/ /en/index.html;
}
location / {
alias /usr/share/nginx/html/angular-phonebook/$accept_language/;
try_files $uri$args $uri$args/ /$accept_language/index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root /usr/share/nginx/html;
#}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
- run the following commands
docker swarm init
docker config create nginxdefault.conf ./nginxdefault.conf
docker config ls
docker config inspect nginxdefault.conf --pretty
- In the current folder create the
app-config.json
file with the following content
Click to show the sample
{
"webApiUrl": "http://localhost:5165/",
"securityUrl": "http://localhost:5165/",
"permissionWebApi": "http://localhost:5165/",
"divisionLpWebApi": "http://localhost:5055/",
"employeeLpWebApi": "http://localhost:5055/",
"phoneLpWebApi": "http://localhost:5055/"
}
- run the following commands
docker swarm init
docker config create app-config.json ./app-config.json
docker config ls
docker config inspect app-config.json --pretty
- run the following command
docker service create ^
--name angular-phone-book-service ^
--config source=app-config.json,target=/usr/share/nginx/html/angular-phonebook/ru/assets/app-config.json ^
--config source=app-config.json,target=/usr/share/nginx/html/angular-phonebook/en/assets/app-config.json ^
--config source=nginxdefault.conf,target=/etc/nginx/conf.d/default.conf ^
--publish published=90,target=80 ^
angular-phone-book:latest ^
sh -c "exec nginx -g 'daemon off;'"
- run the commands
docker service ls
docker ps
docker exec -it edb915519670 /bin/bash
cat /usr/share/nginx/html/angular-phonebook/en/assets/app-config.json
cat /etc/nginx/conf.d/default.conf
exit
Click to show the response
C:\Program Files\Git\usr\bin>docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
cwxp4f6uz04v angular-phone-book-service replicated 1/1 angular-phone-book:latest *:90->80/tcp
C:\Program Files\Git\usr\bin>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
edb915519670 angular-phone-book:latest "/docker-entrypoint.…" 16 minutes ago Up 16 minutes 80/tcp angular-phone-book-service.1.yp5bk2m1pkldmp799jvhgcz6k
C:\Program Files\Git\usr\bin>docker exec -it edb915519670 /bin/bash
root@edb915519670:/# cat /usr/share/nginx/html/angular-phonebook/en/assets/app-config.json
{
"webApiUrl": "http://localhost:5165/",
"securityUrl": "http://localhost:5165/",
"permissionWebApi": "http://localhost:5165/",
"divisionLpWebApi": "http://localhost:5055/",
"employeeLpWebApi": "http://localhost:5055/",
"phoneLpWebApi": "http://localhost:5055/"
}root@edb915519670:/# cat /etc/nginx/conf.d/default.conf
# Browser preferred language detection (does NOT require AcceptLanguageModule)
map $http_accept_language $accept_language {
~*^ru ru;
~*^en en;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
# location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
# }
# Fallback to default language if no preference defined by browser
if ($accept_language ~ "^$") {
set $accept_language "en";
}
location /ru/ {
alias /usr/share/nginx/html/angular-phonebook/ru/;
try_files $uri$args $uri$args/ /ru/index.html;
}
location /en/ {
alias /usr/share/nginx/html/angular-phonebook/en/;
try_files $uri$args $uri$args/ /en/index.html;
}
location / {
alias /usr/share/nginx/html/angular-phonebook/$accept_language/;
try_files $uri$args $uri$args/ /$accept_language/index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root /usr/share/nginx/html;
#}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
root@edb915519670:/# exit
exit
C:\Program Files\Git\usr\bin>
- run the commands
docker service ls
docker service rm angular-phone-book-service
docker service ls
- run the commands
docker config ls
docker config rm app-config.json
docker config rm nginxdefault.conf
docker config ls
- Suppose we have more than two locales and our
CMD[...]
command is getting too long- we can simplify Dockerfile and use some features of the Docker compose
Click to show Dockerfile
################################################################
# Build the app in the separate image which is node:latest
################################################################
FROM node:latest as build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm install -g @angular/cli
RUN ng build --configuration=ru --prod --output-path=/dist/angular-phonebook
RUN mv /dist /ru
RUN ng build --configuration=en --prod --output-path=/dist/angular-phonebook
RUN mv /dist /en
################################################################
# Copy form node:latest image into nginx:latest and exec "CMD"
################################################################
FROM nginx:latest as nginxrslt
## COPY nginxdefault.conf /etc/nginx/conf.d/default.conf
COPY --from=build /ru/angular-phonebook/ru/ /usr/share/nginx/html/angular-phonebook/ru/
COPY --from=build /en/angular-phonebook/en/ /usr/share/nginx/html/angular-phonebook/en/
## CMD ["/bin/sh", "-c", "exec nginx -g 'daemon off;'"]
- in the same folder we create
app-config.json
-file with the content shown in the paragraph - in the same folder we create
nginxdefault.conf
-file with the content shown in the paragraph
- in the same folder we create
docker-compose.yml
-file with the content as follows
Click to show Dockerfile
services:
angularphonebook:
build: .
container_name: 'angular-phone-book'
configs:
- source: appconfig
target: /usr/share/nginx/html/angular-phonebook/ru/assets/app-config.json
uid: "103"
gid: "103"
mode: 0440
- source: appconfig
target: /usr/share/nginx/html/angular-phonebook/en/assets/app-config.json
uid: "103"
gid: "103"
mode: 0440
- source: nginxdefaultconf
target: /etc/nginx/conf.d/default.conf
uid: "103"
gid: "103"
mode: 0440
ports:
- 90:80
command: ["/bin/sh", "-c", "exec nginx -g 'daemon off;'"]
configs:
appconfig:
file: ./app-config.json
nginxdefaultconf:
file: ./nginxdefault.conf
- run the command
docker-compose -f "docker-compose.yml" up -d --build
- run the command
docker-compose -f "docker-compose.yml" down
- remove image
docker image ls
docker image rm angularphonebook_angularphonebook
-
Suppose we have more than two locales and our
CMD[...]
command is getting too long- we can save all the commands in the separate Bash Script file
-
in the same folder we create
nginxdefault.conf
-file with the content shown in the paragraph
- in the same folder we create
startnginx.sh
file with the content as follows
#!/bin/bash
envsubst < /usr/share/nginx/html/angular-phonebook/ru/assets/app-config.template.json > /usr/share/nginx/html/angular-phonebook/ru/assets/app-config.json
envsubst < /usr/share/nginx/html/angular-phonebook/en/assets/app-config.template.json > /usr/share/nginx/html/angular-phonebook/en/assets/app-config.json
exec nginx -g 'daemon off;'
- in the same folder we create
Dockerfile
file with the content as follows
Click to show Dockerfile
################################################################
# Build the app in the separate image which is node:latest
################################################################
FROM node:latest as build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm install -g @angular/cli
RUN ng build --configuration=ru --prod --output-path=/dist/angular-phonebook
RUN mv /dist /ru
RUN ng build --configuration=en --prod --output-path=/dist/angular-phonebook
RUN mv /dist /en
################################################################
# Copy form node:latest image into nginx:latest and exec "CMD"
################################################################
FROM nginx:latest as nginxrslt
COPY nginxdefault.conf /etc/nginx/conf.d/default.conf
COPY --from=build /ru/angular-phonebook/ru/ /usr/share/nginx/html/angular-phonebook/ru/
COPY --from=build /en/angular-phonebook/en/ /usr/share/nginx/html/angular-phonebook/en/
COPY ./startnginx.sh /
RUN chmod +x /startnginx.sh
CMD ["/startnginx.sh"]
## CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/angular-phonebook/ru/assets/app-config.template.json > /usr/share/nginx/html/angular-phonebook/ru/assets/app-config.json && envsubst < /usr/share/nginx/html/angular-phonebook/en/assets/app-config.template.json > /usr/share/nginx/html/angular-phonebook/en/assets/app-config.json && exec nginx -g 'daemon off;'"]
- the command to create the image
docker build . -f Dockerfile -t angular-phone-book
- run the command
docker run -d -p 90:80 -e PHNLP_URL="http://localhost:5055/" -e EMPLP_URL="http://localhost:5055/" -e DIVLP_URL="http://localhost:5055/" -e WA_URL="http://localhost:5165/" -e SEC_URL="http://localhost:5165/" -e PERM_URL="http://localhost:5165/" angular-phone-book:latest
-
to remove the container and image run the commands
docker ps
docker container stop e1c6ce6470a4
docker container rm e1c6ce6470a4
docker image rm angular-phone-book
- Use
\src
-folder as a working folder - Create startnginx sh
- Create Dockerfile with Bash Script
- run the command
docker build . -f Dockerfile -t angular-phn-bk