Created
October 14, 2019 21:00
-
-
Save Makeshift/b1fa5dd5095e7a1c12aa58290ed23831 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const config = { | |
docker: process.env["docker_conf"] ? JSON.parse(process.env["docker_conf"]) : {socketPath: '/var/run/docker.sock'}, | |
confdir: process.env["conf_dir"] || "/conf", | |
template: process.env["template"] || "/template.vhost", | |
destination: process.env["destination"] | |
} | |
const fs = require('fs').promises; | |
const path = require('path'); | |
const {Docker} = require('node-docker-api'); | |
const promisifyStream = stream => new Promise((resolve, reject) => { | |
stream.on('data', data => ["die", "start"].includes(JSON.parse(data.toString())).status) ? start() : ""; | |
stream.on('end', resolve) | |
stream.on('error', reject) | |
}) | |
const docker = new Docker(config.docker) | |
docker.events() | |
.then(stream => promisifyStream(stream)) | |
.catch(error => console.log(error)); | |
async function start() { | |
//rm all files | |
await deleteConfigFiles(); | |
//Generate new ones | |
await generateAllFiles(); | |
//Send sighup | |
await sendSigHup(); | |
} | |
async function deleteConfigFiles() { | |
let files = await fs.readdir(path.normalize(config.confdir)); | |
await Promise.all(files.map(async file => { | |
if (file.endsWith(".conf")) { | |
await fs.unlink(path.join(config.confdir, file)); | |
} | |
})) | |
} | |
async function sendSigHup() { | |
let notify = (await docker.container.list()).filter(container => "proxy.notify" in container.data.Labels); | |
await Promise.all(notify.map(async container => await container.kill({signal: "SIGHUP"}))); | |
} | |
async function generateAllFiles() { | |
console.log("Getting list of containers") | |
let containers = await docker.container.list(); | |
await Promise.all(containers.map(async container => { | |
if ("proxy.hosts" in container.data.Labels) { | |
console.log(`Found container for proxying ${container.data.Names[0]}`) | |
await generateHostFile(container) | |
} | |
})) | |
} | |
async function generateHostFile(container) { | |
console.log(container.data.NetworkSettings.Networks) | |
let serverNamesArray = container.data.Labels["proxy.hosts"].split(",") | |
let server_names = serverNamesArray.join(" "); | |
let containerPort = container.data.Labels["proxy.port"] || 80; | |
//External | |
let proxy_pass; | |
if (config.destination) { | |
//External | |
let hostPort = (container.data.Ports.filter(port => port.PrivatePort === containerPort))[0].PublicPort; | |
proxy_pass = `http://${config.destination}:${hostPort}`; | |
} else { | |
//Local | |
proxy_pass = `http://${container.data.Names[0].split("/")[1]}:${containerPort}` | |
} | |
let template = (await fs.readFile(config.template)).toString(); | |
let vhost = template.interpolate({ | |
server_names: server_names, | |
proxy_pass: proxy_pass | |
}) | |
console.log(vhost) | |
await fs.writeFile(`${path.join(config.confdir, serverNamesArray[0])}.conf`, vhost); | |
} | |
String.prototype.interpolate = function (params) { | |
const names = Object.keys(params); | |
const vals = Object.values(params); | |
return new Function(...names, `return \`${this}\`;`)(...vals); | |
} | |
start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment