ELF header or installation problem with bcrypt in Docker container

Kind of a long snapshot, but does anyone have problems using bcrypt in a linux container (specifically docker) and be aware of an automatic workaround? I have the same problem as these two:

Invalid ELF header with node bcrypt in AWSBox

bcrypt invalid elf header when starting node application

My docker file

# Pull base image FROM node:0.12 # Expose port 8080 EXPOSE 8080 # Add current directory into path /data in image ADD . /data # Set working directory to /data WORKDIR /data # Install dependencies from package.json RUN npm install --production # Run index.js CMD ["npm", "start"] 

I got the previously mentioned incorrect ELF header error if I have bcrypt already installed in my node_modules, but if I remove it (either myself or all my packages), it is not installed for some reason when I create the container. I have to manually enter the container after assembly and install it inside.

Is there an automatic workaround?

Or maybe just what would be a good alternative to bcrypt with a node stack?

+7
linux docker bcrypt boot2docker
source share
2 answers

Liam's comment on money, just expanding for him for future travelers on the Internet.

The problem is that you copied your node_modules folder to your container. The reason this is a problem is because bcrypt is a native module. This is not only javascript, but also a bunch of C code that compiles during installation.

The binaries that exit this compilation are saved in the node_modules folder, and they are configured in the place where they were created. Transplanting them from the OSX home to the strange land of Linux makes them misbehave and complain about ELF headers and fairies.

The solution is echo node_modules >> .dockerignore and run npm install as part of your Docker file. This means that native modules will be compiled inside the container, and not outside it on your laptop.

With this in place, there is no need to run npm install before starting CMD. Just having it in the build phase of the Docker file is fine.

protip: official node images set NODE_ENV = default production, which npm handles the same as the --production flag. In most cases, this is good. This is not very good when your Dockerfile also contains some build steps that depend on dev dependencies (webpack, etc.). In this case, you want NODE_ENV=null npm install

pro protip: you can make better use of docker caching by copying the rest of your code separately to your package.json package. Make your Dockerfile as follows:

 # Pull base image FROM node:0.12 # Expose port 8080 EXPOSE 8080 # Set working directory to /data WORKDIR /data # Set working directory to /data COPY package.json /data # Install dependencies from package.json RUN npm install # Add current directory into path /data in image ADD . /data # Run index.js CMD npm start 

And in this case, Docker will rerun npm install when the package.json package changes, but not every time you change the line of code.

+7
source share

Ok, so I have an automatic workaround:

Call npm install --production in the CMD statement. I am going to wave my arms, figuring out why I need to install bcrypt at runtime of the container, but it works.

Updated Dockerfile

 # Pull base image FROM node:0.12 # Expose port 8080 EXPOSE 8080 # Add current directory into path /data in image ADD . /data # Set working directory to /data WORKDIR /data # Install dependencies from package.json RUN npm install --production # Run index.js CMD npm install --production; npm start 
+3
source share

All Articles