DEV Community

Michal Bryxí
Michal Bryxí

Posted on

Volta in Docker

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!
Enter fullscreen mode Exit fullscreen mode

Pin node and yarn versions in your project:

cd my-project
volta pin node@10.18.0; volta pin yarn@1.21.1
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now let's have package.json:

{
  "name": "volta-in-docker-example",
  "volta": {
    "node": "10.17.0",
    "yarn": "1.20.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

If you build such Docker container:

docker image build -t volta:0.0.1 -f volta.Dockerfile .
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Top comments (4)

Collapse
 
onyekaijeh profile image
Ijeh Onyeka

7 0.316 /bin/bash: volta: command not found


executor failed running [/bin/bash -c volta install node]: exit code: 127

Collapse
 
michalbryxi profile image
Michal Bryxí

Did you find solution?

Collapse
 
evanpurkhiser profile image
Evan Purkhiser

If you're using alpine it will fail. See github.com/volta-cli/volta/issues/473

Collapse
 
onyekaijeh profile image
Ijeh Onyeka

I didn't, reverted to using a base node image for now.
Still investigating though.