Files
openstapps/backend/proxy/src/app.ts
2023-05-31 14:04:05 +02:00

84 lines
2.9 KiB
TypeScript

/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Logger} from '@openstapps/logger';
import {execSync} from 'child_process';
import * as Dockerode from 'dockerode';
import mustache from 'mustache';
import {asyncReadFile, asyncWriteFile} from './common.js';
import {getContainers, getTemplateView} from './main.js';
/* eslint-disable unicorn/prefer-module */
// handle unhandled promise rejections
process.on('unhandledRejection', async error => {
await Logger.error(error);
process.exit(1);
});
let containerHashCache = '';
let configHashCache = '';
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
/**
* Reads the container information from the docker socket and updates the nginx config if necessary
*/
async function updateNginxConfig() {
const containers = await getContainers();
const containerHash = containers
.map((container: Dockerode.ContainerInfo) => {
return container.Id;
})
.join(',');
delete require.cache[require.resolve('config')];
// eslint-disable-next-line @typescript-eslint/no-var-requires
const configFile = require('config');
const configHash = JSON.stringify(configFile);
// if containers changed -> write config file, reload nginx
if (containerHash !== containerHashCache || configHash !== configHashCache) {
Logger.log('Generating new NGINX configuration');
Logger.log('Waiting for Docker network to settle...');
await delay(10_000);
// render nginx config file
const nginxConfig = mustache.render(
await asyncReadFile('nginx.conf.template', 'utf8'),
await getTemplateView(containers),
);
containerHashCache = containerHash;
configHashCache = configHash;
Logger.log(`Writing new config file "${configFile.output}"`);
// overwrite nginx config file with our rendered one
await asyncWriteFile(configFile.output, nginxConfig, 'utf8');
Logger.log('Executing "nginx -s reload" to tell nginx to reload the configuration file');
execSync('nginx -s reload');
}
// set timeout to update configuration again in 30s
setTimeout(updateNginxConfig, 30_000);
}
// start the process that checks the docker socket periodically
// eslint-disable-next-line unicorn/prefer-top-level-await
updateNginxConfig();