Docker yarn install stuck forever on M1 mac - node.js

I have an M1 mac. I'm trying to build a docker image. I'm trying to build it on x86_64. Everything works fine until yarn install. It's stuck forever. Here's my Dockerfile:
FROM --platform=linux/x86_64 public.ecr.aws/docker/library/node:16
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && unzip awscliv2.zip
RUN ./aws/install && aws --version
RUN mkdir code
WORKDIR /code
COPY package.json yarn.lock /code/
RUN yarn install --production --frozen-lockfile && yarn cache clean
EXPOSE 3000
ADD lib /code/lib
USER node
CMD ["node", "lib/index.js"]
If I don't set --platform=linux/x86_64 it's failing on installing aws-cli. If I skip aws cli (and don't set platform), yarn install finishes within a minute, and the build succeeds.
I've also tried --platform=linux/amd64, same result.
What causes yarn install take forever?

Related

Running Angular app as docker image using Node js

Trying to build angular application in docker and run as container in my local using Node js.
I have used build image using below Dockerfile, but i am not sure what i am missing while running. Can someone point me out?
Dockerfile:
FROM node:10.15.3
ENV HOME=/home
WORKDIR $HOME
RUN npm config set strict-ssl false \
&& npm config set proxy http://proxy.xxxxxx.com:8080
COPY package.json .
RUN npm install
Image created with below command successfully
docker build -t example .
I am trying to run the image using below command, but it is not helping
docker run -p 4201:4200 example
your Dockerfile does not run/serve your application, in order to do that you have to:
install angular/cli
copy the app
run/serve the app
FROM node:10.15.3
RUN npm config set strict-ssl false \
&& npm config set proxy http://proxy.xxxxxx.com:8080
# get the app
WORKDIR /src
COPY . .
# install packages
RUN npm ci
RUN npm install -g #angular/cli
# start app
CMD ng serve --host 0.0.0.0
hope this helps.
Container need a foreground process running, then it will not exit. If not, the container will directly exit.
For your case, you need to COPY your nodejs project to container when docker build, and also start the project in CMD like CMD [ "npm", "start" ]. As the web server not exit, then your container will not exit.
A good article here for your reference on how to dockerizing a Node.js web app.
Just update your Dockerfile to achieve your goal for more options see here:
# base image
FROM node:12.2.0
RUN npm config set strict-ssl false \
&& npm config set proxy http://proxy.xxxxxx.com:8080
# install chrome for protractor tests
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update && apt-get install -yq google-chrome-stable
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /app/package.json
RUN npm install
RUN npm install -g #angular/cli#7.3.9
# add app
COPY . /app
# start app
CMD ng serve --host 0.0.0.0
Give a shot for the following Dockerfile as well!
FROM node:alpine
# get the app
WORKDIR /src
# install packages
RUN npm ci
RUN npm install -g #angular/cli
COPY package.json .
RUN npm install
COPY . .
# start app
CMD ["ng", "serve", "-o"]

How to install git and gatsby from docker

I am trying to install git and gatsby from docker. Though i am able to install git, which seems to be running when i run "git status" after running docker exec -it sh. But, gatsby does not work.
FROM node:alpine
# Also exposing VSCode debug ports
EXPOSE 8000 9929 9230
ARG SSG_HOME=/opt/ssg
WORKDIR $SSG_HOME
#Install Git
RUN apk update && apk upgrade && \
apk add --no-cache bash git openssh
#Install Gatsby
RUN apk add --update npm
RUN npm install gatsby-cli
COPY . $SSG_HOME
RUN npm run setup
ENTRYPOINT ["npm","run"]
CMD ["start-docker"]
I expect that it'll recognize the keyword gatsby, but it shows gatsby not found
$ docker exec -it db6e5a3518c0 sh
/opt/ssg # gatsby
sh: gatsby: not found
/opt/ssg #
You're only installing it in a particular directory. Instead, go global:
RUN npm install -g gatsby-cli

npm install not being running on building container

I have a simple node app with the following Dockerfile:
FROM node:8-alpine
WORKDIR /home/my-app
COPY package.json .
COPY ./app ./app
COPY ./server.js ./
RUN rm -rf node_modules
RUN npm install \
npm run build
EXPOSE 3000
When I build the image with: docker build -t my-app:latest ., I attempt to run the app and it complains that some modules are missing.
When I go into the container via docker run -i -t my-app:latest /bin/sh I can see that the packages have not been installed. After manually running npm install in the container, it seems to work.
I can only conclude that from this RUN npm install not being executed correctly inside the container.

Why is my npm dockerfile looping?

I'm containerizing a nodejs app. My Dockerfile looks like this:
FROM node:4-onbuild
ADD ./ /egp
RUN cd /egp \
&& apt-get update \
&& apt-get install -y r-base python-dev python-matplotlib python-pil python-pip \
&& ./init.R \
&& pip install wordcloud \
&& echo "ABOUT TO do NPM" \
&& npm install -g bower gulp \
&& echo "JUST FINISHED ALL INSTALLATION"
EXPOSE 5000
# CMD npm start > app.log
CMD ["npm", "start", ">", "app.log"]
When I DON'T use the Dockerfile, and instead run
docker run -it -p 5000:5000 -v $(pwd):/egp node:4-onbuild /bin/bash
I can then paste the value of the RUN command and it all works perfectly, and then execute the npm start command and I'm good to go. However, upon attempting instead docker build . it seems to run in to an endless loop attempting to install npm stuff (and never displaying my echo commands), until it crashes with an out-of-memory error. Where have I gone wrong?
EDIT
Here is a minimal version of the EGP folder that exhibits the same container: logging in and pasting the whole "RUN" command works, but docker build does not.It is a .tar.gz file (though the name might download without one of the .)
http://orys.us/egpbroken
The node:4-onbuild image contains the following Dockerfile
FROM node:4.4.7
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app
CMD [ "npm", "start" ]
The three ONBUILD commands run before your ADD or RUN command are kicked off, and the endless loop appears to come from the npm install command that's running. When you launch the container directly, the ONBUILD commands are skipped since you didn't build a child-image. Change your FROM line to:
FROM node:4
and you should have your expected results.

How to cache the RUN npm install instruction when docker build a Dockerfile

I am currently developing a Node backend for my application.
When dockerizing it (docker build .) the longest phase is the RUN npm install. The RUN npm install instruction runs on every small server code change, which impedes productivity through increased build time.
I found that running npm install where the application code lives and adding the node_modules to the container with the ADD instruction solves this issue, but it is far from best practice. It kind of breaks the whole idea of dockerizing it and it cause the container to weight much more.
Any other solutions?
Ok so I found this great article about efficiency when writing a docker file.
This is an example of a bad docker file adding the application code before running the RUN npm install instruction:
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
WORKDIR /opt/app
COPY . /opt/app
RUN npm install
EXPOSE 3001
CMD ["node", "server.js"]
By dividing the copy of the application into 2 COPY instructions (one for the package.json file and the other for the rest of the files) and running the npm install instruction before adding the actual code, any code change wont trigger the RUN npm install instruction, only changes of the package.json will trigger it. Better practice docker file:
FROM ubuntu
MAINTAINER David Weinstein <david#bitjudo.com>
# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app
EXPOSE 3000
CMD ["node", "server.js"]
This is where the package.json file added, install its dependencies and copy them into the container WORKDIR, where the app lives:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
To avoid the npm install phase on every docker build just copy those lines and change the ^/opt/app^ to the location your app lives inside the container.
Weird! No one mentions multi-stage build.
# ---- Base Node ----
FROM alpine:3.5 AS base
# install node
RUN apk add --no-cache nodejs-current tini
# set working directory
WORKDIR /root/chat
# Set tini as entrypoint
ENTRYPOINT ["/sbin/tini", "--"]
# copy project file
COPY package.json .
#
# ---- Dependencies ----
FROM base AS dependencies
# install node packages
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
# copy production node_modules aside
RUN cp -R node_modules prod_node_modules
# install ALL node_modules, including 'devDependencies'
RUN npm install
#
# ---- Test ----
# run linters, setup and tests
FROM dependencies AS test
COPY . .
RUN npm run lint && npm run setup && npm run test
#
# ---- Release ----
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/chat/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 5000
CMD npm run start
Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/
I've found that the simplest approach is to leverage Docker's copy semantics:
The COPY instruction copies new files or directories from and adds them to the filesystem of the container at the path .
This means that if you first explicitly copy the package.json file and then run the npm install step that it can be cached and then you can copy the rest of the source directory. If the package.json file has changed, then that will be new and it will re-run the npm install caching that for future builds.
A snippet from the end of a Dockerfile would look like:
# install node modules
WORKDIR /usr/app
COPY package.json /usr/app/package.json
RUN npm install
# install application
COPY . /usr/app
I imagine you may already know, but you could include a .dockerignore file in the same folder containing
node_modules
npm-debug.log
to avoid bloating your image when you push to docker hub
you don't need to use tmp folder, just copy package.json to your container's application folder, do some install work and copy all files later.
COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app
I wanted to use volumes, not copy, and keep using docker compose, and I could do it chaining the commands at the end
FROM debian:latest
RUN apt -y update \
&& apt -y install curl \
&& curl -sL https://deb.nodesource.com/setup_12.x | bash - \
&& apt -y install nodejs
RUN apt -y update \
&& apt -y install wget \
build-essential \
net-tools
RUN npm install pm2 -g
RUN mkdir -p /home/services_monitor/ && touch /home/services_monitor/
RUN chown -R root:root /home/services_monitor/
WORKDIR /home/services_monitor/
CMD npm install \
&& pm2-runtime /home/services_monitor/start.json

Resources