From 01788286e28d22a46f084883b7757bff869e321b Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Sun, 20 Jul 2025 11:19:05 +0200 Subject: [PATCH] setup Angular app and integrate Docker image build in docker-compose.yml --- Makefile | 10 +++-- docker-compose.yml | 12 ++++++ kontor-angular/.dockerignore | 3 ++ kontor-angular/.gitignore | 42 +++++++++++++++++++ kontor-angular/Dockerfile | 14 +++++++ kontor-angular/Makefile | 8 ++++ kontor-angular/README.md | 2 +- kontor-angular/angular.json | 19 ++++----- kontor-angular/nginx.conf | 37 ++++++++++++++++ kontor-angular/package-lock.json | 13 ++---- kontor-angular/package.json | 7 ++-- kontor-angular/src/app/app.config.ts | 4 +- kontor-angular/src/app/app.html | 1 + kontor-angular/src/app/{app.css => app.scss} | 0 kontor-angular/src/app/app.spec.ts | 2 + kontor-angular/src/app/app.ts | 2 +- .../src/{styles.css => styles.scss} | 0 kontor-scripts/download.py | 2 +- 18 files changed, 145 insertions(+), 33 deletions(-) create mode 100644 kontor-angular/.dockerignore create mode 100644 kontor-angular/.gitignore create mode 100644 kontor-angular/Dockerfile create mode 100644 kontor-angular/Makefile create mode 100644 kontor-angular/nginx.conf rename kontor-angular/src/app/{app.css => app.scss} (100%) rename kontor-angular/src/{styles.css => styles.scss} (100%) diff --git a/Makefile b/Makefile index b1a65b0..df78fff 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,12 @@ kontor_api := kontor-api kontor_spring := kontor-spring -kontor_servicemix := kontor-servicemix +kontor_angular := kontor-angular +TARGET=docker -.PHONY: all $(kontor_spring) $(kontor_api) -all: $(kontor_spring) $(kontor_api) $(kontor_servicemix) +.PHONY: all $(kontor_spring) $(kontor_api) $(kontor_angular) -$(kontor_spring) $(kontor_api) $(kontor_servicemix): +all: $(kontor_spring) $(kontor_api) $(kontor_angular) + +$(kontor_spring) $(kontor_api) $(kontor_angular): $(MAKE) --directory=$@ $(TARGET) diff --git a/docker-compose.yml b/docker-compose.yml index ba6da95..aaad792 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -83,6 +83,18 @@ services: depends_on: postgres: condition: service_healthy + kontor-angular: + image: kontor-angular:0.2.0-SNAPSHOT + restart: unless-stopped + networks: + - database + - integration + - frontend + ports: + - 8200:80 + depends_on: + postgres: + condition: service_healthy networks: database: integration: diff --git a/kontor-angular/.dockerignore b/kontor-angular/.dockerignore new file mode 100644 index 0000000..1502ec2 --- /dev/null +++ b/kontor-angular/.dockerignore @@ -0,0 +1,3 @@ +dist +node_modules + diff --git a/kontor-angular/.gitignore b/kontor-angular/.gitignore new file mode 100644 index 0000000..cc7b141 --- /dev/null +++ b/kontor-angular/.gitignore @@ -0,0 +1,42 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/kontor-angular/Dockerfile b/kontor-angular/Dockerfile new file mode 100644 index 0000000..770d77a --- /dev/null +++ b/kontor-angular/Dockerfile @@ -0,0 +1,14 @@ +### STAGE 1: Build ### +FROM node:22.15-alpine AS build +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm install +COPY . . +RUN npm run build + +### STAGE 2: Run ### +FROM nginx:1.17.1-alpine +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/dist/kontor-angular/browser /usr/share/nginx/html +EXPOSE 80 + diff --git a/kontor-angular/Makefile b/kontor-angular/Makefile new file mode 100644 index 0000000..2a2107c --- /dev/null +++ b/kontor-angular/Makefile @@ -0,0 +1,8 @@ +.PHONY: docker dev + +docker: + docker build -t kontor-angular:0.2.0-SNAPSHOT . + +dev: + ng serve + diff --git a/kontor-angular/README.md b/kontor-angular/README.md index 21d9c85..37b23c6 100644 --- a/kontor-angular/README.md +++ b/kontor-angular/README.md @@ -1,6 +1,6 @@ # KontorAngular -This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.1.0. +This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.1.1. ## Development server diff --git a/kontor-angular/angular.json b/kontor-angular/angular.json index 6c196b3..74ded1d 100644 --- a/kontor-angular/angular.json +++ b/kontor-angular/angular.json @@ -5,7 +5,11 @@ "projects": { "kontor-angular": { "projectType": "application", - "schematics": {}, + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, "root": "", "sourceRoot": "src", "prefix": "app", @@ -14,10 +18,8 @@ "builder": "@angular/build:application", "options": { "browser": "src/main.ts", - "polyfills": [ - "zone.js" - ], "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", "assets": [ { "glob": "**/*", @@ -25,7 +27,7 @@ } ], "styles": [ - "src/styles.css" + "src/styles.scss" ] }, "configurations": { @@ -70,11 +72,8 @@ "test": { "builder": "@angular/build:karma", "options": { - "polyfills": [ - "zone.js", - "zone.js/testing" - ], "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", "assets": [ { "glob": "**/*", @@ -82,7 +81,7 @@ } ], "styles": [ - "src/styles.css" + "src/styles.scss" ] } } diff --git a/kontor-angular/nginx.conf b/kontor-angular/nginx.conf new file mode 100644 index 0000000..c8444ce --- /dev/null +++ b/kontor-angular/nginx.conf @@ -0,0 +1,37 @@ +server { + # Root-Verzeichnis für den Server setzen (wir kopieren unsere Anwendung hierher) + root /usr/share/nginx/html; + + # Definieren der Standard-Indexdatei (Angular erstellt die Datei index.html für uns und sie befindet sich im oben genannten Verzeichnis) + index index.html; + + # Cache-Header für Medien-ASsets + location ~* \.(?:cur|jpe?g|gif|htc|ico|png|xml|otf|ttf|eot|woff|woff2|svg)$ { + access_log off; + add_header Pragma "must-revalidate, public"; + add_header Cache-Control "must-revalidate, public"; + expires max; + + tcp_nodelay off; + } + + # Cache-Header für HTML, CSS und JS-Dateien + location ~* \.(?:css|js|html)$ { + access_log off; + add_header Pragma "must-revalidate, public"; + add_header Cache-Control "must-revalidate, public"; + expires 2d; + + tcp_nodelay off; + } + + # Konfiguration für den /-Pfad + location / { + # Zunächst versuchen wir die angeforderte URI auzuliefern + # Klappt das nicht, versuchen wir es mit einem abschließenden Slash + # Klappt auch das nicht, liefern wir die index.html aus. + # Das ist nötig, damit Angular-Routen korrekt augeflöst und ausgeliefert werden + try_files $uri $uri/ /index.html; + } +} + diff --git a/kontor-angular/package-lock.json b/kontor-angular/package-lock.json index 69e6013..ca7901f 100644 --- a/kontor-angular/package-lock.json +++ b/kontor-angular/package-lock.json @@ -15,12 +15,11 @@ "@angular/platform-browser": "^20.1.0", "@angular/router": "^20.1.0", "rxjs": "~7.8.0", - "tslib": "^2.3.0", - "zone.js": "~0.15.0" + "tslib": "^2.3.0" }, "devDependencies": { - "@angular/build": "^20.1.0", - "@angular/cli": "^20.1.0", + "@angular/build": "^20.1.1", + "@angular/cli": "^20.1.1", "@angular/compiler-cli": "^20.1.0", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.8.0", @@ -9518,12 +9517,6 @@ "peerDependencies": { "zod": "^3.24.1" } - }, - "node_modules/zone.js": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", - "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", - "license": "MIT" } } } diff --git a/kontor-angular/package.json b/kontor-angular/package.json index 878e3bc..a0e10b7 100644 --- a/kontor-angular/package.json +++ b/kontor-angular/package.json @@ -27,12 +27,11 @@ "@angular/platform-browser": "^20.1.0", "@angular/router": "^20.1.0", "rxjs": "~7.8.0", - "tslib": "^2.3.0", - "zone.js": "~0.15.0" + "tslib": "^2.3.0" }, "devDependencies": { - "@angular/build": "^20.1.0", - "@angular/cli": "^20.1.0", + "@angular/build": "^20.1.1", + "@angular/cli": "^20.1.1", "@angular/compiler-cli": "^20.1.0", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.8.0", diff --git a/kontor-angular/src/app/app.config.ts b/kontor-angular/src/app/app.config.ts index d953f4c..2e06ce8 100644 --- a/kontor-angular/src/app/app.config.ts +++ b/kontor-angular/src/app/app.config.ts @@ -1,4 +1,4 @@ -import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core'; +import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; @@ -6,7 +6,7 @@ import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideBrowserGlobalErrorListeners(), - provideZoneChangeDetection({ eventCoalescing: true }), + provideZonelessChangeDetection(), provideRouter(routes) ] }; diff --git a/kontor-angular/src/app/app.html b/kontor-angular/src/app/app.html index 3869277..7528372 100644 --- a/kontor-angular/src/app/app.html +++ b/kontor-angular/src/app/app.html @@ -124,6 +124,7 @@ line-height: 1.4rem; letter-spacing: -0.00875rem; text-decoration: none; + white-space: nowrap; } .pill:hover { diff --git a/kontor-angular/src/app/app.css b/kontor-angular/src/app/app.scss similarity index 100% rename from kontor-angular/src/app/app.css rename to kontor-angular/src/app/app.scss diff --git a/kontor-angular/src/app/app.spec.ts b/kontor-angular/src/app/app.spec.ts index 9834b5f..02023fb 100644 --- a/kontor-angular/src/app/app.spec.ts +++ b/kontor-angular/src/app/app.spec.ts @@ -1,3 +1,4 @@ +import { provideZonelessChangeDetection } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { App } from './app'; @@ -5,6 +6,7 @@ describe('App', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [App], + providers: [provideZonelessChangeDetection()] }).compileComponents(); }); diff --git a/kontor-angular/src/app/app.ts b/kontor-angular/src/app/app.ts index 6bb57c7..e5dc1af 100644 --- a/kontor-angular/src/app/app.ts +++ b/kontor-angular/src/app/app.ts @@ -5,7 +5,7 @@ import { RouterOutlet } from '@angular/router'; selector: 'app-root', imports: [RouterOutlet], templateUrl: './app.html', - styleUrl: './app.css' + styleUrl: './app.scss' }) export class App { protected readonly title = signal('kontor-angular'); diff --git a/kontor-angular/src/styles.css b/kontor-angular/src/styles.scss similarity index 100% rename from kontor-angular/src/styles.css rename to kontor-angular/src/styles.scss diff --git a/kontor-scripts/download.py b/kontor-scripts/download.py index d8a9ecf..74853a3 100644 --- a/kontor-scripts/download.py +++ b/kontor-scripts/download.py @@ -89,7 +89,7 @@ def rename_file(file_info: dict): item_id = file_info['id'] file_name = file_info['file_name'] if file_name is None: - log.info("file_anme is not set, rename is not executed") + log.info("file_name is not set, rename is not executed") return file = Path(args.dir, file_name) new_file_path = file.with_name(f"{item_id}{file.suffix}")