loading...

Volta in Docker

michalbryxi profile image Michal Bryxí ・2 min read

Volta homepage says: "The JavaScript Launcher ⚡". What it does for me is:

  1. Have multiple node and yarn versions installed side by side
  2. Switch between individual node and yarn versions seamlessly (cd into the directory containing package.json is enough)
  3. Make sure that everyone in the team uses the same version of node and yarn
  4. Globally install node modules

How to volta

Install:

curl https://get.volta.sh | bash
volta install node
## That's it!

Pin node and yarn versions in your project:

cd my-project
volta pin node@10.18.0; volta pin yarn@1.21.1

Now you will have the respective versions of node and yarn available every time you enter the my-project directory.

Volta in Docker

The problem with Docker is that volta relies on sourcing the scripts stored ~/.bashrc. You could in theory prepend every "node command" with source ~/.bashrc && or something, but that's not very practical. Following example Dockerfile shows my solution with explanation on individual lines:

FROM debian:stable-slim
WORKDIR /myapp/

# curl and ca-certificates are needed for volta installation
RUN apt-get update \
  && apt-get install -y \
  curl \
  ca-certificates \
  --no-install-recommends

# bash will load volta() function via .bashrc 
# using $VOLTA_HOME/load.sh
SHELL ["/bin/bash", "-c"]

# since we're starting non-interactive shell, 
# we wil need to tell bash to load .bashrc manually
ENV BASH_ENV ~/.bashrc
# needed by volta() function
ENV VOLTA_HOME /root/.volta
# make sure packages managed by volta will be in PATH
ENV PATH $VOLTA_HOME/bin:$PATH

# install volta
RUN curl https://get.volta.sh | bash
RUN volta install node

# test whether global installation of packages works
RUN volta install ember-cli

# test that volta manages node/yarn version
COPY index.js package.json yarn.lock /myapp/
RUN yarn --pure-lockfile

Now let's have package.json:

{
  "name": "volta-in-docker-example",
  "volta": {
    "node": "10.17.0",
    "yarn": "1.20.0"
  }
}

If you build such Docker container:

docker image build -t volta:0.0.1 -f volta.Dockerfile .

And then check the node version installed, you should get whatever was specified in package.json:

docker container run --rm --name volta volta:0.0.1 node --version
# v10.17.0

The why

One could put FROM node:10.17.0 directly into the Dockerfile. But:

  1. One might not want to run node projects locally in a container, thus there will be a need to sync the versions
  2. Dev environment synchronisation is hard & important & hard
  3. yarn versions should also be in sync to prevent possible (real) problems

Posted on by:

michalbryxi profile

Michal Bryxí

@michalbryxi

Cycle 🚴 , climb 🗻 , run 🏃 , travel 🌍 , enjoy life ♥. IT guy with the need to live fully.

Discussion

markdown guide