Skip to content

Commit 7ce615c

Browse files
TT-511 containerize time tracker UI (#798)
* feat: TT-511 containerize time tracker ui * feat: TT-511 environment variables and tests setup * fix: TT-511 add missing environment variables * fix: TT-511 update .dockerignore * refactor: TT-511 solve comments * feat: TT-511 multi-stage builds in dockerfile and add user to run commands inside docker * feat: TT-511 create build and docker image for production * refactor: TT-511 solve comments * fix: TT-511 changes in makefile to solve comments
1 parent e1cba90 commit 7ce615c

File tree

9 files changed

+210
-2
lines changed

9 files changed

+210
-2
lines changed

.dockerignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
node_modules
2+
.github
3+
dist
4+
coverage
5+
Makefile
6+
.gitignore
7+
*keys.ts
8+
*.keys.json

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ Thumbs.db
5252

5353
# stryker temp files
5454
.stryker-tmp
55+
56+
#ENV VARIABLES
57+
.env

Dockerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
FROM node:14 AS development
2+
3+
ENV USERNAME timetracker
4+
ENV HOME /home/${USERNAME}
5+
6+
RUN useradd -ms /bin/bash ${USERNAME}
7+
8+
WORKDIR ${HOME}/time-tracker-ui
9+
COPY . .
10+
RUN rm -f .env
11+
RUN chown ${USERNAME}:${USERNAME} -R ${HOME}/time-tracker-ui
12+
13+
USER ${USERNAME}
14+
RUN npm cache clean --force && npm install
15+
EXPOSE 4200
16+
EXPOSE 9876
17+
CMD npm run config && ${HOME}/time-tracker-ui/node_modules/.bin/ng serve --host 0.0.0.0 --disableHostCheck
18+
19+
20+
21+
FROM development as build
22+
COPY .env .
23+
RUN npm run build
24+
25+
26+
27+
FROM nginx:1.21 AS production
28+
29+
ENV USERNAME app
30+
RUN useradd -ms /bin/bash ${USERNAME}
31+
32+
COPY nginx.conf /etc/nginx/conf.d/default.conf
33+
COPY --from=build /home/timetracker/time-tracker-ui/dist/time-tracker /usr/share/nginx/html
34+
35+
RUN chown -R ${USERNAME}:${USERNAME} /var/cache/nginx && \
36+
chown -R ${USERNAME}:${USERNAME} /var/log/nginx && \
37+
chown -R ${USERNAME}:${USERNAME} /etc/nginx/conf.d
38+
RUN touch /var/run/nginx.pid && chown -R ${USERNAME}:${USERNAME} /var/run/nginx.pid
39+
40+
USER ${USERNAME}
41+
42+
EXPOSE 4200

Makefile

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
override SHELL := /bin/bash
2+
3+
.PHONY: help
4+
help: ## Show this help message.
5+
@echo 'Usage:'
6+
@echo ' make [target] ...'
7+
@echo
8+
@echo 'Targets:'
9+
@grep --no-filename -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
10+
sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
11+
12+
.PHONY: build
13+
build: ## Create docker image with dependencies needed for development.
14+
docker-compose build
15+
16+
.PHONY: cleanup
17+
cleanup: ## Delete image timetracker_ui
18+
docker rmi timetracker_ui
19+
20+
.PHONY: run
21+
run: ## Execute timetracker_ui docker containe.
22+
docker-compose --env-file ./.env up -d
23+
24+
.PHONY: logs
25+
logs: ## Show logs of timetracker_ui.
26+
docker logs -f timetracker_ui
27+
28+
.PHONY: stop
29+
stop: ## Stop container timetracker_ui.
30+
docker-compose stop
31+
32+
.PHONY: restart
33+
restart: ## Restart container timetracker_ui.
34+
docker-compose stop
35+
docker-compose up -d
36+
37+
.PHONY: remove
38+
remove: ## Delete container timetracker_ui.
39+
docker-compose down --volumes --remove-orphans --rmi local
40+
41+
.PHONY: test
42+
test: ## Run all tests on docker container timetracker_ui.
43+
docker-compose --env-file ./.env up -d
44+
docker exec -it timetracker_ui bash -c "npm run test"
45+
46+
.PHONY: publish
47+
publish: ## Publish the container image timetracker_ui.
48+
docker tag timetracker_ui:latest $(registry_url)/timetracker_ui:latest
49+
docker push $(registry_url)/timetracker_ui:latest
50+
51+
.PHONY: build_prod
52+
build_prod: ## Create docker image with dependencies needed for production.
53+
docker build --target production -t timetracker_ui_prod -f Dockerfile .
54+
55+
.PHONY: run_prod
56+
run_prod: ## Execute timetracker_ui_prod docker container.
57+
docker run -d -p 4200:4200 --name timetracker_ui_prod timetracker_ui_prod
58+
59+
.PHONY: remove_prod
60+
remove_prod: ## Delete container timetracker_ui_pro.
61+
docker stop timetracker_ui_prod
62+
docker rm timetracker_ui_prod
63+
64+
.PHONY: publish_prod
65+
publish_prod: ## Publish the container image timetracker_ui_prod.
66+
docker tag timetracker_ui_prod:latest $(registry_url)/timetracker_ui_prod:latest
67+
docker push $(registry_url)/timetracker_ui_prod:latest
68+
69+
.PHONY: login
70+
login: ## Login in respository of docker images.
71+
az acr login --name $(container_registry)

docker-compose.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
version: '3.9'
2+
services:
3+
time-tracker-ui:
4+
container_name: timetracker_ui
5+
image: timetracker_ui
6+
build:
7+
target: development
8+
context: .
9+
dockerfile: ./Dockerfile
10+
ports:
11+
- 4200:4200
12+
- 9876:9876
13+
environment:
14+
AUTHORITY: ${AUTHORITY}
15+
CLIENT_ID: ${CLIENT_ID}
16+
SCOPES: ${SCOPES}
17+
STACK_EXCHANGE_ID: ${STACK_EXCHANGE_ID}
18+
STACK_EXCHANGE_ACCESS_TOKEN: ${STACK_EXCHANGE_ACCESS_TOKEN}
19+
AZURE_APP_CONFIGURATION_CONNECTION_STRING: ${AZURE_APP_CONFIGURATION_CONNECTION_STRING}
20+
AUTHORITY_JSON: ${AUTHORITY_JSON}
21+
CLIENT_ID_JSON: ${CLIENT_ID_JSON}
22+
SCOPES_JSON: ${SCOPES_JSON}
23+
volumes:
24+
- ./src:/home/timetracker/time-tracker-ui/src/
25+
- ./scripts:/home/timetracker/time-tracker-ui/scripts/
26+
- ./e2e:/home/timetracker/time-tracker-ui/e2e/
27+
- ./coverage:/home/timetracker/time-tracker-ui/coverage
28+
- ./angular.json:/home/timetracker/time-tracker-ui/angular.json
29+
- ./karma.conf.js:/home/timetracker/time-tracker-ui/karma.conf.js
30+
- ./package.json:/home/timetracker/time-tracker-ui/package.json
31+
- ./webpack.config.js:/home/timetracker/time-tracker-ui/webpack.config.js

nginx.conf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
server {
2+
listen 4200;
3+
4+
root /usr/share/nginx/html;
5+
index index.html;
6+
7+
server_name _;
8+
9+
location / {
10+
try_files $uri /index.html;
11+
}
12+
}

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
"name": "time-tracker",
33
"version": "1.62.0",
44
"scripts": {
5+
"config": "ts-node ./scripts/setenv.ts",
56
"preinstall": "npx npm-force-resolutions",
67
"ng": "ng",
7-
"start": "ng serve",
8-
"build": "ng build --prod",
8+
"start": "npm run config && ng serve",
9+
"build": "npm run config && ng build --prod",
910
"test": "ng test",
1011
"test-headless": "ng test --browsers ChromeHeadless",
1112
"ci-test": "ng test --no-watch --no-progress --browsers ChromeHeadless",
@@ -44,6 +45,7 @@
4445
"datatables.net-responsive": "2.2.6",
4546
"datatables.net-responsive-dt": "2.2.6",
4647
"date-fns": "2.22.1",
48+
"dotenv": "^14.2.0",
4749
"jquery": "3.5.1",
4850
"jszip": "3.7.0",
4951
"minimist": "1.2.5",

scripts/setenv.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const { writeFile } = require('fs');
2+
require('dotenv').config();
3+
4+
const pathJs = `./src/environments/keys.ts`
5+
const contentKeys =
6+
`export const AUTHORITY = '${process.env.AUTHORITY}';
7+
export const CLIENT_ID = '${process.env.CLIENT_ID}';
8+
export const SCOPES = ['${process.env.SCOPES}'];
9+
export const STACK_EXCHANGE_ID = '${process.env.STACK_EXCHANGE_ID}';
10+
export const STACK_EXCHANGE_ACCESS_TOKEN = '${process.env.STACK_EXCHANGE_ACCESS_TOKEN}';
11+
export const AZURE_APP_CONFIGURATION_CONNECTION_STRING = '${process.env.AZURE_APP_CONFIGURATION_CONNECTION_STRING}';
12+
`;
13+
14+
writeFile(pathJs, contentKeys, function (err) {
15+
if (err) {
16+
console.log(err);
17+
}
18+
console.log(`Wrote variables to ${pathJs}`);
19+
});
20+
21+
const pathJson = `./src/environments/.keys.json`
22+
const contentKeysJson =
23+
`{
24+
"authority": "${process.env.AUTHORITY_JSON}",
25+
"client_id": "${process.env.CLIENT_ID_JSON}",
26+
"scopes": ["${process.env.SCOPES_JSON}"]
27+
}`;
28+
29+
writeFile(pathJson, contentKeysJson, function (err) {
30+
if (err) {
31+
console.log(err);
32+
}
33+
console.log(`Wrote variables to ${pathJson}`);
34+
});

0 commit comments

Comments
 (0)