containerify (previously known as doqr) allows you to build node.js docker images without docker, allowing you to build a node.js docker image from within a docker container. This means you can build the container image on Kubernetes or Openshift - or locally in a docker container for more hermetic builds.
It will pull an image you specify from a given registry, add the node.js application from a given folder, and push the result to a(nother) given registry.
npm install -g containerify
This will pull the node:13-slim
image from Docker hub, build the image by adding the application in src/
, and push the result to the given registry, and set time timestamp of files in the created layers and configs to the current timestamp of the latest git commit.
containerify --fromImage node:13-slim --folder src/ --toImage myapp:latest --toRegistry https://registry.example.com/v2/ --setTimeStamp=$(git show -s --format="%aI" HEAD)
If you want to build a non-node container (e.g. add compiled frontend code to an nginx container), you can use --customContent
. When doing this
the normal node_modules
etc layers will not be added. By default it does NOT modify then entrypoint, user or workdir, so the base image settings are still used when running. You can still override with --entrypoint
etc. if needed.
npm run build # or some other build command
containerify --fromImage nginx:alpine --folder . --toImage frontend:latest --customContent dist:/usr/share/nginx/html --toRegistry https://registry.example.com/v2/
This will take the nginx:alpine
image, and copy the files from ./dist/
into /usr/share/nginx/html
.
- Create a token from https://github.com/settings/tokens/new?scopes=write:packages or use GITHUB_TOKEN from Github Actions
- Example:
containerify --registry https://ghcr.io/v2/ --token "$GITHUB_TOKEN" --fromImage docker-mirror/node:alpine --toImage <some image name>:<some tag> --folder .
- Create the repository in AWS from the console or through using the CLI
- Create token using
aws ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken'
- Example:
containerify --toToken "Basic $TOKEN" --toRegistry https://<AWS ACCOUNT ID>.dkr.ecr.<AWS region for repository>.amazonaws.com/v2/ --fromImage node:alpine --toImage <name of repository>:<some tag> --folder .
- Create the repository in GitLab
- Login using your username and password, CI-credentials, or obtain a token from GitLab
- Example using CI-credentials
containerify --toToken "Basic $(echo -n "${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}" | base64)" --to registry.gitlab.com/<Gitlab organisation>/<repository>:<tag>
Usage: containerify [options]
Options:
--from <registry/image:tag> Optional: Shorthand to specify fromRegistry and fromImage in one argument
--to <registry/image:tag> Optional: Shorthand to specify toRegistry and toImage in one argument
--fromImage <name:tag> Required: Image name of base image - [path/]image:tag
--toImage <name:tag> Required: Image name of target image - [path/]image:tag
--folder <full path> Required: Base folder of node application (contains package.json)
--file <path> Optional: Name of configuration file (defaults to containerify.json if found on path)
--doCrossMount Optional: Cross mount image layers from the base image (only works if fromImage and toImage are in the same registry) (default: false)
--fromRegistry <registry url> Optional: URL of registry to pull base image from - Default: https://registry-1.docker.io/v2/
--fromToken <token> Optional: Authentication token for from registry
--toRegistry <registry url> Optional: URL of registry to push base image to - Default: https://registry-1.docker.io/v2/
--optimisticToRegistryCheck Treat redirects as layer existing in remote registry. Potentially unsafe, but can save bandwidth.
--toToken <token> Optional: Authentication token for target registry
--toTar <path> Optional: Export to tar file
--toDocker Optional: Export to local docker registry
--registry <path> Optional: Convenience argument for setting both from and to registry
--platform <platform> Optional: Preferred platform, e.g. linux/amd64 or arm64
--token <path> Optional: Convenience argument for setting token for both from and to registry
--user <user> Optional: User account to run process in container - default: 1000 (empty for customContent)
--workdir <directory> Optional: Workdir where node app will be added and run from - default: /app (empty for customContent)
--entrypoint <entrypoint> Optional: Entrypoint when starting container - default: npm start (empty for customContent)
--labels <labels> Optional: Comma-separated list of key value pairs to use as labels
--label <label> Optional: Single label (name=value). This option can be used multiple times.
--envs <envs> Optional: Comma-separated list of key value pairs to use av environment variables.
--env <env> Optional: Single environment variable (name=value). This option can be used multiple times.
--setTimeStamp <timestamp> Optional: Set a specific ISO 8601 timestamp on all entries (e.g. git commit hash). Default: 1970 in tar files, and current time on manifest/config
--verbose Verbose logging
--allowInsecureRegistries Allow insecure registries (with self-signed/untrusted cert)
--allowNoPushAuth Allow pushing images without authentication/token if the registry allows it
--customContent <dirs/files> Optional: Skip normal node_modules and applayer and include specified root folder files/directories instead. You can specify as
local-path:absolute-container-path if you want to place it in a specific location
--extraContent <dirs/files> Optional: Add specific content. Specify as local-path:absolute-container-path,local-path2:absolute-container-path2 etc
--layerOwner <gid:uid> Optional: Set specific gid and uid on files in the added layers
--buildFolder <path> Optional: Use a specific build folder when creating the image
--layerCacheFolder <path> Optional: Folder to cache base layers between builds
--version Get containerify version
-h, --help display help for command
Everything in the specified folder (--folder
) is currently added to the image. It adds one layer with package.json
, package-lock.json
and node_modules
and then a separate layer with the rest.
You may want to prune dev-dependencies and remove any unwanted files before running containerify
.