Skip to content

Commit 3e8ec13

Browse files
committed
adds traefik compression to all services
1 parent 57055c1 commit 3e8ec13

5 files changed

Lines changed: 103 additions & 74 deletions

File tree

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "monux-cli",
3-
"version": "2.1.0",
3+
"version": "2.1.1",
44
"license": "MIT",
55
"main": "index.js",
66
"engines": {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { DockerComposeFileName } from '../constants';
2+
import { DefaultEnvKeys } from '../env';
3+
import { toSnakeCase } from '../utilities';
4+
5+
/**
6+
* Encapsulates functionality for getting docker traefik labels.
7+
*/
8+
export abstract class DockerTraefikUtilities {
9+
10+
/**
11+
* Gets the traefik labels for the project with the given name.
12+
* @param projectName - The name of the project to get the labels for.
13+
* @param port - The port where the service runs in development.
14+
* @param composeFileName - The name of the compose file to get the traefik labels for.
15+
* @param subDomain - The sub domain of the service.
16+
* @returns The traefik docker labels for the service as an array of string.
17+
* @throws When the sub domain provided is www, as this is reserved.
18+
*/
19+
static getTraefikLabels(
20+
projectName: string,
21+
port: number,
22+
composeFileName: DockerComposeFileName,
23+
subDomain: string | undefined
24+
): string[] {
25+
if (subDomain === 'www') {
26+
throw new Error('The subdomain "www" is reserved and will be set automatically.');
27+
}
28+
29+
switch (composeFileName) {
30+
case 'dev.docker-compose.yaml': {
31+
return [];
32+
}
33+
case 'local.docker-compose.yaml': {
34+
return this.getTraefikLabelsForLocal(projectName, subDomain, port);
35+
}
36+
case 'docker-compose.yaml': {
37+
return this.getTraefikLabelsForProd(projectName, subDomain, port);
38+
}
39+
}
40+
}
41+
42+
private static getTraefikLabelsForProd(projectName: string, subDomain: string | undefined, port: number): string[] {
43+
let host: string = `Host(\`\${${DefaultEnvKeys.subDomain(projectName)}}.\${${DefaultEnvKeys.PROD_ROOT_DOMAIN}}\`)`;
44+
const labels: string[] = [];
45+
const middlewares: string[] = ['compression'];
46+
if (!subDomain) {
47+
host = `Host(\`\${${DefaultEnvKeys.PROD_ROOT_DOMAIN}}\`) || Host(\`www.\${${DefaultEnvKeys.PROD_ROOT_DOMAIN}}\`)`;
48+
labels.push(
49+
'traefik.http.middlewares.wwwredirect.redirectregex.regex=^https://www\.(.*)',
50+
'traefik.http.middlewares.wwwredirect.redirectregex.replacement=https://$${1}'
51+
);
52+
middlewares.push('wwwredirect');
53+
}
54+
labels.push(
55+
'traefik.enable=true',
56+
`traefik.http.routers.${toSnakeCase(projectName)}.rule=${host}`,
57+
`traefik.http.routers.${toSnakeCase(projectName)}.entrypoints=web_secure`,
58+
`traefik.http.routers.${toSnakeCase(projectName)}.tls.certresolver=ssl_resolver`,
59+
`traefik.http.services.${toSnakeCase(projectName)}.loadbalancer.server.port=${port}`,
60+
'traefik.http.middlewares.compression.compress=true'
61+
);
62+
labels.push(`traefik.http.routers.${toSnakeCase(projectName)}.middlewares=${middlewares.join(',')}`);
63+
return labels;
64+
}
65+
66+
private static getTraefikLabelsForLocal(projectName: string, subDomain: string | undefined, port: number): string[] {
67+
let host: string = `Host(\`\${${DefaultEnvKeys.subDomain(projectName)}}.localhost\`)`;
68+
const labels: string[] = [];
69+
const middlewares: string[] = ['compression'];
70+
if (!subDomain) {
71+
host = 'Host(`localhost`) || Host(`www.localhost`)';
72+
labels.push(
73+
'traefik.http.middlewares.wwwredirect.redirectregex.regex=^http://www\.(.*)',
74+
'traefik.http.middlewares.wwwredirect.redirectregex.replacement=http://$${1}'
75+
);
76+
middlewares.push('wwwredirect');
77+
}
78+
labels.push(
79+
'traefik.enable=true',
80+
`traefik.http.routers.${toSnakeCase(projectName)}.rule=${host}`,
81+
`traefik.http.routers.${toSnakeCase(projectName)}.entrypoints=web`,
82+
`traefik.http.services.${toSnakeCase(projectName)}.loadbalancer.server.port=${port}`,
83+
'traefik.http.middlewares.compression.compress=true'
84+
);
85+
labels.push(`traefik.http.routers.${toSnakeCase(projectName)}.middlewares=${middlewares.join(',')}`);
86+
return labels;
87+
}
88+
}

src/docker/docker-utilities.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ describe('DockerUtilities', () => {
5858
`traefik.http.routers.${def.name}.rule=Host(\`\${${def.name}_sub_domain}.\${prod_root_domain}\`)`,
5959
`traefik.http.routers.${def.name}.entrypoints=web_secure`,
6060
`traefik.http.routers.${def.name}.tls.certresolver=ssl_resolver`,
61-
`traefik.http.services.${def.name}.loadbalancer.server.port=4200`
61+
`traefik.http.services.${def.name}.loadbalancer.server.port=4200`,
62+
'traefik.http.middlewares.compression.compress=true',
63+
`traefik.http.routers.${def.name}.middlewares=compression`
6264
]
6365
}).toEqual(service);
6466

@@ -71,7 +73,9 @@ describe('DockerUtilities', () => {
7173
'traefik.enable=true',
7274
`traefik.http.routers.${def.name}.rule=Host(\`\${${def.name}_sub_domain}.localhost\`)`,
7375
`traefik.http.routers.${def.name}.entrypoints=web`,
74-
`traefik.http.services.${def.name}.loadbalancer.server.port=4200`
76+
`traefik.http.services.${def.name}.loadbalancer.server.port=4200`,
77+
'traefik.http.middlewares.compression.compress=true',
78+
`traefik.http.routers.${def.name}.middlewares=compression`
7579
]
7680
}).toEqual(localService);
7781
});

src/docker/docker.utilities.ts

Lines changed: 6 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { FsUtilities } from '../encapsulation';
55
import { ComposeBuild, ComposeDefinition, ComposePort, ComposeService, ComposeServiceEnvironment, ComposeServiceVolume } from './compose-file.model';
66
import { DefaultEnvKeys, EnvUtilities } from '../env';
77
import { OmitStrict } from '../types';
8-
import { getPath, toSnakeCase } from '../utilities';
8+
import { getPath } from '../utilities';
9+
import { DockerTraefikUtilities } from './docker-traefik.utilities';
910

1011
// eslint-disable-next-line jsdoc/require-jsdoc
1112
type ParsedDockerComposeEnvironment = { [key: string]: string } | string[];
@@ -48,73 +49,6 @@ type ParsedDockerCompose = {
4849
*/
4950
export abstract class DockerUtilities {
5051

51-
private static getTraefikLabels(
52-
projectName: string,
53-
port: number,
54-
composeFileName: DockerComposeFileName,
55-
subDomain: string | undefined
56-
): string[] {
57-
if (subDomain === 'www') {
58-
throw new Error('The subdomain "www" is reserved and will be set automatically.');
59-
}
60-
61-
switch (composeFileName) {
62-
// eslint-disable-next-line sonar/no-duplicate-string
63-
case 'dev.docker-compose.yaml': {
64-
return [];
65-
}
66-
// eslint-disable-next-line sonar/no-duplicate-string
67-
case 'local.docker-compose.yaml': {
68-
return this.getTraefikLabelsForLocal(projectName, subDomain, port);
69-
}
70-
// eslint-disable-next-line sonar/no-duplicate-string
71-
case 'docker-compose.yaml': {
72-
return this.getTraefikLabelsForProd(projectName, subDomain, port);
73-
}
74-
}
75-
}
76-
77-
private static getTraefikLabelsForProd(projectName: string, subDomain: string | undefined, port: number): string[] {
78-
let host: string = `Host(\`\${${DefaultEnvKeys.subDomain(projectName)}}.\${${DefaultEnvKeys.PROD_ROOT_DOMAIN}}\`)`;
79-
const labels: string[] = [];
80-
if (!subDomain) {
81-
host = `Host(\`\${${DefaultEnvKeys.PROD_ROOT_DOMAIN}}\`) || Host(\`www.\${${DefaultEnvKeys.PROD_ROOT_DOMAIN}}\`)`;
82-
labels.push(
83-
'traefik.http.middlewares.wwwredirect.redirectregex.regex=^https://www\.(.*)',
84-
'traefik.http.middlewares.wwwredirect.redirectregex.replacement=https://$${1}',
85-
`traefik.http.routers.${toSnakeCase(projectName)}.middlewares=wwwredirect`
86-
);
87-
}
88-
labels.push(
89-
'traefik.enable=true',
90-
`traefik.http.routers.${toSnakeCase(projectName)}.rule=${host}`,
91-
`traefik.http.routers.${toSnakeCase(projectName)}.entrypoints=web_secure`,
92-
`traefik.http.routers.${toSnakeCase(projectName)}.tls.certresolver=ssl_resolver`,
93-
`traefik.http.services.${toSnakeCase(projectName)}.loadbalancer.server.port=${port}`
94-
);
95-
return labels;
96-
}
97-
98-
private static getTraefikLabelsForLocal(projectName: string, subDomain: string | undefined, port: number): string[] {
99-
let host: string = `Host(\`\${${DefaultEnvKeys.subDomain(projectName)}}.localhost\`)`;
100-
const labels: string[] = [];
101-
if (!subDomain) {
102-
host = 'Host(`localhost`) || Host(`www.localhost`)';
103-
labels.push(
104-
'traefik.http.middlewares.wwwredirect.redirectregex.regex=^http://www\.(.*)',
105-
'traefik.http.middlewares.wwwredirect.redirectregex.replacement=http://$${1}',
106-
`traefik.http.routers.${toSnakeCase(projectName)}.middlewares=wwwredirect`
107-
);
108-
}
109-
labels.push(
110-
'traefik.enable=true',
111-
`traefik.http.routers.${toSnakeCase(projectName)}.rule=${host}`,
112-
`traefik.http.routers.${toSnakeCase(projectName)}.entrypoints=web`,
113-
`traefik.http.services.${toSnakeCase(projectName)}.loadbalancer.server.port=${port}`
114-
);
115-
return labels;
116-
}
117-
11852
/**
11953
* Creates the initial docker compose files at the given path.
12054
* @param email - The email that should be used for the letsencrypt certificate.
@@ -257,7 +191,7 @@ export abstract class DockerUtilities {
257191
const composePath: string = getPath(composeFileName);
258192
const definition: ComposeDefinition = await this.yamlToComposeDefinition(composePath);
259193

260-
const labels: string[] = addTraefik ? this.getTraefikLabels(service.name, port, composeFileName, subDomain) : [];
194+
const labels: string[] = addTraefik ? DockerTraefikUtilities.getTraefikLabels(service.name, port, composeFileName, subDomain) : [];
261195

262196
definition.services.push({ ...service, labels: [...service.labels ?? [], ...labels] });
263197
await FsUtilities.updateFile(composePath, this.composeDefinitionToYaml(definition), 'replace');
@@ -281,12 +215,15 @@ export abstract class DockerUtilities {
281215
key: DefaultEnvKeys.baseUrl(service.name),
282216
value: (env, fileName) => {
283217
switch (fileName) {
218+
// eslint-disable-next-line sonar/no-duplicate-string
284219
case 'dev.docker-compose.yaml': {
285220
return `http://localhost:${'PORT_PLACEHOLDER'}`;
286221
}
222+
// eslint-disable-next-line sonar/no-duplicate-string
287223
case 'local.docker-compose.yaml': {
288224
return `http://${'SUB_DOMAIN_PLACEHOLDER'}.localhost`;
289225
}
226+
// eslint-disable-next-line sonar/no-duplicate-string
290227
case 'docker-compose.yaml': {
291228
return `https://${'SUB_DOMAIN_PLACEHOLDER'}.${'PROD_ROOT_DOMAIN_PLACEHOLDER'}`;
292229
}

0 commit comments

Comments
 (0)