Skip to content

Commit 4797345

Browse files
committed
Add support for HTTPS and graceful shutdown handling
1 parent 0c76001 commit 4797345

File tree

5 files changed

+54
-6
lines changed

5 files changed

+54
-6
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,6 @@ RUN yarn install \
7777
COPY --from=builder /data/dist ./dist
7878

7979
EXPOSE 4000
80+
EXPOSE 4443
8081

8182
CMD ["yarn", "run", "start:prod"]

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
APP_PORT = 4002
2+
APP_PORT_SECURE = 4443
23
IMG_NAME = "ghcr.io/libertech-fr/sesame-orchestrator"
34
BASE_NAME = "sesame"
45
APP_NAME = "sesame-orchestrator"
@@ -30,6 +31,7 @@ prod: ## Start production environment
3031
--network dev \
3132
--name $(APP_NAME) \
3233
-p $(APP_PORT):4000 \
34+
-p $(APP_PORT_SECURE):4443 \
3335
-p 9229:9229 \
3436
-v $(CURDIR):/data \
3537
$(IMG_NAME) yarn start:prod
@@ -43,6 +45,7 @@ dev: ## Start development environment
4345
--network dev \
4446
--name $(APP_NAME) \
4547
-p $(APP_PORT):4000 \
48+
-p $(APP_PORT_SECURE):4443 \
4649
-p 9229:9229 \
4750
-v $(CURDIR):/data \
4851
$(IMG_NAME) yarn start:dev
@@ -56,6 +59,7 @@ debug: ## Start debug environment
5659
--network dev \
5760
--name $(APP_NAME) \
5861
-p $(APP_PORT):4000 \
62+
-p $(APP_PORT_SECURE):4443 \
5963
-p 9229:9229 \
6064
-v $(CURDIR):/data \
6165
$(IMG_NAME) yarn start:debug
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Injectable, OnApplicationShutdown } from "@nestjs/common";
2+
import * as http from 'http';
3+
4+
@Injectable()
5+
export class ShutdownObserver implements OnApplicationShutdown {
6+
private httpServers: http.Server[] = [];
7+
8+
public addHttpServer(server: http.Server): void {
9+
this.httpServers.push(server);
10+
}
11+
12+
public async onApplicationShutdown(): Promise<void> {
13+
await Promise.all(
14+
this.httpServers.map(
15+
(server) =>
16+
new Promise((resolve, reject) => {
17+
server.close((error) => {
18+
if (error) {
19+
reject(error);
20+
} else {
21+
resolve(null);
22+
}
23+
});
24+
}),
25+
),
26+
);
27+
}
28+
}

src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { MailadmService } from '~/settings/mailadm.service';
2222
import { FactorydriveModule } from '@the-software-compagny/nestjs_module_factorydrive';
2323
import { MigrationsService } from './migrations/migrations.service';
2424
import { MigrationsModule } from './migrations/migrations.module';
25+
import { ShutdownObserver } from './_common/observers/shutdown.observer';
2526

2627
@Module({
2728
imports: [
@@ -119,6 +120,7 @@ import { MigrationsModule } from './migrations/migrations.module';
119120
controllers: [AppController],
120121
providers: [
121122
AppService,
123+
ShutdownObserver,
122124
{
123125
provide: APP_GUARD,
124126
useClass: AuthGuard('jwt'),

src/main.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { NestFactory } from '@nestjs/core';
2-
import { NestExpressApplication } from '@nestjs/platform-express';
2+
import { ExpressAdapter, NestExpressApplication } from '@nestjs/platform-express';
33
import cookieParser from 'cookie-parser';
4-
import { Response } from 'express';
4+
import express, { Response } from 'express';
55
import passport from 'passport';
66
import { rawBodyBuffer } from '~/_common/middlewares/raw-body-buffer.middleware';
77
import { getLogLevel } from './_common/functions/get-log-level';
88
import { AppModule } from './app.module';
99
import configInstance from './config';
1010
import { InternalLogger } from './core/logger/internal.logger';
1111
import { readFileSync } from 'fs';
12+
import * as http from 'http';
13+
import * as https from 'https';
14+
import { ShutdownObserver } from './_common/observers/shutdown.observer';
1215

1316
declare const module: any;
1417
(async (): Promise<void> => {
@@ -34,7 +37,8 @@ declare const module: any;
3437
}
3538
}
3639

37-
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
40+
const server = express();
41+
const app = await NestFactory.create<NestExpressApplication>(AppModule, new ExpressAdapter(server), {
3842
bodyParser: false,
3943
rawBody: true,
4044
cors: true,
@@ -52,9 +56,18 @@ declare const module: any;
5256
await (await import('./swagger')).default(app);
5357
}
5458

55-
await app.listen(4000, async (): Promise<void> => {
56-
logger.log(`Sesame - Orchestrator is READY on <http://127.0.0.1:4000> !`);
57-
});
59+
await app.init();
60+
61+
const shutdownObserver = app.get(ShutdownObserver);
62+
const httpServer = http.createServer(server).listen(4000);
63+
shutdownObserver.addHttpServer(httpServer);
64+
logger.log(`Sesame - Orchestrator is READY on <http://127.0.0.1:4000> !`);
65+
66+
if (cfg.application?.https?.enabled) {
67+
const httpsServer = https.createServer(extraOptions.httpsOptions!, server).listen(4443);
68+
shutdownObserver.addHttpServer(httpsServer);
69+
logger.log(`Sesame - Orchestrator is READY on <https://127.0.0.1:4443> !`);
70+
}
5871

5972
if (module.hot) {
6073
module.hot.accept();

0 commit comments

Comments
 (0)