Skip to content

Commit 8a649f4

Browse files
authored
Merge pull request #1059 from TMS-Uni-Stuttgart/puppeteer-to-gotenberg
Puppeteer to gotenberg
2 parents 559e269 + a156759 commit 8a649f4

13 files changed

Lines changed: 3032 additions & 3099 deletions

File tree

docker-compose.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,13 @@ services:
2525
networks:
2626
- tms_dev_db
2727

28+
gotenberg:
29+
container_name: gotenberg
30+
image: gotenberg/gotenberg:8
31+
ports:
32+
- '2000:3000'
33+
networks:
34+
- tms_dev_db
35+
2836
networks:
2937
tms_dev_db:

docs/docs/assets/dev/docker-compose.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,13 @@ services:
2222
networks:
2323
- tms_dev_db
2424

25+
gotenberg:
26+
container_name: gotenberg
27+
image: gotenberg/gotenberg:8
28+
ports:
29+
- '2000:3000'
30+
networks:
31+
- tms_dev_db
32+
2533
networks:
2634
tms_dev_db:

docs/docs/assets/docker-compose.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ services:
2727
image: ghcr.io/dudrie/tutor-management-system:<version>
2828
container_name: tms-server
2929
restart: on-failure:1
30-
cap_add:
31-
# This one is needed so puppeteer properly works inside the container (see: https://developers.google.com/web/tools/puppeteer/troubleshooting#tips)
32-
- SYS_ADMIN
3330
depends_on:
3431
- mysql
3532
networks:
@@ -43,6 +40,14 @@ services:
4340
# Replace with the path to the folder containing the configuration and template files of the TMS.
4441
- <path-to-CONFIG>:/tms/server/config
4542

43+
gotenberg:
44+
container_name: gotenberg
45+
image: gotenberg/gotenberg:8
46+
ports:
47+
- '2000:3000'
48+
networks:
49+
- tms_db
50+
4651
volumes:
4752
db_data:
4853

pnpm-lock.yaml

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

scripts/build-test-docker/docker-compose.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ services:
2828
volumes:
2929
- ./config:/tms/server/config
3030

31+
gotenberg:
32+
container_name: gotenberg
33+
image: gotenberg/gotenberg:8
34+
ports:
35+
- '2000:3000'
36+
networks:
37+
- tms_db
38+
3139
volumes:
3240
db_data:
3341

server/config/development.yml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ handbookUrl: 'https://dudrie.github.io/Tutor-Management-System/'
99

1010
# Configuration for the database access. More information can be found in the documentation.
1111
database:
12-
host: localhost
13-
port: 3306
14-
databaseName: tms-big-db
15-
maxRetries: 2
16-
reconnectTimeout: 10000
12+
host: localhost
13+
port: 3306
14+
databaseName: tms-big-db
15+
maxRetries: 2
16+
reconnectTimeout: 10000
1717

1818
defaultSettings:
19-
canTutorExcuseStudents: true
20-
defaultTeamSize: 3
19+
canTutorExcuseStudents: true
20+
defaultTeamSize: 3
2121

22-
# Settings used for the puppeteer instance
23-
puppeteer:
24-
# Timeout in ms
25-
timeout: 30000
22+
# Settings used for the gotenberg instance
23+
gotenberg:
24+
host: localhost
25+
port: 2000
26+
# Timeout in ms
27+
timeout: 30000

server/config/production.yml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ handbookUrl: 'https://dudrie.github.io/Tutor-Management-System/'
99

1010
# Configuration for the database access. More information can be found in the documentation.
1111
database:
12-
host: tms_sql
13-
port: 3306
14-
databaseName: tms-db
15-
maxRetries: 2
16-
reconnectTimeout: 10000
12+
host: tms_sql
13+
port: 3306
14+
databaseName: tms-db
15+
maxRetries: 2
16+
reconnectTimeout: 10000
1717

1818
defaultSettings:
19-
canTutorExcuseStudents: true
20-
defaultTeamSize: 3
19+
canTutorExcuseStudents: true
20+
defaultTeamSize: 3
2121

22-
# Settings used for the puppeteer instance
23-
puppeteer:
24-
# Timeout in ms
25-
timeout: 30000
22+
# Settings used for the gotenberg instance
23+
gotenberg:
24+
host: gotenberg
25+
port: 3000
26+
# Timeout in ms
27+
timeout: 30000

server/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@
3535
"@nestjs/passport": "^9.0.0",
3636
"@nestjs/platform-express": "^9.0.11",
3737
"@nestjs/swagger": "^6.1.0",
38+
"axios": "^1.7.7",
3839
"bcryptjs": "^2.4.3",
3940
"body-parser": "^1.20.0",
4041
"class-validator": "^0.13.2",
4142
"excel4node": "^1.8.0",
4243
"express-session": "^1.17.3",
44+
"form-data": "^4.0.1",
4345
"highlight.js": "^10.7.2",
4446
"jszip": "^3.10.1",
4547
"luxon": "^1.25.0",
@@ -48,7 +50,6 @@
4850
"passport": "^0.6.0",
4951
"passport-local": "^1.0.0",
5052
"pug": "^3.0.2",
51-
"puppeteer": "5.5.0",
5253
"reflect-metadata": "^0.1.13",
5354
"rimraf": "^3.0.2",
5455
"rxjs": "^7.5.6",
@@ -73,7 +74,6 @@
7374
"@types/passport": "^1.0.10",
7475
"@types/passport-local": "^1.0.34",
7576
"@types/pug": "^2.0.6",
76-
"@types/puppeteer": "5.4.2",
7777
"@types/supertest": "^2.0.12",
7878
"@types/uuid": "^8.3.4",
7979
"jest": "^29.0.0",

server/src/module/pdf/subservices/PDFGenerator.core.ts

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// noinspection HtmlRequiredLangAttribute,HtmlRequiredTitleElement
22

33
import { Logger } from '@nestjs/common';
4+
import axios from 'axios';
5+
import FormData from 'form-data';
46
import fs from 'fs';
5-
import puppeteer from 'puppeteer';
6-
import { StaticSettings } from '../../settings/settings.static';
7+
import { StaticSettings } from 'module/settings/settings.static';
78

89
/**
910
* @param T Type of the options passed to `generatePDF`.
@@ -29,52 +30,31 @@ export abstract class PDFGenerator<T = Record<string, unknown>> {
2930
*/
3031
protected async generatePDFFromBodyContent(body: string): Promise<Buffer> {
3132
const html = await this.putBodyInHTML(body);
32-
let browser: puppeteer.Browser | undefined;
33-
34-
this.logger.debug('Starting browser...');
35-
this.logger.debug(`\tExec path: ${process.env.TMS_PUPPETEER_EXEC_PATH}`);
33+
const gotenbergConfig = StaticSettings.getService().getGotenbergConfiguration();
3634

3735
try {
38-
browser = await puppeteer.launch({
39-
args: ['--disable-dev-shm-usage'],
40-
executablePath: process.env.TMS_PUPPETEER_EXEC_PATH,
41-
timeout: StaticSettings.getService().getPuppeteerConfiguration()?.timeout,
42-
});
43-
44-
this.logger.debug('Browser started.');
45-
46-
const page = await browser.newPage();
47-
this.logger.debug('Page created.');
48-
49-
await page.setContent(html, { waitUntil: 'domcontentloaded' });
50-
this.logger.debug('Page content loaded');
51-
52-
const buffer = await page.pdf({
53-
format: 'A4',
54-
margin: {
55-
top: '1cm',
56-
right: '1cm',
57-
bottom: '1cm',
58-
left: '1cm',
59-
},
60-
// Fixes CSS 'background' not being respected in printed PDFs.
61-
printBackground: true,
62-
});
63-
64-
this.logger.debug('PDF created.');
65-
66-
await browser.close();
67-
68-
this.logger.debug('Browser closed');
69-
70-
return buffer;
36+
const form = new FormData();
37+
form.append('files', html, { filename: 'index.html', contentType: 'text/html' });
38+
39+
this.logger.debug('Sending request to Gotenberg for PDF generation...');
40+
41+
const response = await axios.post(
42+
`http://${gotenbergConfig?.host}:${gotenbergConfig?.port}/forms/chromium/convert/html`,
43+
form,
44+
{
45+
headers: {
46+
...form.getHeaders(),
47+
},
48+
timeout: gotenbergConfig?.timeout,
49+
responseType: 'arraybuffer',
50+
}
51+
);
52+
53+
this.logger.debug('PDF generated successfully from Gotenberg.');
54+
55+
return Buffer.from(response.data);
7156
} catch (err) {
72-
if (browser) {
73-
await browser.close();
74-
}
75-
76-
Logger.error(JSON.stringify(err, null, 2));
77-
57+
this.logger.error('Failed to generate PDF:', err);
7858
throw err;
7959
}
8060
}

server/src/module/settings/model/ApplicationConfiguration.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Type } from 'class-transformer';
22
import { IsNumber, IsOptional, IsString, IsUrl, Min, ValidateNested } from 'class-validator';
33
import { ClientSettingsDTO } from '../settings.dto';
44
import { DatabaseConfiguration } from './DatabaseConfiguration';
5-
import { PuppeteerConfiguration } from './PuppeteerConfiguration';
5+
import { GotenbergConfiguration } from './GotenbergConfiguration';
66

77
export class ApplicationConfiguration {
88
@IsOptional()
@@ -28,7 +28,7 @@ export class ApplicationConfiguration {
2828
readonly defaultSettings: ClientSettingsDTO | undefined;
2929

3030
@IsOptional()
31-
@Type(() => PuppeteerConfiguration)
31+
@Type(() => GotenbergConfiguration)
3232
@ValidateNested()
33-
readonly puppeteer: PuppeteerConfiguration | undefined;
33+
readonly gotenberg: GotenbergConfiguration | undefined;
3434
}

0 commit comments

Comments
 (0)