From 662f0ac190d9d99cfaf826a8f50384482b189597 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 7 Mar 2025 15:52:52 +0100 Subject: [PATCH 01/34] chore: backend docker setup .dockerignore en .dockerfile van de backend ingesteld --- backend/.dockerignore | 7 +++++++ backend/backend.dockerfile | 14 ++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 backend/.dockerignore create mode 100644 backend/backend.dockerfile diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 00000000..5fbca23a --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,7 @@ +**/node_modules/ +**/dist +.git +npm-debug.log +.coverage +.coverage.* +.env \ No newline at end of file diff --git a/backend/backend.dockerfile b/backend/backend.dockerfile new file mode 100644 index 00000000..632b7e9e --- /dev/null +++ b/backend/backend.dockerfile @@ -0,0 +1,14 @@ +FROM node:22 + +WORKDIR /app + +COPY ./package*.json ./ + +RUN npm install + +COPY . . + +EXPOSE 80 +EXPOSE 443 + +CMD ["npm", "start"] \ No newline at end of file From 174582848755983fad678ec8bad7d72ac85d46ff Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 7 Mar 2025 15:57:50 +0100 Subject: [PATCH 02/34] chore: backend docker setup .dockerignore en .dockerfile van de backend ingesteld --- backend/backend.dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/backend.dockerfile b/backend/backend.dockerfile index 632b7e9e..708b7520 100644 --- a/backend/backend.dockerfile +++ b/backend/backend.dockerfile @@ -8,7 +8,6 @@ RUN npm install COPY . . -EXPOSE 80 -EXPOSE 443 +EXPOSE 2002 CMD ["npm", "start"] \ No newline at end of file From 987036946ef22dc982b7aa426c0334ed007ef697 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 7 Mar 2025 16:04:46 +0100 Subject: [PATCH 03/34] chore: frontend docker setup .dockerignore en .dockerfile van de frontend ingesteld --- frontend/.dockerignore | 7 +++++++ frontend/frontend.dockerfile | 13 +++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 frontend/.dockerignore create mode 100644 frontend/frontend.dockerfile diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 00000000..5fbca23a --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,7 @@ +**/node_modules/ +**/dist +.git +npm-debug.log +.coverage +.coverage.* +.env \ No newline at end of file diff --git a/frontend/frontend.dockerfile b/frontend/frontend.dockerfile new file mode 100644 index 00000000..b8e60e06 --- /dev/null +++ b/frontend/frontend.dockerfile @@ -0,0 +1,13 @@ +# build stage +FROM node:22 as build-stage +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +RUN npm run build + +# production stage +FROM nginx:stable as production-stage +COPY --from=build-stage /app/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file From d6a7cdf9803a0b0b3828cdc5453bab974dee6361 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 7 Mar 2025 16:10:18 +0100 Subject: [PATCH 04/34] chore: update docker-compose docker compose uitgebreidt om ook front- en backend docker images te builden --- docker-compose.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 0f8219af..70fc4714 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,13 @@ services: + web: + build: ./frontend + depends_on: + - api + ports: + - "443:443" + - "80:80" + api: + build: ./backend db: image: postgres:latest environment: From 9aff94ba62ffb3c9de0add6a9cc5c2f7501f96be Mon Sep 17 00:00:00 2001 From: Lint Action Date: Fri, 7 Mar 2025 15:17:21 +0000 Subject: [PATCH 05/34] style: fix linting issues met Prettier --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 70fc4714..23dd9b07 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,10 +2,10 @@ services: web: build: ./frontend depends_on: - - api + - api ports: - - "443:443" - - "80:80" + - '443:443' + - '80:80' api: build: ./backend db: From 71f6b1b3cbc3a0eda25b8b504c3aa14431e422e7 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 7 Mar 2025 16:45:42 +0100 Subject: [PATCH 06/34] chore: dockerfiles van naam veranderd --- backend/{backend.dockerfile => Dockerfile} | 0 docker-compose.yml | 2 ++ frontend/{frontend.dockerfile => Dockerfile} | 0 3 files changed, 2 insertions(+) rename backend/{backend.dockerfile => Dockerfile} (100%) rename frontend/{frontend.dockerfile => Dockerfile} (100%) diff --git a/backend/backend.dockerfile b/backend/Dockerfile similarity index 100% rename from backend/backend.dockerfile rename to backend/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 23dd9b07..1a4daac0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,8 @@ services: - '80:80' api: build: ./backend + ports: + - '2002:2002' db: image: postgres:latest environment: diff --git a/frontend/frontend.dockerfile b/frontend/Dockerfile similarity index 100% rename from frontend/frontend.dockerfile rename to frontend/Dockerfile From 0995cba88c1eb0ec665a8ff76142f9a8170f55d5 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 7 Mar 2025 17:19:30 +0100 Subject: [PATCH 07/34] chore: update docker layout Dockerfiles in root gezet zodat ze ook aan bestanden daarin kunnen --- backend/.dockerignore => .dockerignore | 0 backend/Dockerfile => backend.Dockerfile | 4 ++-- docker-compose.yml | 6 ++++-- frontend/Dockerfile => frontend.Dockerfile | 4 ++-- frontend/.dockerignore | 7 ------- 5 files changed, 8 insertions(+), 13 deletions(-) rename backend/.dockerignore => .dockerignore (100%) rename backend/Dockerfile => backend.Dockerfile (62%) rename frontend/Dockerfile => frontend.Dockerfile (82%) delete mode 100644 frontend/.dockerignore diff --git a/backend/.dockerignore b/.dockerignore similarity index 100% rename from backend/.dockerignore rename to .dockerignore diff --git a/backend/Dockerfile b/backend.Dockerfile similarity index 62% rename from backend/Dockerfile rename to backend.Dockerfile index 708b7520..c8a595fe 100644 --- a/backend/Dockerfile +++ b/backend.Dockerfile @@ -2,11 +2,11 @@ FROM node:22 WORKDIR /app -COPY ./package*.json ./ +COPY ./backend/package*.json ./ RUN npm install -COPY . . +COPY ./backend . EXPOSE 2002 diff --git a/docker-compose.yml b/docker-compose.yml index 1a4daac0..673b3d4d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,15 @@ services: web: - build: ./frontend + build: + dockerfile: ./frontend.Dockerfile depends_on: - api ports: - '443:443' - '80:80' api: - build: ./backend + build: + dockerfile: ./backend.Dockerfile ports: - '2002:2002' db: diff --git a/frontend/Dockerfile b/frontend.Dockerfile similarity index 82% rename from frontend/Dockerfile rename to frontend.Dockerfile index b8e60e06..40cb0d4a 100644 --- a/frontend/Dockerfile +++ b/frontend.Dockerfile @@ -1,9 +1,9 @@ # build stage FROM node:22 as build-stage WORKDIR /app -COPY package*.json ./ +COPY ./frontend/package*.json ./ RUN npm install -COPY . . +COPY ./frontend . RUN npm run build # production stage diff --git a/frontend/.dockerignore b/frontend/.dockerignore deleted file mode 100644 index 5fbca23a..00000000 --- a/frontend/.dockerignore +++ /dev/null @@ -1,7 +0,0 @@ -**/node_modules/ -**/dist -.git -npm-debug.log -.coverage -.coverage.* -.env \ No newline at end of file From 8890542f5e7ef30ffb23b8cfdacdf645ad9757d9 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 7 Mar 2025 17:29:22 +0100 Subject: [PATCH 08/34] chore: docker container layout aangepast De mappen zitten een laag dieper in de docker container zodat de MenuBar.vue code niet moest aangepast worden --- backend.Dockerfile | 4 +++- frontend.Dockerfile | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/backend.Dockerfile b/backend.Dockerfile index c8a595fe..f2967423 100644 --- a/backend.Dockerfile +++ b/backend.Dockerfile @@ -6,7 +6,9 @@ COPY ./backend/package*.json ./ RUN npm install -COPY ./backend . +COPY ./backend ./backend + +WORKDIR /app/backend EXPOSE 2002 diff --git a/frontend.Dockerfile b/frontend.Dockerfile index 40cb0d4a..6491bb5f 100644 --- a/frontend.Dockerfile +++ b/frontend.Dockerfile @@ -1,13 +1,15 @@ # build stage -FROM node:22 as build-stage +FROM node:22 AS build-stage WORKDIR /app COPY ./frontend/package*.json ./ RUN npm install -COPY ./frontend . +COPY ./frontend ./frontend +COPY ./assets ./assets +WORKDIR /app/frontend RUN npm run build # production stage -FROM nginx:stable as production-stage -COPY --from=build-stage /app/dist /usr/share/nginx/html +FROM nginx:stable AS production-stage +COPY --from=build-stage /app/frontend/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file From 6918f45e34eb9cf2884f68ab0f76b736452a6932 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Sun, 9 Mar 2025 22:30:43 +0100 Subject: [PATCH 09/34] =?UTF-8?q?chore:=20nginx=20configuratie=20toegevoed?= =?UTF-8?q?=20nginx=20geconfigureerd=20en=20via=20docker=20gekopi=C3=ABerd?= =?UTF-8?q?,=20SSL=20ingesteld=20en=20volume=20voor=20gemaakt=20in=20docke?= =?UTF-8?q?r=20compose=20zodat=20de=20certificates=20op=20de=20server=20ge?= =?UTF-8?q?vonden=20worden=20door=20docker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 3 +++ frontend.Dockerfile | 2 ++ nginx/nginx.conf | 50 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 nginx/nginx.conf diff --git a/docker-compose.yml b/docker-compose.yml index 673b3d4d..b7c73821 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,8 @@ services: ports: - '443:443' - '80:80' + volumes: + - ssl:/etc/letsencrypt/live/sel2-1.ugent.be/ api: build: dockerfile: ./backend.Dockerfile @@ -46,3 +48,4 @@ volumes: dwengo_postgres_data: dwengo_loki_data: dwengo_grafana_data: + ssl: diff --git a/frontend.Dockerfile b/frontend.Dockerfile index 6491bb5f..b5b765d2 100644 --- a/frontend.Dockerfile +++ b/frontend.Dockerfile @@ -10,6 +10,8 @@ RUN npm run build # production stage FROM nginx:stable AS production-stage +COPY ./nginx/nginx.conf /etc/nginx/ COPY --from=build-stage /app/frontend/dist /usr/share/nginx/html EXPOSE 80 +EXPOSE 443 CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 00000000..81bf2ae5 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,50 @@ +worker_processes auto; + +events { + worker_connections 1024; +} + +http { + server { + server_name sel2-1.ugent.be; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + location /api/ { + proxy_pass http://127.0.0.1:2002/; + } + + listen 80; + listen 443 default_server ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/sel2-1.ugent.be/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/sel2-1.ugent.be/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot + +} + + server { + listen 2002; + server_name dwengo-api; + + location / { + root /usr/share/api; + } + + } + +# server { +# if ($host = sel2-1.ugent.be) { +# return 301 https://$host$request_uri; +# } # managed by Certbot +# +# +# listen 80; +# server_name sel2-1.ugent.be; +# return 404; # managed by Certbot +# +# } +} \ No newline at end of file From 0c16f127e9a82374889a4c4be5424b5b667489be Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Sun, 9 Mar 2025 22:39:04 +0100 Subject: [PATCH 10/34] chore: docker-compose update context toegevoegd aan frontend en backend services --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index b7c73821..31044cc7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ services: web: build: + context: . dockerfile: ./frontend.Dockerfile depends_on: - api @@ -11,6 +12,7 @@ services: - ssl:/etc/letsencrypt/live/sel2-1.ugent.be/ api: build: + context: . dockerfile: ./backend.Dockerfile ports: - '2002:2002' From 8020b967032dbfc74b86f4b612ec768b57c39a48 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Sun, 9 Mar 2025 22:44:32 +0100 Subject: [PATCH 11/34] chore: docker-compose update ssl volume pad aangepast zodat elk nodig bestand gebruikt kan worden --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 31044cc7..acc7beb7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: - '443:443' - '80:80' volumes: - - ssl:/etc/letsencrypt/live/sel2-1.ugent.be/ + - ssl:/etc/letsencrypt/ api: build: context: . From da86ac94eedffaceb4a2f2151b898286a20fc527 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Sun, 9 Mar 2025 22:51:48 +0100 Subject: [PATCH 12/34] chore: update docker-compose SSL volume aangepast zodat het nu naar de juiste direcotry kijkt en read only is --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index acc7beb7..07b88488 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: - '443:443' - '80:80' volumes: - - ssl:/etc/letsencrypt/ + - /etc/letsencrypt/:/etc/letsencrypt/:ro api: build: context: . From 38ec0c75cafcdf27e7e2d2d598447ac413e98680 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Mon, 10 Mar 2025 00:07:25 +0100 Subject: [PATCH 13/34] =?UTF-8?q?chore:=20update=20backend=20dockerfile=20?= =?UTF-8?q?compiler=20config=20deftig=20gekopi=C3=ABerd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend.Dockerfile | 5 ++++- backend/.env.production | 6 ++++++ backend/package.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 backend/.env.production diff --git a/backend.Dockerfile b/backend.Dockerfile index f2967423..88be591d 100644 --- a/backend.Dockerfile +++ b/backend.Dockerfile @@ -7,9 +7,12 @@ COPY ./backend/package*.json ./ RUN npm install COPY ./backend ./backend +COPY ./tsconfig.json /app WORKDIR /app/backend +RUN npm run build + EXPOSE 2002 -CMD ["npm", "start"] \ No newline at end of file +CMD ["npm", "run", "start"] \ No newline at end of file diff --git a/backend/.env.production b/backend/.env.production new file mode 100644 index 00000000..58694df4 --- /dev/null +++ b/backend/.env.production @@ -0,0 +1,6 @@ +DWENGO_PORT=3000 +DWENGO_DB_HOST=localhost +DWENGO_DB_PORT=5431 +DWENGO_DB_USERNAME=postgres +DWENGO_DB_PASSWORD=postgres +DWENGO_DB_UPDATE=true diff --git a/backend/package.json b/backend/package.json index 478b26e6..3267d28f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -7,7 +7,7 @@ "scripts": { "build": "NODE_ENV=production tsc --project tsconfig.json", "dev": "NODE_ENV=development tsx watch --env-file=.env.development.local src/app.ts", - "start": "NODE_ENV=production node --env-file=.env dist/app.js", + "start": "NODE_ENV=production node --env-file=.env.production dist/app.js", "format": "prettier --write src/", "format-check": "prettier --check src/", "lint": "eslint . --fix", From 00541461885dd77339079d4e67d032896ee4d063 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Mon, 10 Mar 2025 00:37:09 +0100 Subject: [PATCH 14/34] chore: update nginx config SSL wordt standaard gebruikt --- nginx/nginx.conf | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 81bf2ae5..0185fdbc 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -17,7 +17,6 @@ http { proxy_pass http://127.0.0.1:2002/; } - listen 80; listen 443 default_server ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/sel2-1.ugent.be/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/sel2-1.ugent.be/privkey.pem; # managed by Certbot @@ -36,15 +35,15 @@ http { } -# server { -# if ($host = sel2-1.ugent.be) { -# return 301 https://$host$request_uri; -# } # managed by Certbot -# -# -# listen 80; -# server_name sel2-1.ugent.be; -# return 404; # managed by Certbot -# -# } + server { + if ($host = sel2-1.ugent.be) { + return 301 https://$host$request_uri; + } # managed by Certbot + + + listen 80; + server_name sel2-1.ugent.be; + return 404; # managed by Certbot + + } } \ No newline at end of file From 61d03bc7f2b4c485f16dcc941e2a0bb4d7380f25 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 08:25:30 +0100 Subject: [PATCH 15/34] =?UTF-8?q?fix:=20classes=20gedefini=C3=ABerd=20voor?= =?UTF-8?q?dat=20ze=20gebruikt=20worden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/learning-object.entity.ts | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/backend/src/entities/content/learning-object.entity.ts b/backend/src/entities/content/learning-object.entity.ts index 2b7d7684..9ff12ff0 100644 --- a/backend/src/entities/content/learning-object.entity.ts +++ b/backend/src/entities/content/learning-object.entity.ts @@ -3,6 +3,24 @@ import { Language } from './language.js'; import { Attachment } from './attachment.entity.js'; import { Teacher } from '../users/teacher.entity.js'; +@Embeddable() +export class EducationalGoal { + @Property({ type: 'string' }) + source!: string; + + @Property({ type: 'string' }) + id!: string; +} + +@Embeddable() +export class ReturnValue { + @Property({ type: 'string' }) + callbackUrl!: string; + + @Property({ type: 'json' }) + callbackSchema!: string; +} + @Entity() export class LearningObject { @PrimaryKey({ type: 'string' }) @@ -82,24 +100,6 @@ export class LearningObject { content!: Buffer; } -@Embeddable() -export class EducationalGoal { - @Property({ type: 'string' }) - source!: string; - - @Property({ type: 'string' }) - id!: string; -} - -@Embeddable() -export class ReturnValue { - @Property({ type: 'string' }) - callbackUrl!: string; - - @Property({ type: 'json' }) - callbackSchema!: string; -} - export enum ContentType { Markdown = 'text/markdown', Image = 'image/image', From 2bc59a17d9b7876e120129bbe3aef655136aadde Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 08:31:43 +0100 Subject: [PATCH 16/34] fix: update package versies @mikro-orm/sqlite moet zelfde versie zijn dan @mikro-orm/core --- backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/package.json b/backend/package.json index 3267d28f..f94c72cf 100644 --- a/backend/package.json +++ b/backend/package.json @@ -17,7 +17,7 @@ "@mikro-orm/core": "^6.4.6", "@mikro-orm/postgresql": "^6.4.6", "@mikro-orm/reflection": "^6.4.6", - "@mikro-orm/sqlite": "6.4.6", + "@mikro-orm/sqlite": "^6.4.6", "@types/js-yaml": "^4.0.9", "axios": "^1.8.1", "dotenv": "^16.4.7", From a2db3d1191fd27828e9ab81cd3e64620dc817aea Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 08:45:00 +0100 Subject: [PATCH 17/34] fix: package versies update Alles van mikro-orm is 6.4.6 --- backend/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/package.json b/backend/package.json index f94c72cf..07c3dae2 100644 --- a/backend/package.json +++ b/backend/package.json @@ -14,10 +14,10 @@ "test:unit": "vitest" }, "dependencies": { - "@mikro-orm/core": "^6.4.6", - "@mikro-orm/postgresql": "^6.4.6", - "@mikro-orm/reflection": "^6.4.6", - "@mikro-orm/sqlite": "^6.4.6", + "@mikro-orm/core": "6.4.6", + "@mikro-orm/postgresql": "6.4.6", + "@mikro-orm/reflection": "6.4.6", + "@mikro-orm/sqlite": "6.4.6", "@types/js-yaml": "^4.0.9", "axios": "^1.8.1", "dotenv": "^16.4.7", From d0190cef238c480be177dfe4f0eb9be7c38a626d Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 08:47:17 +0100 Subject: [PATCH 18/34] fix: package versies update @mikro-orm/cli vergeten bij vorige commit --- backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/package.json b/backend/package.json index 07c3dae2..4ec84cc0 100644 --- a/backend/package.json +++ b/backend/package.json @@ -30,7 +30,7 @@ "winston-loki": "^6.1.3" }, "devDependencies": { - "@mikro-orm/cli": "^6.4.6", + "@mikro-orm/cli": "6.4.6", "@types/express": "^5.0.0", "@types/node": "^22.13.4", "@types/response-time": "^2.3.8", From 468b371587e490fc2bd8c62e5af7cb87dc28d784 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 08:50:34 +0100 Subject: [PATCH 19/34] chore: docker compose update api container depends on db container --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 07b88488..72863d00 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,8 @@ services: build: context: . dockerfile: ./backend.Dockerfile + depends_on: + - db ports: - '2002:2002' db: From 885021b0b1aac28e70b326313778879e1e643964 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 09:22:49 +0100 Subject: [PATCH 20/34] chore: env variables aangepast DB_NAME toegevoegd --- backend/.env.production | 1 + backend/src/util/envvars.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/.env.production b/backend/.env.production index 58694df4..d202a4d9 100644 --- a/backend/.env.production +++ b/backend/.env.production @@ -1,6 +1,7 @@ DWENGO_PORT=3000 DWENGO_DB_HOST=localhost DWENGO_DB_PORT=5431 +DWENGO_DB_NAME=postgres DWENGO_DB_USERNAME=postgres DWENGO_DB_PASSWORD=postgres DWENGO_DB_UPDATE=true diff --git a/backend/src/util/envvars.ts b/backend/src/util/envvars.ts index 6d10e296..d0448bc8 100644 --- a/backend/src/util/envvars.ts +++ b/backend/src/util/envvars.ts @@ -6,7 +6,7 @@ type EnvVar = { key: string; required?: boolean; defaultValue?: any }; export const EnvVars: { [key: string]: EnvVar } = { Port: { key: PREFIX + 'PORT', defaultValue: 3000 }, DbHost: { key: DB_PREFIX + 'HOST', required: true }, - DbPort: { key: DB_PREFIX + 'PORT', defaultValue: 5432 }, + DbPort: { key: DB_PREFIX + 'PORT', defaultValue: 5431 }, DbName: { key: DB_PREFIX + 'NAME', defaultValue: 'dwengo' }, DbUsername: { key: DB_PREFIX + 'USERNAME', required: true }, DbPassword: { key: DB_PREFIX + 'PASSWORD', required: true }, From 72cab189a675dc0057ff89eb5cc8db881ce62dff Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 09:44:38 +0100 Subject: [PATCH 21/34] fix: update env vars DB_PORT aangepast --- backend/.env.production | 2 +- backend/src/util/envvars.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/.env.production b/backend/.env.production index d202a4d9..8ee6113e 100644 --- a/backend/.env.production +++ b/backend/.env.production @@ -1,6 +1,6 @@ DWENGO_PORT=3000 DWENGO_DB_HOST=localhost -DWENGO_DB_PORT=5431 +DWENGO_DB_PORT=5432 DWENGO_DB_NAME=postgres DWENGO_DB_USERNAME=postgres DWENGO_DB_PASSWORD=postgres diff --git a/backend/src/util/envvars.ts b/backend/src/util/envvars.ts index d0448bc8..6d10e296 100644 --- a/backend/src/util/envvars.ts +++ b/backend/src/util/envvars.ts @@ -6,7 +6,7 @@ type EnvVar = { key: string; required?: boolean; defaultValue?: any }; export const EnvVars: { [key: string]: EnvVar } = { Port: { key: PREFIX + 'PORT', defaultValue: 3000 }, DbHost: { key: DB_PREFIX + 'HOST', required: true }, - DbPort: { key: DB_PREFIX + 'PORT', defaultValue: 5431 }, + DbPort: { key: DB_PREFIX + 'PORT', defaultValue: 5432 }, DbName: { key: DB_PREFIX + 'NAME', defaultValue: 'dwengo' }, DbUsername: { key: DB_PREFIX + 'USERNAME', required: true }, DbPassword: { key: DB_PREFIX + 'PASSWORD', required: true }, From edccf4ef623b9c9e023bcb3f51d27e27e254d911 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 11 Mar 2025 09:45:24 +0100 Subject: [PATCH 22/34] chore: postgresql config toegevoegd postgresql config toegevoegd om voorlopig van alle adressen te luisteren --- config/postgresql/postgresql.conf | 862 ++++++++++++++++++++++++++++++ docker-compose.yml | 1 + 2 files changed, 863 insertions(+) create mode 100644 config/postgresql/postgresql.conf diff --git a/config/postgresql/postgresql.conf b/config/postgresql/postgresql.conf new file mode 100644 index 00000000..25070161 --- /dev/null +++ b/config/postgresql/postgresql.conf @@ -0,0 +1,862 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, run "pg_ctl reload", or execute +# "SELECT pg_reload_conf()". Some parameters, which are marked below, +# require a server shutdown and restart to take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: B = bytes Time units: us = microseconds +# kB = kilobytes ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +#data_directory = 'ConfigDir' # use data in another directory + # (change requires restart) +#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file + # (change requires restart) +#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +#external_pid_file = '' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '*' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +port = 5432 # (change requires restart) +#max_connections = 100 # (change requires restart) +#reserved_connections = 0 # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +#unix_socket_directories = '/tmp' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - TCP settings - +# see "man tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default +#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; + # 0 selects the system default + +#client_connection_check_interval = 0 # time between checks for client + # disconnection while running queries; + # 0 for never + +# - Authentication - + +#authentication_timeout = 1min # 1s-600s +#password_encryption = scram-sha-256 # scram-sha-256 or md5 +#scram_iterations = 4096 +#md5_password_warnings = on + +# GSSAPI using Kerberos +#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' +#krb_caseins_users = off +#gss_accept_delegation = off + +# - SSL - + +#ssl = off +#ssl_ca_file = '' +#ssl_cert_file = 'server.crt' +#ssl_crl_file = '' +#ssl_crl_dir = '' +#ssl_key_file = 'server.key' +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed TLSv1.2 ciphers +#ssl_tls13_ciphers = '' # allowed TLSv1.3 cipher suites, blank for default +#ssl_prefer_server_ciphers = on +#ssl_groups = 'prime256v1' +#ssl_min_protocol_version = 'TLSv1.2' +#ssl_max_protocol_version = '' +#ssl_dh_params_file = '' +#ssl_passphrase_command = '' +#ssl_passphrase_command_supports_reload = off + +# OAuth +#oauth_validator_libraries = '' # comma-separated list of trusted validator modules + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +#shared_buffers = 128MB # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#huge_page_size = 0 # zero for system default + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +#hash_mem_multiplier = 2.0 # 1-1000.0 multiplier on hash table work_mem +#maintenance_work_mem = 64MB # min 64kB +#autovacuum_work_mem = -1 # min 64kB, or -1 to use maintenance_work_mem +#logical_decoding_work_mem = 64MB # min 64kB +#max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) +#dynamic_shared_memory_type = posix # the default is usually the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # (change requires restart) +#min_dynamic_shared_memory = 0MB # (change requires restart) +#vacuum_buffer_usage_limit = 2MB # size of vacuum and analyze buffer access strategy ring; + # 0 to disable vacuum buffer access strategy; + # range 128kB to 16GB + +# SLRU buffers (change requires restart) +#commit_timestamp_buffers = 0 # memory for pg_commit_ts (0 = auto) +#multixact_offset_buffers = 16 # memory for pg_multixact/offsets +#multixact_member_buffers = 32 # memory for pg_multixact/members +#notify_buffers = 16 # memory for pg_notify +#serializable_buffers = 32 # memory for pg_serial +#subtransaction_buffers = 0 # memory for pg_subtrans (0 = auto) +#transaction_buffers = 0 # memory for pg_xact (0 = auto) + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kilobytes, or -1 for no limit + +#max_notify_queue_pages = 1048576 # limits the number of SLRU pages allocated + # for NOTIFY / LISTEN queue + +# - Kernel Resources - + +#max_files_per_process = 1000 # min 64 + # (change requires restart) + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 0 # measured in pages, 0 disables + +# - I/O - + +#backend_flush_after = 0 # measured in pages, 0 disables +#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching +#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching +#io_combine_limit = 128kB # usually 1-32 blocks (depends on OS) + +# - Worker Processes - + +#max_worker_processes = 8 # (change requires restart) +#max_parallel_workers_per_gather = 2 # limited by max_parallel_workers +#max_parallel_maintenance_workers = 2 # limited by max_parallel_workers +#max_parallel_workers = 8 # number of max_worker_processes that + # can be used in parallel operations +#parallel_leader_participation = on + + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = replica # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux and FreeBSD) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_compression = off # enables compression of full-page writes; + # off, pglz, lz4, zstd, or on +#wal_init_zero = on # zero-fill new WAL files +#wal_recycle = on # recycle WAL files +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables +#wal_skip_threshold = 2MB + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +#checkpoint_timeout = 5min # range 30s-1d +#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_flush_after = 0 # measured in pages, 0 disables +#checkpoint_warning = 30s # 0 disables +#max_wal_size = 1GB +#min_wal_size = 80MB + +# - Prefetching during recovery - + +#recovery_prefetch = try # prefetch pages referenced in the WAL? +#wal_decode_buffer_size = 512kB # lookahead window used for prefetching + # (change requires restart) + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_library = '' # library to use to archive a WAL file + # (empty string indicates archive_command should + # be used) +#archive_command = '' # command to use to archive a WAL file + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a WAL file switch after this + # number of seconds; 0 disables + +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived WAL file + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + +# - WAL Summarization - + +#summarize_wal = off # run WAL summarizer process? +#wal_summary_keep_time = '10d' # when to remove old summary files, 0 = never + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +# Set these on the primary and on any standby that will send replication data. + +#max_wal_senders = 10 # max number of walsender processes + # (change requires restart) +#max_replication_slots = 10 # max number of replication slots + # (change requires restart) +#wal_keep_size = 0 # in megabytes; 0 disables +#max_slot_wal_keep_size = -1 # in megabytes; -1 disables +#idle_replication_slot_timeout = 0 # in minutes; 0 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Primary Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # method to choose sync standbys, number of sync standbys, + # and comma-separated list of application_name + # from standby(s); '*' = all +#synchronized_standby_slots = '' # streaming replication standby server slot + # names that logical walsender processes will wait for + +# - Standby Servers - + +# These settings are ignored on a primary server. + +#primary_conninfo = '' # connection string to sending server +#primary_slot_name = '' # replication slot on sending server +#hot_standby = on # "off" disallows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name + # is not set +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from primary + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery +#sync_replication_slots = off # enables slot synchronization on the physical standby from the primary + +# - Subscribers - + +# These settings are ignored on a publisher. + +#max_logical_replication_workers = 4 # taken from max_worker_processes + # (change requires restart) +#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers +#max_parallel_apply_workers_per_subscription = 2 # taken from max_logical_replication_workers + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_async_append = on +#enable_bitmapscan = on +#enable_gathermerge = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_incremental_sort = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_memoize = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_parallel_append = on +#enable_parallel_hash = on +#enable_partition_pruning = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off +#enable_presorted_aggregate = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on +#enable_group_by_reordering = on +#enable_distinct_reordering = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#parallel_setup_cost = 1000.0 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB +#effective_cache_size = 4GB + +#jit_above_cost = 100000 # perform JIT compilation if available + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; + # -1 disables + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#jit = on # allow JIT compilation +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan +#recursive_worktable_factor = 10.0 # range 0.001-1000000 + + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +#log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, jsonlog, syslog, and + # eventlog, depending on platform. + # csvlog and jsonlog require + # logging_collector to be on. + +# This is used when logging to stderr: +#logging_collector = off # Enable capturing of stderr, jsonlog, + # and csvlog into log files. Required + # to be on for csvlogs and jsonlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +#log_directory = 'log' # directory where log files are written, + # can be absolute or relative to PGDATA +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + # can include strftime() escapes +#log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +#log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +#log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. +#log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (Windows): +# (change requires restart) +#event_source = 'PostgreSQL' + +# - When to Log - + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + +#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements + # and their durations, > 0 logs only a sample of + # statements running at least this number + # of milliseconds; + # sample fraction is determined by log_statement_sample_rate + +#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding + # log_min_duration_sample to be logged; + # 1.0 logs all such statements, 0.0 never logs + + +#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements + # are logged regardless of their duration; 1.0 logs all + # statements from all transactions, 0.0 never logs + +#log_startup_progress_interval = 10s # Time between progress updates for + # long-running startup operations. + # 0 disables the feature, > 0 indicates + # the interval in milliseconds. + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_autovacuum_min_duration = 10min # log autovacuum activity; + # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#log_checkpoints = on +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +#log_line_prefix = '%m [%p] ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %b = backend type + # %p = process ID + # %P = process ID of parallel group leader + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %n = timestamp with milliseconds (as a Unix epoch) + # %Q = query ID (0 if none or not computed) + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +#log_lock_waits = off # log lock waits >= deadlock_timeout +#log_recovery_conflict_waits = off # log standby recovery conflict waits + # >= deadlock_timeout +#log_parameter_max_length = -1 # when logging statements, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_parameter_max_length_on_error = 0 # when logging an error, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_statement = 'none' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +#log_timezone = 'GMT' + +# - Process Title - + +#cluster_name = '' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +# - Cumulative Query and Index Statistics - + +#track_activities = on +#track_activity_query_size = 1024 # (change requires restart) +#track_counts = on +#track_cost_delay_timing = off +#track_io_timing = off +#track_wal_io_timing = off +#track_functions = none # none, pl, all +#stats_fetch_consistency = cache # cache, none, snapshot + + +# - Monitoring - + +#compute_query_id = auto +#log_statement_stats = off +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off + + +#------------------------------------------------------------------------------ +# VACUUMING +#------------------------------------------------------------------------------ + +# - Automatic Vacuuming - + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +autovacuum_worker_slots = 16 # autovacuum worker slots to allocate + # (change requires restart) +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts + # before vacuum; -1 disables insert + # vacuums +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of unfrozen pages + # before insert vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_vacuum_max_threshold = 100000000 # max number of row updates + # before vacuum; -1 disables max + # threshold +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 2 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Freezing - + +#vacuum_freeze_table_age = 150000000 +#vacuum_freeze_min_age = 50000000 +#vacuum_failsafe_age = 1600000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_failsafe_age = 1600000000 +#vacuum_max_eager_freeze_failure_rate = 0.03 # 0 disables eager scanning + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error +#search_path = '"$user", public' # schema names +#row_security = on +#default_table_access_method = 'heap' +#default_tablespace = '' # a tablespace name, '' uses the default +#default_toast_compression = 'pglz' # 'pglz' or 'lz4' +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#transaction_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled +#idle_session_timeout = 0 # in milliseconds, 0 is disabled +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_pending_list_limit = 4MB +#createrole_self_grant = '' # set and/or inherit +#event_triggers = on + +# - Locale and Formatting - + +#datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +#timezone = 'GMT' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +#lc_messages = '' # locale for system error message + # strings +#lc_monetary = 'C' # locale for monetary formatting +#lc_numeric = 'C' # locale for number formatting +#lc_time = 'C' # locale for time formatting + +#icu_validation_level = warning # report ICU locale validation + # errors at the given level + +# default configuration for text search +#default_text_search_config = 'pg_catalog.simple' + +# - Shared Library Preloading - + +#local_preload_libraries = '' +#session_preload_libraries = '' +#shared_preload_libraries = '' # (change requires restart) +#jit_provider = 'llvmjit' # JIT library to use + +# - Other Defaults - + +#dynamic_library_path = '$libdir' +#gin_fuzzy_search_limit = 0 + + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_relation = -2 # negative values mean + # (max_pred_locks_per_transaction + # / -max_pred_locks_per_relation) - 1 +#max_pred_locks_per_page = 2 # min 0 + + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off +#allow_alter_system = on + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? +#data_sync_retry = off # retry or panic on failure to fsync + # data? + # (change requires restart) +#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+) + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. + +#include_dir = '...' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 72863d00..d20d819d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,7 @@ services: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres + POSTGRES_INITDB_ARGS: -T ./config/postgresql/postgresql.conf ports: - '5431:5432' volumes: From 0053279dc3ac19257d799ba5dd4f6c95914df129 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 11 Mar 2025 13:50:55 +0100 Subject: [PATCH 23/34] ci: Frontend routing --- backend.Dockerfile | 18 - backend/{.env.test => .env.test.example} | 0 backend/Dockerfile | 35 + backend/package.json | 4 +- config/nginx/nginx.conf | 16 + config/postgresql/postgresql.conf | 862 ----------------------- docker-compose.production.yml | 108 +++ docker-compose.yml | 64 +- frontend.Dockerfile | 17 - frontend/Dockerfile | 35 + nginx/nginx.conf | 49 -- 11 files changed, 248 insertions(+), 960 deletions(-) delete mode 100644 backend.Dockerfile rename backend/{.env.test => .env.test.example} (100%) create mode 100644 backend/Dockerfile create mode 100644 config/nginx/nginx.conf delete mode 100644 config/postgresql/postgresql.conf create mode 100644 docker-compose.production.yml delete mode 100644 frontend.Dockerfile create mode 100644 frontend/Dockerfile delete mode 100644 nginx/nginx.conf diff --git a/backend.Dockerfile b/backend.Dockerfile deleted file mode 100644 index 88be591d..00000000 --- a/backend.Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM node:22 - -WORKDIR /app - -COPY ./backend/package*.json ./ - -RUN npm install - -COPY ./backend ./backend -COPY ./tsconfig.json /app - -WORKDIR /app/backend - -RUN npm run build - -EXPOSE 2002 - -CMD ["npm", "run", "start"] \ No newline at end of file diff --git a/backend/.env.test b/backend/.env.test.example similarity index 100% rename from backend/.env.test rename to backend/.env.test.example diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 00000000..5f26847c --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,35 @@ +FROM node:22 AS build-stage + +WORKDIR /app + +# Install dependencies + +COPY package*.json ./ +COPY backend/package.json ./backend/ + +RUN npm install --silent + +# Build the backend + +# Root tsconfig.json +COPY tsconfig.json ./ + +WORKDIR /app/backend + +COPY backend ./ + +RUN npm run build + +FROM node:22 AS production-stage + +WORKDIR /app + +COPY package-lock.json backend/package.json ./ + +RUN npm install --silent --only=production + +COPY --from=build-stage /app/backend/dist ./dist/ + +EXPOSE 3000 + +CMD ["node", "--env-file=.env", "dist/app.js"] diff --git a/backend/package.json b/backend/package.json index 4ec84cc0..930932fb 100644 --- a/backend/package.json +++ b/backend/package.json @@ -7,7 +7,7 @@ "scripts": { "build": "NODE_ENV=production tsc --project tsconfig.json", "dev": "NODE_ENV=development tsx watch --env-file=.env.development.local src/app.ts", - "start": "NODE_ENV=production node --env-file=.env.production dist/app.js", + "start": "NODE_ENV=production node --env-file=.env dist/app.js", "format": "prettier --write src/", "format-check": "prettier --check src/", "lint": "eslint . --fix", @@ -18,7 +18,6 @@ "@mikro-orm/postgresql": "6.4.6", "@mikro-orm/reflection": "6.4.6", "@mikro-orm/sqlite": "6.4.6", - "@types/js-yaml": "^4.0.9", "axios": "^1.8.1", "dotenv": "^16.4.7", "express": "^5.0.1", @@ -34,6 +33,7 @@ "@types/express": "^5.0.0", "@types/node": "^22.13.4", "@types/response-time": "^2.3.8", + "@types/js-yaml": "^4.0.9", "globals": "^15.15.0", "ts-node": "^10.9.2", "tsx": "^4.19.3", diff --git a/config/nginx/nginx.conf b/config/nginx/nginx.conf new file mode 100644 index 00000000..650a09c9 --- /dev/null +++ b/config/nginx/nginx.conf @@ -0,0 +1,16 @@ +worker_processes auto; + +events { + worker_connections 1024; +} + +http { + server { + listen 80; + + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + } + } +} diff --git a/config/postgresql/postgresql.conf b/config/postgresql/postgresql.conf deleted file mode 100644 index 25070161..00000000 --- a/config/postgresql/postgresql.conf +++ /dev/null @@ -1,862 +0,0 @@ -# ----------------------------- -# PostgreSQL configuration file -# ----------------------------- -# -# This file consists of lines of the form: -# -# name = value -# -# (The "=" is optional.) Whitespace may be used. Comments are introduced with -# "#" anywhere on a line. The complete list of parameter names and allowed -# values can be found in the PostgreSQL documentation. -# -# The commented-out settings shown in this file represent the default values. -# Re-commenting a setting is NOT sufficient to revert it to the default value; -# you need to reload the server. -# -# This file is read on server startup and when the server receives a SIGHUP -# signal. If you edit the file on a running system, you have to SIGHUP the -# server for the changes to take effect, run "pg_ctl reload", or execute -# "SELECT pg_reload_conf()". Some parameters, which are marked below, -# require a server shutdown and restart to take effect. -# -# Any parameter can also be given as a command-line option to the server, e.g., -# "postgres -c log_connections=on". Some parameters can be changed at run time -# with the "SET" SQL command. -# -# Memory units: B = bytes Time units: us = microseconds -# kB = kilobytes ms = milliseconds -# MB = megabytes s = seconds -# GB = gigabytes min = minutes -# TB = terabytes h = hours -# d = days - - -#------------------------------------------------------------------------------ -# FILE LOCATIONS -#------------------------------------------------------------------------------ - -# The default values of these variables are driven from the -D command-line -# option or PGDATA environment variable, represented here as ConfigDir. - -#data_directory = 'ConfigDir' # use data in another directory - # (change requires restart) -#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file - # (change requires restart) -#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file - # (change requires restart) - -# If external_pid_file is not explicitly set, no extra PID file is written. -#external_pid_file = '' # write an extra PID file - # (change requires restart) - - -#------------------------------------------------------------------------------ -# CONNECTIONS AND AUTHENTICATION -#------------------------------------------------------------------------------ - -# - Connection Settings - - -listen_addresses = '*' # what IP address(es) to listen on; - # comma-separated list of addresses; - # defaults to 'localhost'; use '*' for all - # (change requires restart) -port = 5432 # (change requires restart) -#max_connections = 100 # (change requires restart) -#reserved_connections = 0 # (change requires restart) -#superuser_reserved_connections = 3 # (change requires restart) -#unix_socket_directories = '/tmp' # comma-separated list of directories - # (change requires restart) -#unix_socket_group = '' # (change requires restart) -#unix_socket_permissions = 0777 # begin with 0 to use octal notation - # (change requires restart) -#bonjour = off # advertise server via Bonjour - # (change requires restart) -#bonjour_name = '' # defaults to the computer name - # (change requires restart) - -# - TCP settings - -# see "man tcp" for details - -#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; - # 0 selects the system default -#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; - # 0 selects the system default -#tcp_keepalives_count = 0 # TCP_KEEPCNT; - # 0 selects the system default -#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; - # 0 selects the system default - -#client_connection_check_interval = 0 # time between checks for client - # disconnection while running queries; - # 0 for never - -# - Authentication - - -#authentication_timeout = 1min # 1s-600s -#password_encryption = scram-sha-256 # scram-sha-256 or md5 -#scram_iterations = 4096 -#md5_password_warnings = on - -# GSSAPI using Kerberos -#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' -#krb_caseins_users = off -#gss_accept_delegation = off - -# - SSL - - -#ssl = off -#ssl_ca_file = '' -#ssl_cert_file = 'server.crt' -#ssl_crl_file = '' -#ssl_crl_dir = '' -#ssl_key_file = 'server.key' -#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed TLSv1.2 ciphers -#ssl_tls13_ciphers = '' # allowed TLSv1.3 cipher suites, blank for default -#ssl_prefer_server_ciphers = on -#ssl_groups = 'prime256v1' -#ssl_min_protocol_version = 'TLSv1.2' -#ssl_max_protocol_version = '' -#ssl_dh_params_file = '' -#ssl_passphrase_command = '' -#ssl_passphrase_command_supports_reload = off - -# OAuth -#oauth_validator_libraries = '' # comma-separated list of trusted validator modules - - -#------------------------------------------------------------------------------ -# RESOURCE USAGE (except WAL) -#------------------------------------------------------------------------------ - -# - Memory - - -#shared_buffers = 128MB # min 128kB - # (change requires restart) -#huge_pages = try # on, off, or try - # (change requires restart) -#huge_page_size = 0 # zero for system default - # (change requires restart) -#temp_buffers = 8MB # min 800kB -#max_prepared_transactions = 0 # zero disables the feature - # (change requires restart) -# Caution: it is not advisable to set max_prepared_transactions nonzero unless -# you actively intend to use prepared transactions. -#work_mem = 4MB # min 64kB -#hash_mem_multiplier = 2.0 # 1-1000.0 multiplier on hash table work_mem -#maintenance_work_mem = 64MB # min 64kB -#autovacuum_work_mem = -1 # min 64kB, or -1 to use maintenance_work_mem -#logical_decoding_work_mem = 64MB # min 64kB -#max_stack_depth = 2MB # min 100kB -#shared_memory_type = mmap # the default is the first option - # supported by the operating system: - # mmap - # sysv - # windows - # (change requires restart) -#dynamic_shared_memory_type = posix # the default is usually the first option - # supported by the operating system: - # posix - # sysv - # windows - # mmap - # (change requires restart) -#min_dynamic_shared_memory = 0MB # (change requires restart) -#vacuum_buffer_usage_limit = 2MB # size of vacuum and analyze buffer access strategy ring; - # 0 to disable vacuum buffer access strategy; - # range 128kB to 16GB - -# SLRU buffers (change requires restart) -#commit_timestamp_buffers = 0 # memory for pg_commit_ts (0 = auto) -#multixact_offset_buffers = 16 # memory for pg_multixact/offsets -#multixact_member_buffers = 32 # memory for pg_multixact/members -#notify_buffers = 16 # memory for pg_notify -#serializable_buffers = 32 # memory for pg_serial -#subtransaction_buffers = 0 # memory for pg_subtrans (0 = auto) -#transaction_buffers = 0 # memory for pg_xact (0 = auto) - -# - Disk - - -#temp_file_limit = -1 # limits per-process temp file space - # in kilobytes, or -1 for no limit - -#max_notify_queue_pages = 1048576 # limits the number of SLRU pages allocated - # for NOTIFY / LISTEN queue - -# - Kernel Resources - - -#max_files_per_process = 1000 # min 64 - # (change requires restart) - -# - Background Writer - - -#bgwriter_delay = 200ms # 10-10000ms between rounds -#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables -#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round -#bgwriter_flush_after = 0 # measured in pages, 0 disables - -# - I/O - - -#backend_flush_after = 0 # measured in pages, 0 disables -#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching -#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching -#io_combine_limit = 128kB # usually 1-32 blocks (depends on OS) - -# - Worker Processes - - -#max_worker_processes = 8 # (change requires restart) -#max_parallel_workers_per_gather = 2 # limited by max_parallel_workers -#max_parallel_maintenance_workers = 2 # limited by max_parallel_workers -#max_parallel_workers = 8 # number of max_worker_processes that - # can be used in parallel operations -#parallel_leader_participation = on - - -#------------------------------------------------------------------------------ -# WRITE-AHEAD LOG -#------------------------------------------------------------------------------ - -# - Settings - - -#wal_level = replica # minimal, replica, or logical - # (change requires restart) -#fsync = on # flush data to disk for crash safety - # (turning this off can cause - # unrecoverable data corruption) -#synchronous_commit = on # synchronization level; - # off, local, remote_write, remote_apply, or on -#wal_sync_method = fsync # the default is the first option - # supported by the operating system: - # open_datasync - # fdatasync (default on Linux and FreeBSD) - # fsync - # fsync_writethrough - # open_sync -#full_page_writes = on # recover from partial page writes -#wal_log_hints = off # also do full page writes of non-critical updates - # (change requires restart) -#wal_compression = off # enables compression of full-page writes; - # off, pglz, lz4, zstd, or on -#wal_init_zero = on # zero-fill new WAL files -#wal_recycle = on # recycle WAL files -#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers - # (change requires restart) -#wal_writer_delay = 200ms # 1-10000 milliseconds -#wal_writer_flush_after = 1MB # measured in pages, 0 disables -#wal_skip_threshold = 2MB - -#commit_delay = 0 # range 0-100000, in microseconds -#commit_siblings = 5 # range 1-1000 - -# - Checkpoints - - -#checkpoint_timeout = 5min # range 30s-1d -#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0 -#checkpoint_flush_after = 0 # measured in pages, 0 disables -#checkpoint_warning = 30s # 0 disables -#max_wal_size = 1GB -#min_wal_size = 80MB - -# - Prefetching during recovery - - -#recovery_prefetch = try # prefetch pages referenced in the WAL? -#wal_decode_buffer_size = 512kB # lookahead window used for prefetching - # (change requires restart) - -# - Archiving - - -#archive_mode = off # enables archiving; off, on, or always - # (change requires restart) -#archive_library = '' # library to use to archive a WAL file - # (empty string indicates archive_command should - # be used) -#archive_command = '' # command to use to archive a WAL file - # placeholders: %p = path of file to archive - # %f = file name only - # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' -#archive_timeout = 0 # force a WAL file switch after this - # number of seconds; 0 disables - -# - Archive Recovery - - -# These are only used in recovery mode. - -#restore_command = '' # command to use to restore an archived WAL file - # placeholders: %p = path of file to restore - # %f = file name only - # e.g. 'cp /mnt/server/archivedir/%f %p' -#archive_cleanup_command = '' # command to execute at every restartpoint -#recovery_end_command = '' # command to execute at completion of recovery - -# - Recovery Target - - -# Set these only when performing a targeted recovery. - -#recovery_target = '' # 'immediate' to end recovery as soon as a - # consistent state is reached - # (change requires restart) -#recovery_target_name = '' # the named restore point to which recovery will proceed - # (change requires restart) -#recovery_target_time = '' # the time stamp up to which recovery will proceed - # (change requires restart) -#recovery_target_xid = '' # the transaction ID up to which recovery will proceed - # (change requires restart) -#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed - # (change requires restart) -#recovery_target_inclusive = on # Specifies whether to stop: - # just after the specified recovery target (on) - # just before the recovery target (off) - # (change requires restart) -#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID - # (change requires restart) -#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' - # (change requires restart) - -# - WAL Summarization - - -#summarize_wal = off # run WAL summarizer process? -#wal_summary_keep_time = '10d' # when to remove old summary files, 0 = never - - -#------------------------------------------------------------------------------ -# REPLICATION -#------------------------------------------------------------------------------ - -# - Sending Servers - - -# Set these on the primary and on any standby that will send replication data. - -#max_wal_senders = 10 # max number of walsender processes - # (change requires restart) -#max_replication_slots = 10 # max number of replication slots - # (change requires restart) -#wal_keep_size = 0 # in megabytes; 0 disables -#max_slot_wal_keep_size = -1 # in megabytes; -1 disables -#idle_replication_slot_timeout = 0 # in minutes; 0 disables -#wal_sender_timeout = 60s # in milliseconds; 0 disables -#track_commit_timestamp = off # collect timestamp of transaction commit - # (change requires restart) - -# - Primary Server - - -# These settings are ignored on a standby server. - -#synchronous_standby_names = '' # standby servers that provide sync rep - # method to choose sync standbys, number of sync standbys, - # and comma-separated list of application_name - # from standby(s); '*' = all -#synchronized_standby_slots = '' # streaming replication standby server slot - # names that logical walsender processes will wait for - -# - Standby Servers - - -# These settings are ignored on a primary server. - -#primary_conninfo = '' # connection string to sending server -#primary_slot_name = '' # replication slot on sending server -#hot_standby = on # "off" disallows queries during recovery - # (change requires restart) -#max_standby_archive_delay = 30s # max delay before canceling queries - # when reading WAL from archive; - # -1 allows indefinite delay -#max_standby_streaming_delay = 30s # max delay before canceling queries - # when reading streaming WAL; - # -1 allows indefinite delay -#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name - # is not set -#wal_receiver_status_interval = 10s # send replies at least this often - # 0 disables -#hot_standby_feedback = off # send info from standby to prevent - # query conflicts -#wal_receiver_timeout = 60s # time that receiver waits for - # communication from primary - # in milliseconds; 0 disables -#wal_retrieve_retry_interval = 5s # time to wait before retrying to - # retrieve WAL after a failed attempt -#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery -#sync_replication_slots = off # enables slot synchronization on the physical standby from the primary - -# - Subscribers - - -# These settings are ignored on a publisher. - -#max_logical_replication_workers = 4 # taken from max_worker_processes - # (change requires restart) -#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers -#max_parallel_apply_workers_per_subscription = 2 # taken from max_logical_replication_workers - - -#------------------------------------------------------------------------------ -# QUERY TUNING -#------------------------------------------------------------------------------ - -# - Planner Method Configuration - - -#enable_async_append = on -#enable_bitmapscan = on -#enable_gathermerge = on -#enable_hashagg = on -#enable_hashjoin = on -#enable_incremental_sort = on -#enable_indexscan = on -#enable_indexonlyscan = on -#enable_material = on -#enable_memoize = on -#enable_mergejoin = on -#enable_nestloop = on -#enable_parallel_append = on -#enable_parallel_hash = on -#enable_partition_pruning = on -#enable_partitionwise_join = off -#enable_partitionwise_aggregate = off -#enable_presorted_aggregate = on -#enable_seqscan = on -#enable_sort = on -#enable_tidscan = on -#enable_group_by_reordering = on -#enable_distinct_reordering = on - -# - Planner Cost Constants - - -#seq_page_cost = 1.0 # measured on an arbitrary scale -#random_page_cost = 4.0 # same scale as above -#cpu_tuple_cost = 0.01 # same scale as above -#cpu_index_tuple_cost = 0.005 # same scale as above -#cpu_operator_cost = 0.0025 # same scale as above -#parallel_setup_cost = 1000.0 # same scale as above -#parallel_tuple_cost = 0.1 # same scale as above -#min_parallel_table_scan_size = 8MB -#min_parallel_index_scan_size = 512kB -#effective_cache_size = 4GB - -#jit_above_cost = 100000 # perform JIT compilation if available - # and query more expensive than this; - # -1 disables -#jit_inline_above_cost = 500000 # inline small functions if query is - # more expensive than this; -1 disables -#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if - # query is more expensive than this; - # -1 disables - -# - Genetic Query Optimizer - - -#geqo = on -#geqo_threshold = 12 -#geqo_effort = 5 # range 1-10 -#geqo_pool_size = 0 # selects default based on effort -#geqo_generations = 0 # selects default based on effort -#geqo_selection_bias = 2.0 # range 1.5-2.0 -#geqo_seed = 0.0 # range 0.0-1.0 - -# - Other Planner Options - - -#default_statistics_target = 100 # range 1-10000 -#constraint_exclusion = partition # on, off, or partition -#cursor_tuple_fraction = 0.1 # range 0.0-1.0 -#from_collapse_limit = 8 -#jit = on # allow JIT compilation -#join_collapse_limit = 8 # 1 disables collapsing of explicit - # JOIN clauses -#plan_cache_mode = auto # auto, force_generic_plan or - # force_custom_plan -#recursive_worktable_factor = 10.0 # range 0.001-1000000 - - -#------------------------------------------------------------------------------ -# REPORTING AND LOGGING -#------------------------------------------------------------------------------ - -# - Where to Log - - -#log_destination = 'stderr' # Valid values are combinations of - # stderr, csvlog, jsonlog, syslog, and - # eventlog, depending on platform. - # csvlog and jsonlog require - # logging_collector to be on. - -# This is used when logging to stderr: -#logging_collector = off # Enable capturing of stderr, jsonlog, - # and csvlog into log files. Required - # to be on for csvlogs and jsonlogs. - # (change requires restart) - -# These are only used if logging_collector is on: -#log_directory = 'log' # directory where log files are written, - # can be absolute or relative to PGDATA -#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, - # can include strftime() escapes -#log_file_mode = 0600 # creation mode for log files, - # begin with 0 to use octal notation -#log_rotation_age = 1d # Automatic rotation of logfiles will - # happen after that time. 0 disables. -#log_rotation_size = 10MB # Automatic rotation of logfiles will - # happen after that much log output. - # 0 disables. -#log_truncate_on_rotation = off # If on, an existing log file with the - # same name as the new log file will be - # truncated rather than appended to. - # But such truncation only occurs on - # time-driven rotation, not on restarts - # or size-driven rotation. Default is - # off, meaning append to existing files - # in all cases. - -# These are relevant when logging to syslog: -#syslog_facility = 'LOCAL0' -#syslog_ident = 'postgres' -#syslog_sequence_numbers = on -#syslog_split_messages = on - -# This is only relevant when logging to eventlog (Windows): -# (change requires restart) -#event_source = 'PostgreSQL' - -# - When to Log - - -#log_min_messages = warning # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic - -#log_min_error_statement = error # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic (effectively off) - -#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements - # and their durations, > 0 logs only - # statements running at least this number - # of milliseconds - -#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements - # and their durations, > 0 logs only a sample of - # statements running at least this number - # of milliseconds; - # sample fraction is determined by log_statement_sample_rate - -#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding - # log_min_duration_sample to be logged; - # 1.0 logs all such statements, 0.0 never logs - - -#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements - # are logged regardless of their duration; 1.0 logs all - # statements from all transactions, 0.0 never logs - -#log_startup_progress_interval = 10s # Time between progress updates for - # long-running startup operations. - # 0 disables the feature, > 0 indicates - # the interval in milliseconds. - -# - What to Log - - -#debug_print_parse = off -#debug_print_rewritten = off -#debug_print_plan = off -#debug_pretty_print = on -#log_autovacuum_min_duration = 10min # log autovacuum activity; - # -1 disables, 0 logs all actions and - # their durations, > 0 logs only - # actions running at least this number - # of milliseconds. -#log_checkpoints = on -#log_connections = off -#log_disconnections = off -#log_duration = off -#log_error_verbosity = default # terse, default, or verbose messages -#log_hostname = off -#log_line_prefix = '%m [%p] ' # special values: - # %a = application name - # %u = user name - # %d = database name - # %r = remote host and port - # %h = remote host - # %b = backend type - # %p = process ID - # %P = process ID of parallel group leader - # %t = timestamp without milliseconds - # %m = timestamp with milliseconds - # %n = timestamp with milliseconds (as a Unix epoch) - # %Q = query ID (0 if none or not computed) - # %i = command tag - # %e = SQL state - # %c = session ID - # %l = session line number - # %s = session start timestamp - # %v = virtual transaction ID - # %x = transaction ID (0 if none) - # %q = stop here in non-session - # processes - # %% = '%' - # e.g. '<%u%%%d> ' -#log_lock_waits = off # log lock waits >= deadlock_timeout -#log_recovery_conflict_waits = off # log standby recovery conflict waits - # >= deadlock_timeout -#log_parameter_max_length = -1 # when logging statements, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -#log_parameter_max_length_on_error = 0 # when logging an error, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -#log_statement = 'none' # none, ddl, mod, all -#log_replication_commands = off -#log_temp_files = -1 # log temporary files equal or larger - # than the specified size in kilobytes; - # -1 disables, 0 logs all temp files -#log_timezone = 'GMT' - -# - Process Title - - -#cluster_name = '' # added to process titles if nonempty - # (change requires restart) -#update_process_title = on - - -#------------------------------------------------------------------------------ -# STATISTICS -#------------------------------------------------------------------------------ - -# - Cumulative Query and Index Statistics - - -#track_activities = on -#track_activity_query_size = 1024 # (change requires restart) -#track_counts = on -#track_cost_delay_timing = off -#track_io_timing = off -#track_wal_io_timing = off -#track_functions = none # none, pl, all -#stats_fetch_consistency = cache # cache, none, snapshot - - -# - Monitoring - - -#compute_query_id = auto -#log_statement_stats = off -#log_parser_stats = off -#log_planner_stats = off -#log_executor_stats = off - - -#------------------------------------------------------------------------------ -# VACUUMING -#------------------------------------------------------------------------------ - -# - Automatic Vacuuming - - -#autovacuum = on # Enable autovacuum subprocess? 'on' - # requires track_counts to also be on. -autovacuum_worker_slots = 16 # autovacuum worker slots to allocate - # (change requires restart) -#autovacuum_max_workers = 3 # max number of autovacuum subprocesses -#autovacuum_naptime = 1min # time between autovacuum runs -#autovacuum_vacuum_threshold = 50 # min number of row updates before - # vacuum -#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts - # before vacuum; -1 disables insert - # vacuums -#autovacuum_analyze_threshold = 50 # min number of row updates before - # analyze -#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum -#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of unfrozen pages - # before insert vacuum -#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze -#autovacuum_vacuum_max_threshold = 100000000 # max number of row updates - # before vacuum; -1 disables max - # threshold -#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum - # (change requires restart) -#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age - # before forced vacuum - # (change requires restart) -#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for - # autovacuum, in milliseconds; - # -1 means use vacuum_cost_delay -#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for - # autovacuum, -1 means use - # vacuum_cost_limit - -# - Cost-Based Vacuum Delay - - -#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) -#vacuum_cost_page_hit = 1 # 0-10000 credits -#vacuum_cost_page_miss = 2 # 0-10000 credits -#vacuum_cost_page_dirty = 20 # 0-10000 credits -#vacuum_cost_limit = 200 # 1-10000 credits - -# - Freezing - - -#vacuum_freeze_table_age = 150000000 -#vacuum_freeze_min_age = 50000000 -#vacuum_failsafe_age = 1600000000 -#vacuum_multixact_freeze_table_age = 150000000 -#vacuum_multixact_freeze_min_age = 5000000 -#vacuum_multixact_failsafe_age = 1600000000 -#vacuum_max_eager_freeze_failure_rate = 0.03 # 0 disables eager scanning - -#------------------------------------------------------------------------------ -# CLIENT CONNECTION DEFAULTS -#------------------------------------------------------------------------------ - -# - Statement Behavior - - -#client_min_messages = notice # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # log - # notice - # warning - # error -#search_path = '"$user", public' # schema names -#row_security = on -#default_table_access_method = 'heap' -#default_tablespace = '' # a tablespace name, '' uses the default -#default_toast_compression = 'pglz' # 'pglz' or 'lz4' -#temp_tablespaces = '' # a list of tablespace names, '' uses - # only default tablespace -#check_function_bodies = on -#default_transaction_isolation = 'read committed' -#default_transaction_read_only = off -#default_transaction_deferrable = off -#session_replication_role = 'origin' -#statement_timeout = 0 # in milliseconds, 0 is disabled -#transaction_timeout = 0 # in milliseconds, 0 is disabled -#lock_timeout = 0 # in milliseconds, 0 is disabled -#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled -#idle_session_timeout = 0 # in milliseconds, 0 is disabled -#bytea_output = 'hex' # hex, escape -#xmlbinary = 'base64' -#xmloption = 'content' -#gin_pending_list_limit = 4MB -#createrole_self_grant = '' # set and/or inherit -#event_triggers = on - -# - Locale and Formatting - - -#datestyle = 'iso, mdy' -#intervalstyle = 'postgres' -#timezone = 'GMT' -#timezone_abbreviations = 'Default' # Select the set of available time zone - # abbreviations. Currently, there are - # Default - # Australia (historical usage) - # India - # You can create your own file in - # share/timezonesets/. -#extra_float_digits = 1 # min -15, max 3; any value >0 actually - # selects precise output mode -#client_encoding = sql_ascii # actually, defaults to database - # encoding - -# These settings are initialized by initdb, but they can be changed. -#lc_messages = '' # locale for system error message - # strings -#lc_monetary = 'C' # locale for monetary formatting -#lc_numeric = 'C' # locale for number formatting -#lc_time = 'C' # locale for time formatting - -#icu_validation_level = warning # report ICU locale validation - # errors at the given level - -# default configuration for text search -#default_text_search_config = 'pg_catalog.simple' - -# - Shared Library Preloading - - -#local_preload_libraries = '' -#session_preload_libraries = '' -#shared_preload_libraries = '' # (change requires restart) -#jit_provider = 'llvmjit' # JIT library to use - -# - Other Defaults - - -#dynamic_library_path = '$libdir' -#gin_fuzzy_search_limit = 0 - - -#------------------------------------------------------------------------------ -# LOCK MANAGEMENT -#------------------------------------------------------------------------------ - -#deadlock_timeout = 1s -#max_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_relation = -2 # negative values mean - # (max_pred_locks_per_transaction - # / -max_pred_locks_per_relation) - 1 -#max_pred_locks_per_page = 2 # min 0 - - -#------------------------------------------------------------------------------ -# VERSION AND PLATFORM COMPATIBILITY -#------------------------------------------------------------------------------ - -# - Previous PostgreSQL Versions - - -#array_nulls = on -#backslash_quote = safe_encoding # on, off, or safe_encoding -#escape_string_warning = on -#lo_compat_privileges = off -#quote_all_identifiers = off -#standard_conforming_strings = on -#synchronize_seqscans = on - -# - Other Platforms and Clients - - -#transform_null_equals = off -#allow_alter_system = on - - -#------------------------------------------------------------------------------ -# ERROR HANDLING -#------------------------------------------------------------------------------ - -#exit_on_error = off # terminate session on any error? -#restart_after_crash = on # reinitialize after backend crash? -#data_sync_retry = off # retry or panic on failure to fsync - # data? - # (change requires restart) -#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+) - - -#------------------------------------------------------------------------------ -# CONFIG FILE INCLUDES -#------------------------------------------------------------------------------ - -# These options allow settings to be loaded from files other than the -# default postgresql.conf. Note that these are directives, not variable -# assignments, so they can usefully be given more than once. - -#include_dir = '...' # include files ending in '.conf' from - # a directory, e.g., 'conf.d' -#include_if_exists = '...' # include file only if it exists -#include = '...' # include file - - -#------------------------------------------------------------------------------ -# CUSTOMIZED OPTIONS -#------------------------------------------------------------------------------ - -# Add settings for extensions here \ No newline at end of file diff --git a/docker-compose.production.yml b/docker-compose.production.yml new file mode 100644 index 00000000..64117082 --- /dev/null +++ b/docker-compose.production.yml @@ -0,0 +1,108 @@ +services: + web: + build: + context: . + dockerfile: ./frontend/Dockerfile + restart: unless-stopped + networks: + - dwengo-1 + labels: + - "traefik.enable=true" + - "traefik.http.routers.web.rule=PathPrefix(`/`)" + - "traefik.http.services.web.loadbalancer.server.port=80" + + api: + build: + context: . + dockerfile: ./backend/Dockerfile + restart: unless-stopped + volumes: + # TODO Replace with environment keys + - ./backend/.env:/app/.env + networks: + - dwengo-1 + depends_on: + - db + - logging + labels: + - "traefik.enable=true" + - "traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api" + - "traefik.http.routers.api.rule=Host(`sel2-1.ugent.be`)" + - "traefik.http.routers.api.rule=PathPrefix(`/api`)" + - "traefik.http.routers.api.middlewares=api-prefix" + - "traefik.http.services.api.loadbalancer.server.port=3000" + + db: + image: postgres:latest + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + restart: unless-stopped + volumes: + - dwengo_postgres_data:/var/lib/postgresql/data + networks: + - dwengo-1 + + reverse-proxy: + image: traefik:v3.3 + command: > + --api.insecure=true + --providers.docker=true + --providers.docker.exposedbydefault=false + --entrypoints.web.address=:80/tcp + --entrypoints.web.http.redirections.entryPoint.to=websecure + --entrypoints.web.http.redirections.entrypoint.scheme=https + --entrypoints.websecure.address=:443/tcp + --entrypoints.websecure.http.tls=true + --entrypoints.websecure.http.tls.certResolver=letsencrypt + --entrypoints.websecure.http.tls.domains[0].main=sel2-1.ugent.be + --certificatesresolvers.letsencrypt.acme.email=timo.demeyst@ugent.be + --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json + --certificatesresolvers.letsencrypt.acme.httpChallenge=true + --certificatesresolvers.letsencrypt.acme.httpChallenge.entrypoint=web + ports: + - '8080:8080' + - '80:80/tcp' + - '443:443/tcp' + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - dwengo_letsencrypt:/letsencrypt:ro + networks: + - dwengo-1 + + logging: + image: grafana/loki:latest + ports: + - '3102:3102' + - '9095:9095' + volumes: + - ./config/loki/config.yml:/etc/loki/config.yaml + - dwengo_loki_data:/loki + command: -config.file=/etc/loki/config.yaml + restart: unless-stopped + networks: + - dwengo-1 + labels: + - "traefik.enable=true" + - "traefik.http.middlewares.logging-prefix.stripprefix.prefixes=/logging" + - "traefik.http.routers.web.rule=PathPrefix(`/logging`)" + - "traefik.http.routers.web.middlewares=logging-prefix" + - "traefik.http.services.web.loadbalancer.server.port=3102" + + dashboards: + image: grafana/grafana:latest + ports: + - '3100:3000' + volumes: + - dwengo_grafana_data:/var/lib/grafana + restart: unless-stopped + networks: + - dwengo-1 + +volumes: + dwengo_postgres_data: + dwengo_letsencrypt: + dwengo_loki_data: + dwengo_grafana_data: diff --git a/docker-compose.yml b/docker-compose.yml index d20d819d..06e882ca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,33 +2,69 @@ services: web: build: context: . - dockerfile: ./frontend.Dockerfile - depends_on: - - api + dockerfile: ./frontend/Dockerfile ports: - - '443:443' - - '80:80' - volumes: - - /etc/letsencrypt/:/etc/letsencrypt/:ro + - '8090:80/tcp' + restart: unless-stopped +# networks: +# - dwengo-1 + labels: + - "traefik.enable=true" + - "traefik.http.routers.web.rule=PathPrefix(`/`)" + - "traefik.http.services.web.loadbalancer.server.port=80" + api: build: context: . - dockerfile: ./backend.Dockerfile + dockerfile: ./backend/Dockerfile + ports: + - '3000:3000/tcp' + restart: unless-stopped + volumes: + - ./backend/.env:/app/.env +# networks: +# - dwengo-1 depends_on: - db - ports: - - '2002:2002' + - logging + labels: + - "traefik.enable=true" + - "traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api" + - "traefik.http.routers.api.rule=PathPrefix(`/api`)" + - "traefik.http.routers.api.middlewares=api-prefix" + - "traefik.http.services.api.loadbalancer.server.port=3000" + db: image: postgres:latest environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres - POSTGRES_INITDB_ARGS: -T ./config/postgresql/postgresql.conf ports: - '5431:5432' + restart: unless-stopped volumes: - dwengo_postgres_data:/var/lib/postgresql/data +# networks: +# - dwengo-1 + + reverse-proxy: + image: traefik:v3.3 + command: > + --api.insecure=true + --providers.docker=true + --providers.docker.exposedbydefault=false + --entrypoints.web.address=:80/tcp + ports: + - '8080:8080' + - '80:80/tcp' +# - '443:443/tcp' + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - dwengo_letsencrypt:/letsencrypt:ro +# networks: +# - dwengo-1 logging: image: grafana/loki:latest @@ -40,6 +76,8 @@ services: - dwengo_loki_data:/loki command: -config.file=/etc/loki/config.yaml restart: unless-stopped +# networks: +# - dwengo-1 dashboards: image: grafana/grafana:latest @@ -48,9 +86,11 @@ services: volumes: - dwengo_grafana_data:/var/lib/grafana restart: unless-stopped +# networks: +# - dwengo-1 volumes: dwengo_postgres_data: + dwengo_letsencrypt: dwengo_loki_data: dwengo_grafana_data: - ssl: diff --git a/frontend.Dockerfile b/frontend.Dockerfile deleted file mode 100644 index b5b765d2..00000000 --- a/frontend.Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# build stage -FROM node:22 AS build-stage -WORKDIR /app -COPY ./frontend/package*.json ./ -RUN npm install -COPY ./frontend ./frontend -COPY ./assets ./assets -WORKDIR /app/frontend -RUN npm run build - -# production stage -FROM nginx:stable AS production-stage -COPY ./nginx/nginx.conf /etc/nginx/ -COPY --from=build-stage /app/frontend/dist /usr/share/nginx/html -EXPOSE 80 -EXPOSE 443 -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 00000000..841f80db --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,35 @@ +FROM node:22 AS build-stage + +# install simple http server for serving static content +RUN npm install -g http-server + +WORKDIR /app + +# Install dependencies + +COPY package*.json ./ +COPY ./frontend/package.json ./frontend/ + +RUN npm install --silent + +# Build the frontend + +# Root tsconfig.json +COPY tsconfig.json ./ +COPY assets ./assets/ + +WORKDIR /app/frontend + +COPY frontend ./ + +RUN npm run build + +FROM nginx:stable AS production-stage + +COPY config/nginx/nginx.conf /etc/nginx/nginx.conf + +COPY --from=build-stage /app/frontend/dist /usr/share/nginx/html + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/nginx/nginx.conf b/nginx/nginx.conf deleted file mode 100644 index 0185fdbc..00000000 --- a/nginx/nginx.conf +++ /dev/null @@ -1,49 +0,0 @@ -worker_processes auto; - -events { - worker_connections 1024; -} - -http { - server { - server_name sel2-1.ugent.be; - - location / { - root /usr/share/nginx/html; - index index.html index.htm; - } - - location /api/ { - proxy_pass http://127.0.0.1:2002/; - } - - listen 443 default_server ssl; # managed by Certbot - ssl_certificate /etc/letsencrypt/live/sel2-1.ugent.be/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/sel2-1.ugent.be/privkey.pem; # managed by Certbot - include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot - -} - - server { - listen 2002; - server_name dwengo-api; - - location / { - root /usr/share/api; - } - - } - - server { - if ($host = sel2-1.ugent.be) { - return 301 https://$host$request_uri; - } # managed by Certbot - - - listen 80; - server_name sel2-1.ugent.be; - return 404; # managed by Certbot - - } -} \ No newline at end of file From f2bbb5ed1396d7a9fc506b63ff89d2d95ae50c09 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 11 Mar 2025 13:55:34 +0100 Subject: [PATCH 24/34] fix: Add network --- docker-compose.production.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.production.yml b/docker-compose.production.yml index 64117082..60d7425e 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -106,3 +106,6 @@ volumes: dwengo_letsencrypt: dwengo_loki_data: dwengo_grafana_data: + +networks: + dwengo-1: From 9dfa16f5f0b2095f6ed46373982a2b4085f55fbd Mon Sep 17 00:00:00 2001 From: Lint Action Date: Wed, 12 Mar 2025 17:46:11 +0000 Subject: [PATCH 25/34] style: fix linting issues met Prettier --- docker-compose.production.yml | 28 +++++++++++------------ docker-compose.yml | 42 +++++++++++++++++------------------ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docker-compose.production.yml b/docker-compose.production.yml index 60d7425e..7480746f 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -7,9 +7,9 @@ services: networks: - dwengo-1 labels: - - "traefik.enable=true" - - "traefik.http.routers.web.rule=PathPrefix(`/`)" - - "traefik.http.services.web.loadbalancer.server.port=80" + - 'traefik.enable=true' + - 'traefik.http.routers.web.rule=PathPrefix(`/`)' + - 'traefik.http.services.web.loadbalancer.server.port=80' api: build: @@ -25,12 +25,12 @@ services: - db - logging labels: - - "traefik.enable=true" - - "traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api" - - "traefik.http.routers.api.rule=Host(`sel2-1.ugent.be`)" - - "traefik.http.routers.api.rule=PathPrefix(`/api`)" - - "traefik.http.routers.api.middlewares=api-prefix" - - "traefik.http.services.api.loadbalancer.server.port=3000" + - 'traefik.enable=true' + - 'traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api' + - 'traefik.http.routers.api.rule=Host(`sel2-1.ugent.be`)' + - 'traefik.http.routers.api.rule=PathPrefix(`/api`)' + - 'traefik.http.routers.api.middlewares=api-prefix' + - 'traefik.http.services.api.loadbalancer.server.port=3000' db: image: postgres:latest @@ -85,11 +85,11 @@ services: networks: - dwengo-1 labels: - - "traefik.enable=true" - - "traefik.http.middlewares.logging-prefix.stripprefix.prefixes=/logging" - - "traefik.http.routers.web.rule=PathPrefix(`/logging`)" - - "traefik.http.routers.web.middlewares=logging-prefix" - - "traefik.http.services.web.loadbalancer.server.port=3102" + - 'traefik.enable=true' + - 'traefik.http.middlewares.logging-prefix.stripprefix.prefixes=/logging' + - 'traefik.http.routers.web.rule=PathPrefix(`/logging`)' + - 'traefik.http.routers.web.middlewares=logging-prefix' + - 'traefik.http.services.web.loadbalancer.server.port=3102' dashboards: image: grafana/grafana:latest diff --git a/docker-compose.yml b/docker-compose.yml index 11e3cb3b..8d3a0010 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,12 +6,12 @@ services: ports: - '8090:80/tcp' restart: unless-stopped -# networks: -# - dwengo-1 + # networks: + # - dwengo-1 labels: - - "traefik.enable=true" - - "traefik.http.routers.web.rule=PathPrefix(`/`)" - - "traefik.http.services.web.loadbalancer.server.port=80" + - 'traefik.enable=true' + - 'traefik.http.routers.web.rule=PathPrefix(`/`)' + - 'traefik.http.services.web.loadbalancer.server.port=80' api: build: @@ -22,17 +22,17 @@ services: restart: unless-stopped volumes: - ./backend/.env:/app/.env -# networks: -# - dwengo-1 + # networks: + # - dwengo-1 depends_on: - db - logging labels: - - "traefik.enable=true" - - "traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api" - - "traefik.http.routers.api.rule=PathPrefix(`/api`)" - - "traefik.http.routers.api.middlewares=api-prefix" - - "traefik.http.services.api.loadbalancer.server.port=3000" + - 'traefik.enable=true' + - 'traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api' + - 'traefik.http.routers.api.rule=PathPrefix(`/api`)' + - 'traefik.http.routers.api.middlewares=api-prefix' + - 'traefik.http.services.api.loadbalancer.server.port=3000' db: image: postgres:latest @@ -45,8 +45,8 @@ services: restart: unless-stopped volumes: - dwengo_postgres_data:/var/lib/postgresql/data -# networks: -# - dwengo-1 + # networks: + # - dwengo-1 reverse-proxy: image: traefik:v3.3 @@ -58,13 +58,13 @@ services: ports: - '8080:8080' - '80:80/tcp' -# - '443:443/tcp' + # - '443:443/tcp' restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - dwengo_letsencrypt:/letsencrypt:ro -# networks: -# - dwengo-1 + # networks: + # - dwengo-1 logging: image: grafana/loki:latest @@ -76,8 +76,8 @@ services: - dwengo_loki_data:/loki command: -config.file=/etc/loki/config.yaml restart: unless-stopped -# networks: -# - dwengo-1 + # networks: + # - dwengo-1 dashboards: image: grafana/grafana:latest @@ -86,8 +86,8 @@ services: volumes: - dwengo_grafana_data:/var/lib/grafana restart: unless-stopped -# networks: -# - dwengo-1 + # networks: + # - dwengo-1 idp: # Based on: https://medium.com/@fingervinicius/easy-running-keycloak-with-docker-compose-b0d7a4ee2358 image: quay.io/keycloak/keycloak:latest From 7b317b28d1179109c525687fff00f9f750b74bee Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 00:15:47 +0100 Subject: [PATCH 26/34] ci: Fix MIMETYPEs --- config/nginx/nginx.conf | 16 ++++++++++++++++ frontend/Dockerfile | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/config/nginx/nginx.conf b/config/nginx/nginx.conf index 650a09c9..7a3b995e 100644 --- a/config/nginx/nginx.conf +++ b/config/nginx/nginx.conf @@ -1,10 +1,19 @@ worker_processes auto; + events { worker_connections 1024; } http { + include mime.types; + default_type application/octet-stream; + + types { + application/javascript js mjs; + text/css css; + } + server { listen 80; @@ -12,5 +21,12 @@ http { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { + root /usr/share/nginx/html; + expires 1y; + add_header Cache-Control "public"; + try_files $uri =404; + } } } diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 841f80db..b7799a2d 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -22,12 +22,13 @@ WORKDIR /app/frontend COPY frontend ./ -RUN npm run build +RUN npx vite build FROM nginx:stable AS production-stage COPY config/nginx/nginx.conf /etc/nginx/nginx.conf +COPY --from=build-stage /app/assets /usr/share/nginx/html/assets COPY --from=build-stage /app/frontend/dist /usr/share/nginx/html EXPOSE 80 From 774adb6688da73d2ac15ae714884197e17f83d8d Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 01:21:38 +0100 Subject: [PATCH 27/34] fix: .js toevoegen aan imports --- backend/src/middleware/auth/auth.ts | 2 +- frontend/src/services/auth/auth-service.ts | 23 +++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/backend/src/middleware/auth/auth.ts b/backend/src/middleware/auth/auth.ts index ca64b3b3..5ff5a53c 100644 --- a/backend/src/middleware/auth/auth.ts +++ b/backend/src/middleware/auth/auth.ts @@ -6,7 +6,7 @@ import * as express from 'express'; import * as jwt from 'jsonwebtoken'; import { AuthenticatedRequest } from './authenticated-request.js'; import { AuthenticationInfo } from './authentication-info.js'; -import { ForbiddenException, UnauthorizedException } from '../../exceptions'; +import { ForbiddenException, UnauthorizedException } from '../../exceptions.js'; const JWKS_CACHE = true; const JWKS_RATE_LIMIT = true; diff --git a/frontend/src/services/auth/auth-service.ts b/frontend/src/services/auth/auth-service.ts index 61032170..53f8cb61 100644 --- a/frontend/src/services/auth/auth-service.ts +++ b/frontend/src/services/auth/auth-service.ts @@ -12,12 +12,13 @@ import apiClient from "@/services/api-client.ts"; import router from "@/router"; import type { AxiosError } from "axios"; -const authConfig = await loadAuthConfig(); - -const userManagers: UserManagersForRoles = { - student: new UserManager(authConfig.student), - teacher: new UserManager(authConfig.teacher), -}; +async function getUserManagers(): Promise { + const authConfig = await loadAuthConfig(); + return { + student: new UserManager(authConfig.student), + teacher: new UserManager(authConfig.teacher), + }; +} /** * Load the information about who is currently logged in from the IDP. @@ -27,7 +28,7 @@ async function loadUser(): Promise { if (!activeRole) { return null; } - const user = await userManagers[activeRole].getUser(); + const user = await (await getUserManagers())[activeRole].getUser(); authState.user = user; authState.accessToken = user?.access_token || null; authState.activeRole = activeRole || null; @@ -59,7 +60,7 @@ async function initiateLogin() { async function loginAs(role: Role): Promise { // Storing it in local storage so that it won't be lost when redirecting outside of the app. authStorage.setActiveRole(role); - await userManagers[role].signinRedirect(); + await (await getUserManagers())[role].signinRedirect(); } /** @@ -70,7 +71,7 @@ async function handleLoginCallback(): Promise { if (!activeRole) { throw new Error("Login callback received, but the user is not logging in!"); } - authState.user = (await userManagers[activeRole].signinCallback()) || null; + authState.user = (await (await getUserManagers())[activeRole].signinCallback()) || null; } /** @@ -84,7 +85,7 @@ async function renewToken() { return; } try { - return await userManagers[activeRole].signinSilent(); + return await (await getUserManagers())[activeRole].signinSilent(); } catch (error) { console.log("Can't renew the token:"); console.log(error); @@ -98,7 +99,7 @@ async function renewToken() { async function logout(): Promise { const activeRole = authStorage.getActiveRole(); if (activeRole) { - await userManagers[activeRole].signoutRedirect(); + await (await getUserManagers())[activeRole].signoutRedirect(); authStorage.deleteActiveRole(); } } From 6a6eed89786549ec98999bbb63c45d7bf74c0350 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 01:22:32 +0100 Subject: [PATCH 28/34] chore: Verplaats Keycloak naar config --- {idp => config/idp}/README.md | 0 {idp => config/idp}/student-realm.json | 2 +- {idp => config/idp}/teacher-realm.json | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename {idp => config/idp}/README.md (100%) rename {idp => config/idp}/student-realm.json (99%) rename {idp => config/idp}/teacher-realm.json (99%) diff --git a/idp/README.md b/config/idp/README.md similarity index 100% rename from idp/README.md rename to config/idp/README.md diff --git a/idp/student-realm.json b/config/idp/student-realm.json similarity index 99% rename from idp/student-realm.json rename to config/idp/student-realm.json index 697fda34..0c1d45f5 100644 --- a/idp/student-realm.json +++ b/config/idp/student-realm.json @@ -620,7 +620,7 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-jwt", - "redirectUris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost:5173/*", "http://localhost:5173"], + "redirectUris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost:5173/*", "http://localhost:5173", "http://localhost/*", "http://localhost", "https://sel2-1.ugent.be/*", "https://sel2-1.ugent.be"], "webOrigins": ["+"], "notBefore": 0, "bearerOnly": false, diff --git a/idp/teacher-realm.json b/config/idp/teacher-realm.json similarity index 99% rename from idp/teacher-realm.json rename to config/idp/teacher-realm.json index fd965e96..6bfd0c6b 100644 --- a/idp/teacher-realm.json +++ b/config/idp/teacher-realm.json @@ -620,7 +620,7 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost:5173/*", "http://localhost:5173"], + "redirectUris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost:5173/*", "http://localhost:5173", "http://localhost/*", "http://localhost", "https://sel2-1.ugent.be/*", "https://sel2-1.ugent.be"], "webOrigins": ["+"], "notBefore": 0, "bearerOnly": false, From fc5ba93ba09a9565a1482f70d553c49190d83996 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 14:27:12 +0100 Subject: [PATCH 29/34] fix: Voorbereiding production --- backend/.env.development.example | 16 ++++- backend/.env.example | 2 +- backend/.env.production | 7 -- backend/.env.production.example | 28 ++++++++ backend/src/app.ts | 26 +++---- compose.override.yml | 72 +++++++++++++++++++ compose.prod.yml | 110 ++++++++++++++++++++++++++++ compose.yml | 52 ++++++++++++++ config/nginx/nginx.conf | 2 +- docker-compose.production.yml | 111 ---------------------------- docker-compose.yml | 120 ------------------------------- frontend/Dockerfile | 2 +- frontend/src/config.ts | 2 +- 13 files changed, 293 insertions(+), 257 deletions(-) delete mode 100644 backend/.env.production create mode 100644 backend/.env.production.example create mode 100644 compose.override.yml create mode 100644 compose.prod.yml create mode 100644 compose.yml delete mode 100644 docker-compose.production.yml delete mode 100644 docker-compose.yml diff --git a/backend/.env.development.example b/backend/.env.development.example index 247ff054..c9f3cdbf 100644 --- a/backend/.env.development.example +++ b/backend/.env.development.example @@ -1,10 +1,16 @@ -DWENGO_PORT=3000 +# +# Basic configuration +# + +DWENGO_PORT=3000 # The port the backend will listen on DWENGO_DB_HOST=localhost -DWENGO_DB_PORT=5431 +DWENGO_DB_PORT=5432 DWENGO_DB_USERNAME=postgres DWENGO_DB_PASSWORD=postgres DWENGO_DB_UPDATE=true +# Auth + DWENGO_AUTH_STUDENT_URL=http://localhost:7080/realms/student DWENGO_AUTH_STUDENT_CLIENT_ID=dwengo DWENGO_AUTH_STUDENT_JWKS_ENDPOINT=http://localhost:7080/realms/student/protocol/openid-connect/certs @@ -14,3 +20,9 @@ DWENGO_AUTH_TEACHER_JWKS_ENDPOINT=http://localhost:7080/realms/teacher/protocol/ # Allow Vite dev-server to access the backend (for testing purposes). Don't forget to remove this in production! DWENGO_CORS_ALLOWED_ORIGINS=http://localhost:5173 + +# +# Advanced configuration +# + +# LOKI_HOST=http://localhost:9001 # The address of the Loki instance, used for logging diff --git a/backend/.env.example b/backend/.env.example index 105a1654..0a8f3994 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,4 +1,4 @@ -DWENGO_PORT=3000 # The port the backend will listen on +DWENGO_PORT=3000 # The port the backend will listen on DWENGO_DB_HOST=domain-or-ip-of-database DWENGO_DB_PORT=5432 diff --git a/backend/.env.production b/backend/.env.production deleted file mode 100644 index 8ee6113e..00000000 --- a/backend/.env.production +++ /dev/null @@ -1,7 +0,0 @@ -DWENGO_PORT=3000 -DWENGO_DB_HOST=localhost -DWENGO_DB_PORT=5432 -DWENGO_DB_NAME=postgres -DWENGO_DB_USERNAME=postgres -DWENGO_DB_PASSWORD=postgres -DWENGO_DB_UPDATE=true diff --git a/backend/.env.production.example b/backend/.env.production.example new file mode 100644 index 00000000..1adf7d95 --- /dev/null +++ b/backend/.env.production.example @@ -0,0 +1,28 @@ +DWENGO_PORT=3000 # The port the backend will listen on +DWENGO_DB_HOST=db # Name of the database container +DWENGO_DB_PORT=5432 + +# Change this to the actual credentials of the user Dwengo should use in the backend +DWENGO_DB_NAME=postgres +DWENGO_DB_USERNAME=postgres +DWENGO_DB_PASSWORD=postgres + +# Set this to true when the database scheme needs to be updated. In that case, take a backup first. +DWENGO_DB_UPDATE=false + +# Data for the identity provider via which the students authenticate. +DWENGO_AUTH_STUDENT_URL=https://sel2-1.ugent.be/idp/realms/student +DWENGO_AUTH_STUDENT_CLIENT_ID=dwengo +DWENGO_AUTH_STUDENT_JWKS_ENDPOINT=http://idp:7080/idp/realms/student/protocol/openid-connect/certs # Name of the idp container +# Data for the identity provider via which the teachers authenticate. +DWENGO_AUTH_TEACHER_URL=https://sel2-1.ugent.be/idp/realms/teacher +DWENGO_AUTH_TEACHER_CLIENT_ID=dwengo +DWENGO_AUTH_TEACHER_JWKS_ENDPOINT=http://idp:7080/idp/realms/teacher/protocol/openid-connect/certs # Name of the idp container + +# +# Advanced configuration +# + +# Logging and monitoring + +# LOKI_HOST=http://logging:3102 # The address of the Loki instance, used for logging diff --git a/backend/src/app.ts b/backend/src/app.ts index 61d173ec..55352220 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -30,29 +30,29 @@ app.use(responseTime(responseTimeLogger)); app.use(authenticateUser); // TODO Replace with Express routes -app.get('/', (_, res: Response) => { - logger.debug('GET /'); +app.get('/api/', (_, res: Response) => { + logger.debug('GET /api/'); res.json({ message: 'Hello Dwengo!🚀', }); }); -app.use('/student', studentRouter); -app.use('/group', groupRouter); -app.use('/assignment', assignmentRouter); -app.use('/submission', submissionRouter); -app.use('/class', classRouter); -app.use('/question', questionRouter); -app.use('/auth', authRouter); -app.use('/theme', themeRoutes); -app.use('/learningPath', learningPathRoutes); -app.use('/learningObject', learningObjectRoutes); +app.use('/api/student', studentRouter); +app.use('/api/group', groupRouter); +app.use('/api/assignment', assignmentRouter); +app.use('/api/submission', submissionRouter); +app.use('/api/class', classRouter); +app.use('/api/question', questionRouter); +app.use('/api/auth', authRouter); +app.use('/api/theme', themeRoutes); +app.use('/api/learningPath', learningPathRoutes); +app.use('/api/learningObject', learningObjectRoutes); async function startServer() { await initORM(); app.listen(port, () => { - logger.info(`Server is running at http://localhost:${port}`); + logger.info(`Server is running at http://localhost:${port}/api`); }); } diff --git a/compose.override.yml b/compose.override.yml new file mode 100644 index 00000000..5c35441e --- /dev/null +++ b/compose.override.yml @@ -0,0 +1,72 @@ +# +# Use this configuration to test the production configuration locally. +# +# This configuration builds the frontend and backend services as Docker images, +# and uses the paths for the services, instead of ports. +# +services: + web: + build: + context: . + dockerfile: frontend/Dockerfile + ports: + - '8080:8080/tcp' + restart: unless-stopped + labels: + - 'traefik.http.routers.web.rule=PathPrefix(`/`)' + - 'traefik.http.services.web.loadbalancer.server.port=8080' + + api: + build: + context: . + dockerfile: backend/Dockerfile + ports: + - '3000:3000/tcp' + restart: unless-stopped + volumes: + - ./backend/.env:/app/.env + depends_on: + - db + - logging + labels: + - 'traefik.http.routers.api.rule=PathPrefix(`/api`)' + - 'traefik.http.services.api.loadbalancer.server.port=3000' + + idp: + # Also see compose.yml + labels: + - 'traefik.http.routers.idp.rule=PathPrefix(`/idp`)' + - 'traefik.http.services.idp.loadbalancer.server.port=7080' + environment: + PROXY_ADDRESS_FORWARDING: 'true' + KC_HTTP_RELATIVE_PATH: '/idp' + + reverse-proxy: + image: traefik:v3.3 + command: + # Enable web UI + - '--api.insecure=true' + + # Add Docker provider + - '--providers.docker=true' + - '--providers.docker.exposedbydefault=true' + + # Add web entrypoint + - '--entrypoints.web.address=:80/tcp' + ports: + - '9000:8080' + - '80:80/tcp' + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + + dashboards: + image: grafana/grafana:latest + ports: + - '9002:3000' + volumes: + - dwengo_grafana_data:/var/lib/grafana + restart: unless-stopped + +volumes: + dwengo_grafana_data: diff --git a/compose.prod.yml b/compose.prod.yml new file mode 100644 index 00000000..2063323e --- /dev/null +++ b/compose.prod.yml @@ -0,0 +1,110 @@ +# +# This file is used to define the production environment for the project. +# It is used to deploy the project on a server. +# Should not be used for local development. +# +services: + web: + build: + context: . + dockerfile: frontend/Dockerfile + restart: unless-stopped + networks: + - dwengo-1 + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.web.rule=PathPrefix(`/`)' + - 'traefik.http.services.web.loadbalancer.server.port=80' + + api: + build: + context: . + dockerfile: backend/Dockerfile + restart: unless-stopped + volumes: + # TODO Replace with environment keys + - ./backend/.env:/app/.env + depends_on: + - db + - logging + networks: + - dwengo-1 + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.api.rule=PathPrefix(`/api`)' + - 'traefik.http.services.api.loadbalancer.server.port=3000' + + db: + # Also see compose.yml + networks: + - dwengo-1 + + idp: + # Also see compose.yml + # TODO Replace with proper production command + command: ['start-dev', '--http-port', '7080', '--https-port', '7443', '--import-realm'] + networks: + - dwengo-1 + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.idp.rule=PathPrefix(`/idp`)' + - 'traefik.http.services.idp.loadbalancer.server.port=7080' + env_file: + - ./config/idp/.env + environment: + KC_HOSTNAME: 'sel2-1.ugent.be' + PROXY_ADDRESS_FORWARDING: 'true' + KC_HTTP_RELATIVE_PATH: '/idp' + + reverse-proxy: + image: traefik:v3.3 + ports: + - '80:80/tcp' + - '443:443/tcp' + command: + # Add Docker provider + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + + # Add web entrypoint + - "--entrypoints.web.address=:80/tcp" + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + + # Add websecure entrypoint + - "--entrypoints.websecure.address=:443/tcp" + - "--entrypoints.websecure.http.tls=true" + - "--entrypoints.websecure.http.tls.certResolver=letsencrypt" + - "--entrypoints.websecure.http.tls.domains[0].main=sel2-1.ugent.be" + + # Certificates + - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" + - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" + - "--certificatesresolvers.letsencrypt.acme.email=timo.demeyst@ugent.be" + - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - dwengo_letsencrypt:/letsencrypt + networks: + - dwengo-1 + + logging: + # Also see compose.yml + networks: + - dwengo-1 + + dashboards: + image: grafana/grafana:latest + ports: + - '9002:3000' + restart: unless-stopped + volumes: + - dwengo_grafana_data:/var/lib/grafana + +volumes: + dwengo_grafana_data: + dwengo_letsencrypt: + +networks: + dwengo-1: diff --git a/compose.yml b/compose.yml new file mode 100644 index 00000000..2bb736bf --- /dev/null +++ b/compose.yml @@ -0,0 +1,52 @@ +# +# Use this configuration during development. +# +# This configuration is suitable to access the services using their ports. +# +services: + db: + image: postgres:latest + ports: + - '5432:5432' + restart: unless-stopped + volumes: + - dwengo_postgres_data:/var/lib/postgresql/data + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + + idp: # Based on: https://medium.com/@fingervinicius/easy-running-keycloak-with-docker-compose-b0d7a4ee2358 + image: quay.io/keycloak/keycloak:latest + ports: + - '7080:7080' + # - '7443:7443' + command: [ 'start-dev', '--http-port', '7080', '--https-port', '7443', '--import-realm' ] + restart: unless-stopped + volumes: + - ./config/idp:/opt/keycloak/data/import + depends_on: + - db + environment: + KC_HOSTNAME: localhost + KC_HOSTNAME_PORT: 7080 + KC_HOSTNAME_STRICT_BACKCHANNEL: 'true' + KC_BOOTSTRAP_ADMIN_USERNAME: admin + KC_BOOTSTRAP_ADMIN_PASSWORD: admin + KC_HEALTH_ENABLED: 'true' + KC_LOG_LEVEL: info + + logging: + image: grafana/loki:latest + ports: + - '9001:3102' + - '9095:9095' + command: -config.file=/etc/loki/config.yaml + restart: unless-stopped + volumes: + - ./config/loki/config.yml:/etc/loki/config.yaml + - dwengo_loki_data:/loki + +volumes: + dwengo_loki_data: + dwengo_postgres_data: diff --git a/config/nginx/nginx.conf b/config/nginx/nginx.conf index 7a3b995e..975b9580 100644 --- a/config/nginx/nginx.conf +++ b/config/nginx/nginx.conf @@ -15,7 +15,7 @@ http { } server { - listen 80; + listen 8080; location / { root /usr/share/nginx/html; diff --git a/docker-compose.production.yml b/docker-compose.production.yml deleted file mode 100644 index 7480746f..00000000 --- a/docker-compose.production.yml +++ /dev/null @@ -1,111 +0,0 @@ -services: - web: - build: - context: . - dockerfile: ./frontend/Dockerfile - restart: unless-stopped - networks: - - dwengo-1 - labels: - - 'traefik.enable=true' - - 'traefik.http.routers.web.rule=PathPrefix(`/`)' - - 'traefik.http.services.web.loadbalancer.server.port=80' - - api: - build: - context: . - dockerfile: ./backend/Dockerfile - restart: unless-stopped - volumes: - # TODO Replace with environment keys - - ./backend/.env:/app/.env - networks: - - dwengo-1 - depends_on: - - db - - logging - labels: - - 'traefik.enable=true' - - 'traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api' - - 'traefik.http.routers.api.rule=Host(`sel2-1.ugent.be`)' - - 'traefik.http.routers.api.rule=PathPrefix(`/api`)' - - 'traefik.http.routers.api.middlewares=api-prefix' - - 'traefik.http.services.api.loadbalancer.server.port=3000' - - db: - image: postgres:latest - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - restart: unless-stopped - volumes: - - dwengo_postgres_data:/var/lib/postgresql/data - networks: - - dwengo-1 - - reverse-proxy: - image: traefik:v3.3 - command: > - --api.insecure=true - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80/tcp - --entrypoints.web.http.redirections.entryPoint.to=websecure - --entrypoints.web.http.redirections.entrypoint.scheme=https - --entrypoints.websecure.address=:443/tcp - --entrypoints.websecure.http.tls=true - --entrypoints.websecure.http.tls.certResolver=letsencrypt - --entrypoints.websecure.http.tls.domains[0].main=sel2-1.ugent.be - --certificatesresolvers.letsencrypt.acme.email=timo.demeyst@ugent.be - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json - --certificatesresolvers.letsencrypt.acme.httpChallenge=true - --certificatesresolvers.letsencrypt.acme.httpChallenge.entrypoint=web - ports: - - '8080:8080' - - '80:80/tcp' - - '443:443/tcp' - restart: unless-stopped - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - dwengo_letsencrypt:/letsencrypt:ro - networks: - - dwengo-1 - - logging: - image: grafana/loki:latest - ports: - - '3102:3102' - - '9095:9095' - volumes: - - ./config/loki/config.yml:/etc/loki/config.yaml - - dwengo_loki_data:/loki - command: -config.file=/etc/loki/config.yaml - restart: unless-stopped - networks: - - dwengo-1 - labels: - - 'traefik.enable=true' - - 'traefik.http.middlewares.logging-prefix.stripprefix.prefixes=/logging' - - 'traefik.http.routers.web.rule=PathPrefix(`/logging`)' - - 'traefik.http.routers.web.middlewares=logging-prefix' - - 'traefik.http.services.web.loadbalancer.server.port=3102' - - dashboards: - image: grafana/grafana:latest - ports: - - '3100:3000' - volumes: - - dwengo_grafana_data:/var/lib/grafana - restart: unless-stopped - networks: - - dwengo-1 - -volumes: - dwengo_postgres_data: - dwengo_letsencrypt: - dwengo_loki_data: - dwengo_grafana_data: - -networks: - dwengo-1: diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 8d3a0010..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,120 +0,0 @@ -services: - web: - build: - context: . - dockerfile: ./frontend/Dockerfile - ports: - - '8090:80/tcp' - restart: unless-stopped - # networks: - # - dwengo-1 - labels: - - 'traefik.enable=true' - - 'traefik.http.routers.web.rule=PathPrefix(`/`)' - - 'traefik.http.services.web.loadbalancer.server.port=80' - - api: - build: - context: . - dockerfile: ./backend/Dockerfile - ports: - - '3000:3000/tcp' - restart: unless-stopped - volumes: - - ./backend/.env:/app/.env - # networks: - # - dwengo-1 - depends_on: - - db - - logging - labels: - - 'traefik.enable=true' - - 'traefik.http.middlewares.api-prefix.stripprefix.prefixes=/api' - - 'traefik.http.routers.api.rule=PathPrefix(`/api`)' - - 'traefik.http.routers.api.middlewares=api-prefix' - - 'traefik.http.services.api.loadbalancer.server.port=3000' - - db: - image: postgres:latest - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - ports: - - '5431:5432' - restart: unless-stopped - volumes: - - dwengo_postgres_data:/var/lib/postgresql/data - # networks: - # - dwengo-1 - - reverse-proxy: - image: traefik:v3.3 - command: > - --api.insecure=true - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80/tcp - ports: - - '8080:8080' - - '80:80/tcp' - # - '443:443/tcp' - restart: unless-stopped - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - dwengo_letsencrypt:/letsencrypt:ro - # networks: - # - dwengo-1 - - logging: - image: grafana/loki:latest - ports: - - '3102:3102' - - '9095:9095' - volumes: - - ./config/loki/config.yml:/etc/loki/config.yaml - - dwengo_loki_data:/loki - command: -config.file=/etc/loki/config.yaml - restart: unless-stopped - # networks: - # - dwengo-1 - - dashboards: - image: grafana/grafana:latest - ports: - - '3100:3000' - volumes: - - dwengo_grafana_data:/var/lib/grafana - restart: unless-stopped - # networks: - # - dwengo-1 - - idp: # Based on: https://medium.com/@fingervinicius/easy-running-keycloak-with-docker-compose-b0d7a4ee2358 - image: quay.io/keycloak/keycloak:latest - volumes: - - ./idp:/opt/keycloak/data/import - environment: - KC_HOSTNAME: localhost - KC_HOSTNAME_PORT: 7080 - KC_HOSTNAME_STRICT_BACKCHANNEL: 'true' - KC_BOOTSTRAP_ADMIN_USERNAME: admin - KC_BOOTSTRAP_ADMIN_PASSWORD: admin - KC_HEALTH_ENABLED: 'true' - KC_LOG_LEVEL: info - healthcheck: - test: ['CMD', 'curl', '-f', 'http://localhost:7080/health/ready'] - interval: 15s - timeout: 2s - retries: 15 - command: ['start-dev', '--http-port', '7080', '--https-port', '7443', '--import-realm'] - ports: - - '7080:7080' - - '7443:7443' - depends_on: - - db - -volumes: - dwengo_postgres_data: - dwengo_letsencrypt: - dwengo_loki_data: - dwengo_grafana_data: diff --git a/frontend/Dockerfile b/frontend/Dockerfile index b7799a2d..9cbb61ea 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -31,6 +31,6 @@ COPY config/nginx/nginx.conf /etc/nginx/nginx.conf COPY --from=build-stage /app/assets /usr/share/nginx/html/assets COPY --from=build-stage /app/frontend/dist /usr/share/nginx/html -EXPOSE 80 +EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/src/config.ts b/frontend/src/config.ts index 9feb71b3..3f303846 100644 --- a/frontend/src/config.ts +++ b/frontend/src/config.ts @@ -1,5 +1,5 @@ export const apiConfig = { - baseUrl: window.location.hostname == "localhost" ? "http://localhost:3000" : window.location.origin, + baseUrl: (window.location.hostname === "localhost" && !(window.location.port === '80' || window.location.port === '')) ? "http://localhost:3000/api" : window.location.origin + "/api", }; export const loginRoute = "/login"; From ff66dd64f0faec58b98677f1ca6736e77d34fbe4 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 19:22:29 +0100 Subject: [PATCH 30/34] chore: PostgreSQL op 5431 --- backend/.env.development.example | 2 +- backend/.env.example | 2 +- backend/.env.production.example | 2 +- compose.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/.env.development.example b/backend/.env.development.example index c9f3cdbf..466e1b7b 100644 --- a/backend/.env.development.example +++ b/backend/.env.development.example @@ -4,7 +4,7 @@ DWENGO_PORT=3000 # The port the backend will listen on DWENGO_DB_HOST=localhost -DWENGO_DB_PORT=5432 +DWENGO_DB_PORT=5431 DWENGO_DB_USERNAME=postgres DWENGO_DB_PASSWORD=postgres DWENGO_DB_UPDATE=true diff --git a/backend/.env.example b/backend/.env.example index 0a8f3994..bd13b54c 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,6 +1,6 @@ DWENGO_PORT=3000 # The port the backend will listen on DWENGO_DB_HOST=domain-or-ip-of-database -DWENGO_DB_PORT=5432 +DWENGO_DB_PORT=5431 # Change this to the actual credentials of the user Dwengo should use in the backend DWENGO_DB_USERNAME=postgres diff --git a/backend/.env.production.example b/backend/.env.production.example index 1adf7d95..390409d1 100644 --- a/backend/.env.production.example +++ b/backend/.env.production.example @@ -1,6 +1,6 @@ DWENGO_PORT=3000 # The port the backend will listen on DWENGO_DB_HOST=db # Name of the database container -DWENGO_DB_PORT=5432 +DWENGO_DB_PORT=5431 # Change this to the actual credentials of the user Dwengo should use in the backend DWENGO_DB_NAME=postgres diff --git a/compose.yml b/compose.yml index 2bb736bf..3c4bff9a 100644 --- a/compose.yml +++ b/compose.yml @@ -7,7 +7,7 @@ services: db: image: postgres:latest ports: - - '5432:5432' + - '5431:5432' restart: unless-stopped volumes: - dwengo_postgres_data:/var/lib/postgresql/data From 1be2e23b7fbfb5d1be7d28f3ee951c7cee993d8b Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 19:49:18 +0100 Subject: [PATCH 31/34] fix: frontend routeren --- compose.prod.yml | 2 +- config/nginx/nginx.conf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compose.prod.yml b/compose.prod.yml index 2063323e..075f75b9 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -14,7 +14,7 @@ services: labels: - 'traefik.enable=true' - 'traefik.http.routers.web.rule=PathPrefix(`/`)' - - 'traefik.http.services.web.loadbalancer.server.port=80' + - 'traefik.http.services.web.loadbalancer.server.port=8080' api: build: diff --git a/config/nginx/nginx.conf b/config/nginx/nginx.conf index 975b9580..dc9317f6 100644 --- a/config/nginx/nginx.conf +++ b/config/nginx/nginx.conf @@ -10,8 +10,8 @@ http { default_type application/octet-stream; types { - application/javascript js mjs; - text/css css; + application/javascript mjs; + text/css; } server { From a2be18d816e4d1f105d9d44a84faf630389d7d96 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 20:56:24 +0100 Subject: [PATCH 32/34] fix: IDP insecure cookies --- compose.prod.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compose.prod.yml b/compose.prod.yml index 075f75b9..9dd5b066 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -54,6 +54,8 @@ services: environment: KC_HOSTNAME: 'sel2-1.ugent.be' PROXY_ADDRESS_FORWARDING: 'true' + KC_PROXY_HEADERS: 'xforwarded' + KC_HTTP_ENABLED: 'true' KC_HTTP_RELATIVE_PATH: '/idp' reverse-proxy: From 4c5f6196f6becdac977c37cefd458730385ecc0b Mon Sep 17 00:00:00 2001 From: Lint Action Date: Thu, 13 Mar 2025 20:12:09 +0000 Subject: [PATCH 33/34] style: fix linting issues met Prettier --- compose.prod.yml | 28 ++++++++++++++-------------- compose.yml | 2 +- config/idp/student-realm.json | 10 +++++++++- config/idp/teacher-realm.json | 10 +++++++++- frontend/src/config.ts | 5 ++++- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/compose.prod.yml b/compose.prod.yml index 9dd5b066..8825796e 100644 --- a/compose.prod.yml +++ b/compose.prod.yml @@ -50,7 +50,7 @@ services: - 'traefik.http.routers.idp.rule=PathPrefix(`/idp`)' - 'traefik.http.services.idp.loadbalancer.server.port=7080' env_file: - - ./config/idp/.env + - ./config/idp/.env environment: KC_HOSTNAME: 'sel2-1.ugent.be' PROXY_ADDRESS_FORWARDING: 'true' @@ -65,25 +65,25 @@ services: - '443:443/tcp' command: # Add Docker provider - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" + - '--providers.docker=true' + - '--providers.docker.exposedbydefault=false' # Add web entrypoint - - "--entrypoints.web.address=:80/tcp" - - "--entrypoints.web.http.redirections.entryPoint.to=websecure" - - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + - '--entrypoints.web.address=:80/tcp' + - '--entrypoints.web.http.redirections.entryPoint.to=websecure' + - '--entrypoints.web.http.redirections.entryPoint.scheme=https' # Add websecure entrypoint - - "--entrypoints.websecure.address=:443/tcp" - - "--entrypoints.websecure.http.tls=true" - - "--entrypoints.websecure.http.tls.certResolver=letsencrypt" - - "--entrypoints.websecure.http.tls.domains[0].main=sel2-1.ugent.be" + - '--entrypoints.websecure.address=:443/tcp' + - '--entrypoints.websecure.http.tls=true' + - '--entrypoints.websecure.http.tls.certResolver=letsencrypt' + - '--entrypoints.websecure.http.tls.domains[0].main=sel2-1.ugent.be' # Certificates - - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" - - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - - "--certificatesresolvers.letsencrypt.acme.email=timo.demeyst@ugent.be" - - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" + - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true' + - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web' + - '--certificatesresolvers.letsencrypt.acme.email=timo.demeyst@ugent.be' + - '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json' restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock:ro diff --git a/compose.yml b/compose.yml index 3c4bff9a..1276c1af 100644 --- a/compose.yml +++ b/compose.yml @@ -21,7 +21,7 @@ services: ports: - '7080:7080' # - '7443:7443' - command: [ 'start-dev', '--http-port', '7080', '--https-port', '7443', '--import-realm' ] + command: ['start-dev', '--http-port', '7080', '--https-port', '7443', '--import-realm'] restart: unless-stopped volumes: - ./config/idp:/opt/keycloak/data/import diff --git a/config/idp/student-realm.json b/config/idp/student-realm.json index 0c1d45f5..32107e4e 100644 --- a/config/idp/student-realm.json +++ b/config/idp/student-realm.json @@ -620,7 +620,15 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-jwt", - "redirectUris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost:5173/*", "http://localhost:5173", "http://localhost/*", "http://localhost", "https://sel2-1.ugent.be/*", "https://sel2-1.ugent.be"], + "redirectUris": [ + "urn:ietf:wg:oauth:2.0:oob", + "http://localhost:5173/*", + "http://localhost:5173", + "http://localhost/*", + "http://localhost", + "https://sel2-1.ugent.be/*", + "https://sel2-1.ugent.be" + ], "webOrigins": ["+"], "notBefore": 0, "bearerOnly": false, diff --git a/config/idp/teacher-realm.json b/config/idp/teacher-realm.json index 6bfd0c6b..b9d29dcb 100644 --- a/config/idp/teacher-realm.json +++ b/config/idp/teacher-realm.json @@ -620,7 +620,15 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost:5173/*", "http://localhost:5173", "http://localhost/*", "http://localhost", "https://sel2-1.ugent.be/*", "https://sel2-1.ugent.be"], + "redirectUris": [ + "urn:ietf:wg:oauth:2.0:oob", + "http://localhost:5173/*", + "http://localhost:5173", + "http://localhost/*", + "http://localhost", + "https://sel2-1.ugent.be/*", + "https://sel2-1.ugent.be" + ], "webOrigins": ["+"], "notBefore": 0, "bearerOnly": false, diff --git a/frontend/src/config.ts b/frontend/src/config.ts index 3f303846..53d6f253 100644 --- a/frontend/src/config.ts +++ b/frontend/src/config.ts @@ -1,5 +1,8 @@ export const apiConfig = { - baseUrl: (window.location.hostname === "localhost" && !(window.location.port === '80' || window.location.port === '')) ? "http://localhost:3000/api" : window.location.origin + "/api", + baseUrl: + window.location.hostname === "localhost" && !(window.location.port === "80" || window.location.port === "") + ? "http://localhost:3000/api" + : window.location.origin + "/api", }; export const loginRoute = "/login"; From c9e95f4429796c17c55ce5b8cfaf8fd756739107 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 13 Mar 2025 21:22:05 +0100 Subject: [PATCH 34/34] refactor(backend): Gebruik /api router --- backend/src/app.ts | 33 +++------------------------------ backend/src/routes/router.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 30 deletions(-) create mode 100644 backend/src/routes/router.ts diff --git a/backend/src/app.ts b/backend/src/app.ts index 436af86f..cad68420 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -1,23 +1,13 @@ -import express, { Express, Response } from 'express'; +import express, { Express } from 'express'; import { initORM } from './orm.js'; -import themeRoutes from './routes/themes.js'; -import learningPathRoutes from './routes/learning-paths.js'; -import learningObjectRoutes from './routes/learning-objects.js'; - -import studentRouter from './routes/student.js'; -import groupRouter from './routes/group.js'; -import assignmentRouter from './routes/assignment.js'; -import submissionRouter from './routes/submission.js'; -import classRouter from './routes/class.js'; -import questionRouter from './routes/question.js'; -import authRouter from './routes/auth.js'; import { authenticateUser } from './middleware/auth/auth.js'; import cors from './middleware/cors.js'; import { getLogger, Logger } from './logging/initalize.js'; import { responseTimeLogger } from './logging/responseTimeLogger.js'; import responseTime from 'response-time'; import { EnvVars, getNumericEnvVar } from './util/envvars.js'; +import apiRouter from './routes/router.js'; const logger: Logger = getLogger(); @@ -29,24 +19,7 @@ app.use(express.json()); app.use(responseTime(responseTimeLogger)); app.use(authenticateUser); -// TODO Replace with Express routes -app.get('/api/', (_, res: Response) => { - logger.debug('GET /api/'); - res.json({ - message: 'Hello Dwengo!🚀', - }); -}); - -app.use('/api/student', studentRouter); -app.use('/api/group', groupRouter); -app.use('/api/assignment', assignmentRouter); -app.use('/api/submission', submissionRouter); -app.use('/api/class', classRouter); -app.use('/api/question', questionRouter); -app.use('/api/auth', authRouter); -app.use('/api/theme', themeRoutes); -app.use('/api/learningPath', learningPathRoutes); -app.use('/api/learningObject', learningObjectRoutes); +app.get('/api', apiRouter); async function startServer() { await initORM(); diff --git a/backend/src/routes/router.ts b/backend/src/routes/router.ts new file mode 100644 index 00000000..391f3ab5 --- /dev/null +++ b/backend/src/routes/router.ts @@ -0,0 +1,35 @@ +import { Response, Router } from 'express'; +import studentRouter from './student'; +import groupRouter from './group'; +import assignmentRouter from './assignment'; +import submissionRouter from './submission'; +import classRouter from './class'; +import questionRouter from './question'; +import authRouter from './auth'; +import themeRoutes from './themes'; +import learningPathRoutes from './learning-paths'; +import learningObjectRoutes from './learning-objects'; +import { getLogger, Logger } from '../logging/initalize'; + +const router = Router(); +const logger: Logger = getLogger(); + +router.get('/', (_, res: Response) => { + logger.debug('GET /'); + res.json({ + message: 'Hello Dwengo!🚀', + }); +}); + +router.use('/student', studentRouter); +router.use('/group', groupRouter); +router.use('/assignment', assignmentRouter); +router.use('/submission', submissionRouter); +router.use('/class', classRouter); +router.use('/question', questionRouter); +router.use('/auth', authRouter); +router.use('/theme', themeRoutes); +router.use('/learningPath', learningPathRoutes); +router.use('/learningObject', learningObjectRoutes); + +export default router;