Skip to content

Commit 4899dcf

Browse files
RI-5036: Ensure tls cert and key work from file path or as env variable
1 parent 2dee9a0 commit 4899dcf

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,15 @@ FROM node:18.18-alpine
4343

4444
# runtime args and environment variables
4545
ARG NODE_ENV=production
46+
ARG RI_HOSTNAME
47+
ARG RI_APP_PORT=5000
48+
ARG RI_SERVER_TLS
4649
ARG RI_SERVER_TLS_CERT
4750
ARG RI_SERVER_TLS_KEY
4851
ARG SEGMENT_WRITE_KEY
52+
ENV RI_HOSTNAME=${RI_HOSTNAME}
53+
ENV RI_APP_PORT=${RI_APP_PORT}
54+
ENV RI_SERVER_TLS=${RI_SERVER_TLS}
4955
ENV RI_SERVER_TLS_CERT=${RI_SERVER_TLS_CERT}
5056
ENV RI_SERVER_TLS_KEY=${RI_SERVER_TLS_KEY}
5157
ENV SEGMENT_WRITE_KEY=${SEGMENT_WRITE_KEY}

redisinsight/api/src/main.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { WindowsAuthAdapter } from 'src/modules/auth/window-auth/adapters/window
1414
import { AppModule } from './app.module';
1515
import SWAGGER_CONFIG from '../config/swagger';
1616
import LOGGER_CONFIG from '../config/logger';
17+
import { createHttpOptions } from './utils/createHttpOptions';
1718

1819
const serverConfig = get('server') as Config['server'];
1920

@@ -33,10 +34,7 @@ export default async function bootstrap(): Promise<IApp> {
3334
};
3435

3536
if (serverConfig.tls && serverConfig.tlsCert && serverConfig.tlsKey) {
36-
options.httpsOptions = {
37-
key: JSON.parse(`"${serverConfig.tlsKey}"`),
38-
cert: JSON.parse(`"${serverConfig.tlsCert}"`),
39-
};
37+
options.httpsOptions = await createHttpOptions(serverConfig);
4038
}
4139

4240
const app = await NestFactory.create<NestExpressApplication>(
@@ -70,7 +68,9 @@ export default async function bootstrap(): Promise<IApp> {
7068

7169
await app.listen(port, serverConfig.listenInterface);
7270
logger.log({
73-
message: `Server is running on http(s)://localhost:${port}`,
71+
message: `Server is running on http(s)://${
72+
serverConfig.listenInterface ?? 'localhost'
73+
}:${port}`,
7474
context: 'bootstrap',
7575
});
7676

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { readFile } from 'fs/promises';
2+
import { Config } from '.';
3+
4+
export const createHttpOptions = async (serverConfig: Config['server']) => {
5+
const { tlsKey, tlsCert } = serverConfig;
6+
7+
try {
8+
const [key, cert] = await Promise.all([
9+
readFile(tlsKey, { encoding: 'utf-8' }),
10+
readFile(tlsCert, { encoding: 'utf-8' }),
11+
]);
12+
return {
13+
key,
14+
cert,
15+
};
16+
} catch (e) {
17+
/* if this throws, it could mean
18+
1. the tlsKey and tlsCert provided by the config were actually certificates in PEM format, not file paths or
19+
2. there were issues reading the files (wrong path, permissions, etc.)
20+
21+
nothing to do in this case except assume PEM format and let the calling code throw if that doesn't work either */
22+
}
23+
24+
// for docker and perhaps other environments, multi-line env vars are problematic, so if there are escaped new-lines
25+
// in the key or cert, replace them with proper newlines
26+
const key = tlsKey.replace(/\\n/g, '\n');
27+
const cert = tlsCert.replace(/\\n/g, '\n');
28+
29+
return {
30+
key,
31+
cert,
32+
};
33+
};

0 commit comments

Comments
 (0)