import { attachLogs, buildDockerImage, createContainer, listContainers, restartContainer, runCommandInContainer, startContainer, stopContainer } from "../apis/docker.js"; import { createCertificate, createProxyHost, deleteProxyHostByDomain, getCertificateByDomains, getCertificates, hasCerficateByDomains, isDomainRegistered } from "../apis/npm.js"; import { BASE_DOMAIN, INTERNAL_ADDRESS, INTERNAL_IP } from "../config.js"; interface Options { cloneUrl: string; branch: string; } export default async function deploy(options: Options) { const { cloneUrl, branch } = options; const [, user, name] = /http[s]{0,1}:\/\/.*\/(.*)\/(.*)\.git/.exec(cloneUrl); console.log(`deploying ${user}/${name}`); const imageName = await buildDockerImage({ user, name, cloneUrl, branch }); const containerName = `deploy-${user}-${name}-${branch}`; const { port } = await createContainer(imageName, containerName); const domain = `${branch}.${name}.${user}.${BASE_DOMAIN}`; await ensureDomainConfig(domain, port); console.log(`${user}/${name} available at https://${domain}/`); } async function ensureDomainConfig(domain: string, port: number) { // === certificate info let certId = null; if(await hasCerficateByDomains([domain])) { certId = (await getCertificateByDomains([domain])).id; console.log('certificate for', domain, 'already exists'); } else { const newCert = await createCertificate([domain]); certId = newCert.id; } if(await isDomainRegistered(domain)) { await deleteProxyHostByDomain(domain); } await createProxyHost([domain], port, INTERNAL_ADDRESS, { ssl_forced: true, block_exploits: true, allow_websocket_upgrade: true, http2_support: true, certificate_id: certId }); }