Skip to content

Instantly share code, notes, and snippets.

@nodkz
Created December 8, 2016 14:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nodkz/b843d65a3430a4f510e5f5eb0cc759d2 to your computer and use it in GitHub Desktop.
Save nodkz/b843d65a3430a4f510e5f5eb0cc759d2 to your computer and use it in GitHub Desktop.
Building `node:slim` docker container with your node_modules via `node:build` container on Mac.
/* eslint-disable no-use-before-define, camelcase */
import cp from 'child_process';
import fsExtra from 'fs-extra';
import hashFiles from 'hash-files';
import chalk from 'chalk';
import {
repositoryName,
rootDir,
buildEnv,
isDockerImageExists,
getContainerInfo,
} from '../config';
const imageName = `${repositoryName}/node-modules`;
const ramDiskName = `docker_${new Date().toJSON().slice(0, 19).replace(/[^0-9]+/g, '')}`;
const dockerContextFolder = `/Volumes/${ramDiskName}`;
console.log(imageName);
export default function build_DockerContainer_With_NodeModules() {
const imageTag = calcPackageHash(buildEnv);
const imageNameWithTag = `${imageName}:${imageTag}`;
if (!isDockerImageExists(imageNameWithTag)) {
try {
console.log(`Mounting RAM disk ${ramDiskName}`);
mountRamDisk();
console.log(
chalk.magenta('Installing node_modules for debian '
+ 'via Docker container (node:onbuild 650MB) to the RAM disk')
);
npmInstallViaFatContainer(buildEnv);
console.log(chalk.magenta(`Creating slim docker image: ${imageNameWithTag}...`));
createDockerContainer(imageNameWithTag);
} finally {
console.log(`Unmounting RAM disk ${ramDiskName}`);
unmountRamDisk();
}
console.log(chalk.magenta('Docker container with NODE_MODULES successfully builded.'));
} else {
console.log(chalk.magenta('Docker container with NODE_MODULES already exists.'));
}
console.log(chalk.magenta(getContainerInfo(imageNameWithTag)));
console.log(chalk.magenta('You can run container via command:'));
console.log(chalk.bold.magenta(`docker run -i -t ${imageNameWithTag} /bin/bash`));
return {
name: imageName,
tag: imageTag,
nameWithTag: imageNameWithTag,
};
}
function createDockerContainer(imageNameWithTag) {
const dockerfile = [
'FROM node:slim', // 120MB container only with node
'WORKDIR /src',
'COPY . /src',
];
fsExtra.outputFileSync(`${dockerContextFolder}/Dockerfile`, dockerfile.join('\n'));
cp.execSync(`docker build \
-t ${imageNameWithTag} \
${dockerContextFolder}`,
{
cwd: dockerContextFolder,
stdio: [0, 1, 2],
}
);
}
function npmInstallViaFatContainer(env) {
fsExtra.emptyDirSync(dockerContextFolder);
fsExtra.copySync(`${rootDir}/package.json`, `${dockerContextFolder}/package.json`);
fsExtra.copySync(`${rootDir}/yarn.lock`, `${dockerContextFolder}/yarn.lock`);
const npmInstallCmd = (env === 'production')
// ? 'npm install --production'
? 'curl -o- -L https://yarnpkg.com/install.sh | bash && ~/.yarn/bin/yarn install --production && rm -rf ~/.yarn'
: 'npm install';
// IMPORTANT: `node:onbuild` is 650MB container with build scripts
// needed for build `fsevent` and `crypto` bin-files for debian
cp.execSync(`docker run \
-t --rm -v ${dockerContextFolder}:/src \
node:onbuild \
/bin/bash -c "cd /src && ${npmInstallCmd}"`,
{
cwd: dockerContextFolder,
stdio: [0, 1, 2],
}
);
}
function calcPackageHash(env) {
const hash = hashFiles.sync({
files: [
`${rootDir}/package.json`,
],
});
return `${env}-${hash}`;
}
function mountRamDisk() {
cp.execSync(`diskutil erasevolume hfsx ${ramDiskName} \`hdiutil attach -nomount ram://1000000\``,
{ stdio: [0, 1, 2] }
);
}
function unmountRamDisk() {
cp.execSync(`diskutil unmountDisk force ${ramDiskName}`,
{ stdio: [0, 1, 2] }
);
}
@nodkz
Copy link
Author

nodkz commented Dec 8, 2016

Yarn 0.17.10 may not install all needed packages with --production flag.
So you should change:

'curl -o- -L https://yarnpkg.com/install.sh | bash && ~/.yarn/bin/yarn install --production && rm -rf ~/.yarn'

on lates nightly build 0.19.0-20161207.1241, which works correctly fo me:

wget https://yarnpkg.com/install.sh && chmod +x install.sh && ./install.sh --nightly && rm -f install.sh && ~/.yarn/bin/yarn install --production && rm -rf ~/.yarn

Related issue: yarnpkg/yarn#761

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment