@travetto/pack
Version:
Code packing utilities
140 lines (130 loc) • 4.09 kB
text/typescript
import { DockerPackConfig } from './types.ts';
/**
* Common utils for setting up pack config
*/
export class PackConfigUtil {
/**
* Docker setup
*/
static dockerInit(cfg: DockerPackConfig): string {
return `FROM ${cfg.dockerImage}`;
}
/**
* Install docker pages in either apk or apt environments
*/
static dockerPackageInstall(cfg: DockerPackConfig): string {
const { os, packages } = cfg.dockerRuntime;
if (packages?.length) {
switch (os) {
case 'alpine': return `RUN apk --update add ${packages.join(' ')} && rm -rf /var/cache/apk/*`;
case 'debian': return `RUN apt update && apt install -y ${packages.join(' ')} && rm -rf /var/lib/{apt,dpkg,cache,log}/`;
case 'centos': return `RUN yum -y install ${packages.join(' ')} && yum -y clean all && rm -fr /var/cache`;
case 'unknown':
default: throw new Error('Unable to install packages in an unknown os');
}
} else {
return '';
}
}
/**
* Install docker pages in either apk or apt environments
*/
static dockerNodePackageInstall(cfg: DockerPackConfig): string {
const out: string[] = [];
for (const item of cfg.externalDependencies ?? []) {
const [name, directive] = item.split(':');
switch (directive) {
case 'from-source':
out.push(`RUN npm_config_build_from_source=true npm install ${name} --build-from-source`); break;
default:
out.push(`RUN npm install ${name}`); break;
}
}
if (out.length) {
out.unshift(`WORKDIR ${cfg.dockerRuntime.folder}`);
}
return out.join('\n');
}
/**
* Setup docker ports
*/
static dockerPorts(cfg: DockerPackConfig): string {
return (cfg.dockerPort?.map(x => `EXPOSE ${x}`) ?? []).join('\n');
}
/**
* Setup docker user
*/
static dockerUser(cfg: DockerPackConfig): string {
const { os, user, group, uid, gid } = cfg.dockerRuntime;
if (user === 'root') {
return '';
} else {
switch (os) {
case 'alpine': return `RUN addgroup -g ${gid} ${group} && adduser -D -G ${group} -u ${uid} ${user}`;
case 'debian':
case 'centos': return `RUN groupadd --gid ${gid} ${group} && useradd -u ${uid} -g ${group} ${user}`;
case 'unknown':
default: throw new Error('Unable to add user/group for an unknown os');
}
}
}
/**
* Setup Env Vars for NODE_OPTIONS and other standard environment variables
*/
static dockerEnvVars(cfg: DockerPackConfig): string {
return [
`ENV NODE_OPTIONS="${[...(cfg.sourcemap ? ['--enable-source-maps'] : [])].join(' ')}"`,
].join('\n');
}
/**
* Setup docker runtime folder
*/
static dockerAppFolder(cfg: DockerPackConfig): string {
const { folder, user, group } = cfg.dockerRuntime;
return [
`RUN mkdir ${folder} && chown ${user}:${group} ${folder}`,
].join('\n');
}
/**
* Docker app files copied with proper permissions
*/
static dockerAppFiles(cfg: DockerPackConfig): string {
const { user, group, folder } = cfg.dockerRuntime;
return `COPY --chown="${user}:${group}" . ${folder}`;
}
/**
* Entrypoint creation for a docker configuration
*/
static dockerEntrypoint(cfg: DockerPackConfig): string {
const { user, folder } = cfg.dockerRuntime;
return [
`USER ${user}`,
`WORKDIR ${folder}`,
`ENTRYPOINT ["${folder}/${cfg.mainName}.sh"]`,
].join('\n');
}
/**
* Common docker environment setup
*/
static dockerWorkspace(cfg: DockerPackConfig): string {
return [
this.dockerPorts(cfg),
this.dockerUser(cfg),
this.dockerPackageInstall(cfg),
this.dockerAppFolder(cfg),
this.dockerAppFiles(cfg),
this.dockerEnvVars(cfg),
].filter(x => !!x).join('\n');
}
/**
* Common docker file setup
*/
static dockerStandardFile(cfg: DockerPackConfig): string {
return [
this.dockerInit(cfg),
this.dockerWorkspace(cfg),
this.dockerNodePackageInstall(cfg),
this.dockerEntrypoint(cfg)
].join('\n');
}
}