Search code examples
dockerdockerfileyarnpkggithub-actions

Yarn install errors with "ENOENT: no such file or directory


I have a Dockerfile and when I run it locally, everything works fine, however my build through GitHub actions seems to fail, the error I am getting is:

error An unexpected error occurred: "ENOENT: no such file or directory, stat '/home/runner/work/akira/akira/README.md'".

I tried to remove the yarn.lock but without success, a full log of the build that fails can be found here, my Dockerfile is below:

Dockerfile:

FROM node:14.0.0 AS base
WORKDIR /usr/src/app

FROM base as builder
COPY ./lerna.json .
COPY ./package.json .
COPY ./tsconfig.json .
COPY ./yarn.lock .
COPY ./packages/akira/prisma ./packages/akira/prisma
COPY ./packages/akira/src ./packages/akira/src
COPY ./packages/akira/types ./packages/akira/types
COPY ./packages/akira/package*.json ./packages/akira/
COPY ./packages/akira/tsconfig.json ./packages/akira
RUN yarn install --frozen-lockfile
RUN yarn build

FROM builder as migrate
RUN yarn workspace akira prisma migrate up --experimental

FROM base AS app
COPY --from=builder /usr/src/app/yarn.lock .
COPY --from=builder /usr/src/app/packages/akira/dist ./dist
COPY --from=builder /usr/src/app/packages/akira/prisma ./prisma
COPY --from=builder /usr/src/app/packages/akira/package.json .
RUN yarn install --production
USER node
ENV NODE_ENV=production
EXPOSE 4000
CMD ["node", "dist/index.js"]

Solution

  • If you look at your GitHub Actions workflow, or the log from the failing build that you linked, it seems to be running yarn commands outside of docker.

    It looks like yarn is struggling with the README symlink, not sure why, but as it seems you want to build with docker, I would try the following:

    Replace this part of the yaml

    - name: Use Node.js
      uses: actions/setup-node@master
      with:
        node-version: 14.4.0
    
    - name: Install dependencies
      run: yarn --frozen-lockfile
    
    - name: Build packages
      run: yarn build
    

    with something like

    - name: Build docker image
      run: docker build .
    

    Edit:

    As pointed out in below comment, the Dockerfile includes a side-effect of deploying database migrations.

    If you don't want to run everything from the Dockerfile in the Build pipeline, you can leverage multi-stage builds and stop at a specific stage.

    I.e., move the migrations into its own stage:

    FROM node:14.0.0 AS base
    WORKDIR /usr/src/app
    
    FROM base as builder
    COPY ./lerna.json .
    << lines omitted >>
    RUN yarn install --frozen-lockfile
    RUN yarn build
    
    FROM builder AS migr
    RUN yarn workspace akira prisma migrate up --experimental
    
    FROM base AS app
    COPY --from=builder /usr/src/app/yarn.lock .
    << lines omitted >>
    

    Then you can stop after the builder stage with

    docker build --target builder .
    

    Edit 2:

    Or you could keep the build pipeline and Dockerfile as it is, and instead fix the broken symlink, i.e. revert commit 0c87fa3