skip to Main Content

I’m migrating a VueJS application from "classic" Yarn 1.x to Yarn 2. Following the install documentation is straightforward and works without problems.

The tricky part comes when packaging the application in a Docker image.

Current Dockerfile

FROM node:14-alpine AS build-stage

WORKDIR /app

COPY package.json yarn.lock ./

RUN yarn install

COPY . ./

RUN yarn build --modern 
    && find dist -type f -exec gzip -k "{}" ;

FROM nginx:mainline-alpine as production-stage

RUN apk add --no-cache curl

HEALTHCHECK CMD curl -f http://localhost || exit 1

COPY docker/entrypoint.sh /
RUN chmod +x /entrypoint.sh

COPY docker/app.nginx /etc/nginx/conf.d/default.conf
COPY --from=build-stage /app/dist /usr/share/nginx/html

ENTRYPOINT [ "/entrypoint.sh" ]

Maybe I looked in the wrong places but I couldn’t find any information how a Yarn 2 Zero-Install setup would look like for a Docker image.

Do you have any recommendation on how to use the Yarn 2 approach in a Dockerfile?

2

Answers


  1. Due to a weird catch-22 with yarn 2’s package install process, I’ve found this to be the most effective method of installing yarn@berry with docker. There’s likely a better method of doing it, but I’m not aware of one.

    FROM node:latest as build
    WORKDIR /app
    
    # copy only the package.json file so yarn set version can
    # correctly download its modules for berry without overwriting
    # the existing yarnrc and cache files. If the rc is added now,
    # yarn will attempt to use the berry module without it being
    # installed.
    COPY package.json .
    RUN yarn set version berry
    
    # and _now_ pull in the rest of the build files overriding
    # the rc generated by setting the yarn version
    COPY yarn.lock .yarn .yarnrc.yml ./
    RUN yarn install
    COPY . .
    
    # continue with your build process
    

    However, I will note that yarn is intended to run from the local .yarn/releases folder, so the best method may simply be to install yarn2 in local and add it to the repo as yarn recommends. Then as a preliminary step with pulling in the package.json file, pull the necessary .yarn files with it as shown above. This should work under most circumstances, however it gave me difficulty sometimes, hence the above example.

    FROM node:latest as build
    WORKDIR /app
    
    # Copy in the package file as well as other yarn
    # dependencies in the local directory, assuming the
    # yarn berry release module is inside .yarn/releases
    # already
    COPY package.json yarn.lock .yarn .yarnrc.yml ./
    
    RUN yarn install
    COPY . .
    
    # continue with your build process
    
    Login or Signup to reply.
  2. @Ethan’s answer makes sense, and it should work. But for me I was getting this strange error during a build:

     > [ 7/10] RUN yarn --version:                                                                                                               
    #11 1.430 internal/modules/cjs/loader.js:905                                                                                                 
    #11 1.430   throw err;                                                                                                                       
    #11 1.430   ^                                                                                                                                
    #11 1.430                                                                                                                                    
    #11 1.430 Error: Cannot find module '/base/.yarn/releases/yarn-3.1.1.cjs'
    #11 1.430     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
    #11 1.430     at Function.Module._load (internal/modules/cjs/loader.js:746:27)
    #11 1.430     at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    #11 1.430     at internal/main/run_main_module.js:17:47 {
    #11 1.430   code: 'MODULE_NOT_FOUND',
    #11 1.430   requireStack: []
    #11 1.430 }
    

    Even though I definitely copied .yarn to the image, how well.

    I had to actually install yarn v2 within the build:

    FROM node:14.17.1 as build
    
    WORKDIR /base
    COPY package.json .
    RUN yarn set version berry
    
    RUN yarn install --frozen-lockfile
    

    UPDATE

    Turns out Docker doesn’t copy entire directories the way I thought it did.

    I had to add an explict COPY for the .yarn:

    COPY .yarn ./.yarn
    

    Solved it for me.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search