Error in Docker alpine linux
joyarzun opened this issue · comments
When running in docker alpine linux (FROM node:6-alpine) i get the following error:
/BlogApi/node_modules/mongodb-prebuilt/index.js:75
mongodb_logs(child.stdout.toString());
^
TypeError: Cannot read property 'toString' of null
at start (/BlogApi/node_modules/mongodb-prebuilt/index.js:75:34)
at Object.start_server (/BlogApi/node_modules/mongodb-prebuilt/index.js:69:16)
at /BlogApi/node_modules/mockgoose/Mockgoose.js:144:42
at next (/BlogApi/node_modules/rimraf/rimraf.js:74:7)
at CB (/BlogApi/node_modules/rimraf/rimraf.js:110:9)
at /BlogApi/node_modules/rimraf/rimraf.js:136:14
at FSReqWrap.oncomplete (fs.js:123:15)
Environment:
# npm ls mongodb-prebuilt
npm info it worked if it ends with ok
npm info using npm@3.10.8
npm info using node@v6.9.1
blogapi@1.0.0 /BlogApi
`-- mockgoose@6.0.8
`-- mongodb-prebuilt@5.0.8
I tested in MacOs and Debian, and work like a charm
I posted an issue in mockgoose project Mockgoose/Mockgoose#10
I used to get that error, but since using the latest mockgoose which uses mongodb-prebuilt@6, I get a different error. Here's my setup:
index.js
'use strict'
const MongodHelper = require('mongodb-prebuilt').MongodHelper
const helper = new MongodHelper()
helper.run()
.then(() => { console.log('done') })
.catch((err) => { console.log(err) })
Dockerfile
FROM node:boron-alpine
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install dependencies
COPY package.json /usr/src/app/
COPY yarn.lock /user/src/app/
RUN yarn
# Bundle app source
COPY . /usr/src/app
RUN node index
docker build .
Output (after it runs through and creates the .mongodb-prebuilt/
directory and such):
Error: spawn /root/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff/mongodb-linux-x86_64-3.5.4-15-ga271833/bin/mongod ENOENT
at exports._errnoException (util.js:1022:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
at onErrorNT (internal/child_process.js:359:16)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
I know it's not your job to be compatible with every platform, so let me know if there's additional work or information you'd like me to provide. I'll try and figure out what's going on. On an initial look, it does appear that path exists, just not sure why the spawn would think it wasn't.
@ksmithut this was interesting learning curve for me... thank you for this bug report
so in a few words, here is how to fix it:
- add to your Docker file before running index this:
ENV GLIBC_VERSION 2.25-r0
# Download and install glibc
RUN apk add --update curl && \
curl -Lo /etc/apk/keys/sgerrand.rsa.pub https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub && \
curl -Lo glibc.apk "https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk" && \
curl -Lo glibc-bin.apk "https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-bin-${GLIBC_VERSION}.apk" && \
apk add glibc-bin.apk glibc.apk && \
/usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib && \
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \
apk del curl && \
rm -rf glibc.apk glibc-bin.apk /var/cache/apk/*
my complete Dockerfile:
FROM node:boron-alpine
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install dependencies
RUN npm install mongodb-prebuilt
ENV GLIBC_VERSION 2.25-r0
# Download and install glibc
RUN apk add --update curl && \
curl -Lo /etc/apk/keys/sgerrand.rsa.pub https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub && \
curl -Lo glibc.apk "https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk" && \
curl -Lo glibc-bin.apk "https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-bin-${GLIBC_VERSION}.apk" && \
apk add glibc-bin.apk glibc.apk && \
/usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib && \
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \
apk del curl && \
rm -rf glibc.apk glibc-bin.apk /var/cache/apk/*
COPY index.js /usr/src/app/
RUN node index
next problem is, if you are running mongodb-prebuilt directly, you either have to create "/data/db" directory in your Dockerfile, or pass dbpath in MongodHelper constructor (or if you are using Mockgoose, it will create temporary dbpath for itself, and pass that to MongodHelper)
example of my index.js
'use strict'
const MongodHelper = require('mongodb-prebuilt').MongodHelper
const helper = new MongodHelper(['--dbpath', '/tmp'])
helper.run()
.then(() => { console.log('done') })
.catch((err) => { console.log(err) })
now if anyone is interested and probably for my future self some notes:
reason why this is happening is because mongod is glib application, which means it requires glibc to run, which from what i see alpine linux doesn't support out of the box (or this docker container doesn't support, i didnt research this at all)
if we would add ARG DEBUG=* to Dockerfile, we would see something like this:
winfinit:Mockgoose-bugs winfinit$ docker build .
Sending build context to Docker daemon 15.87 kB
Step 1/7 : FROM node:boron-alpine
---> 8232a8b9c483
Step 2/7 : ARG DEBUG=*
---> Using cache
---> 36f506c47839
Step 3/7 : RUN mkdir -p /usr/src/app
---> Using cache
---> a18b74e1109c
Step 4/7 : WORKDIR /usr/src/app
---> Using cache
---> a1d7e310fe32
Step 5/7 : RUN npm install mongodb-prebuilt
---> Using cache
---> 236a309cbfea
Step 6/7 : COPY index.js /usr/src/app/
---> Using cache
---> c37b83127553
Step 7/7 : RUN node index
---> Running in 5becf3bcaae4
Wed, 08 Mar 2017 04:30:49 GMT mongodb-prebuilt-MongoDBPrebuilt getHomeDirectory(): /root/.mongodb-prebuilt
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload createDownloadDir(): /root/.mongodb-prebuilt/mongodb-download
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload createDownloadDir(): true
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload getDownloadURI (url obj returned with href): https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload getHttpOptions { protocol: 'https:',
hostname: 'fastdl.mongodb.org',
path: '/linux/mongodb-linux-x86_64-latest.tgz' }
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload getDownloadLocation(): /root/.mongodb-prebuilt/mongodb-download/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload getTempDownloadLocation(): /root/.mongodb-prebuilt/mongodb-download/mongodb-linux-x86_64-latest.tgz.downloading
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload getDownloadLocation(): /root/.mongodb-prebuilt/mongodb-download/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:49 GMT mongodb-download-MongoDBDownload isDownloadPresent() location missing: false
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload download(): /root/.mongodb-prebuilt/mongodb-download/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadURI (url obj returned with href): https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadURIMD5: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz.md5
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadMD5Hash content: aa13e8317260dd46c63a0ad1dd2bc2ff mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadMD5Hash: aa13e8317260dd46c63a0ad1dd2bc2ff
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getExtractLocation(): /root/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadURI (url obj returned with href): https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadURIMD5: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz.md5
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadMD5Hash content: aa13e8317260dd46c63a0ad1dd2bc2ff mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadMD5Hash: aa13e8317260dd46c63a0ad1dd2bc2ff
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadURI (url obj returned with href): https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadURIMD5: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz.md5
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadMD5Hash content: aa13e8317260dd46c63a0ad1dd2bc2ff mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadMD5Hash: aa13e8317260dd46c63a0ad1dd2bc2ff
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getExtractLocation(): /root/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload isExtractPresent(): false
Wed, 08 Mar 2017 04:30:54 GMT mongodb-download-MongoDBDownload getDownloadLocation(): /root/.mongodb-prebuilt/mongodb-download/mongodb-linux-x86_64-latest.tgz
Wed, 08 Mar 2017 04:30:58 GMT mongodb-download-MongoDBDownload extract(): /root/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff
Wed, 08 Mar 2017 04:30:58 GMT mongodb-prebuilt-MongoDBPrebuilt resolveBinPath(): /root/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff/mongodb-linux-x86_64-3.5.4-15-ga271833/bin
Wed, 08 Mar 2017 04:30:58 GMT mongodb-prebuilt-MongoBins getCommand(): /root/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff/mongodb-linux-x86_64-3.5.4-15-ga271833/bin/mongod
Wed, 08 Mar 2017 04:30:58 GMT mongodb-prebuilt-MongoSupervice isWindows(): false
Wed, 08 Mar 2017 04:30:58 GMT mongodb-prebuilt-MongoSupervice runOnLinux()
Wed, 08 Mar 2017 04:30:58 GMT mongodb-prebuilt-MongoSupervice getSuperviseCommand(): /usr/src/app/node_modules/mongodb-prebuilt/built/bin/mongo-supervise.js
Wed, 08 Mar 2017 04:30:58 GMT mongodb-prebuilt-MongoBins run() Supervise process didn't start: TypeError: Cannot read property 'toString' of undefined
events.js:160
throw er; // Unhandled 'error' event
^
Error: spawn /root/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff/mongodb-linux-x86_64-3.5.4-15-ga271833/bin/mongod ENOENT
at exports._errnoException (util.js:1022:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
at onErrorNT (internal/child_process.js:359:16)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
The command '/bin/sh -c node index' returned a non-zero code: 1
so we see that we are getting ENOENT when attempting to run mongod command, so lets get into our container and investigate...
get a container id
docker ps -a
start container
docker run -dit <image_id_from_docker_ps>
enter container
docker exec -it <container_id> /bin/sh
run index, so it will download mongodb, and wait for it to fail, then cd into bin dir of extracted archive of mongodb
cd /root/.mongodb-prebuilt/*/*/*/bin
attempt to run mongod
~/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff/mongodb-linux-x86_64-3.5.4-15-ga271833/bin # ./mongod
/bin/sh: ./mongod: not found
but file exists, and perms are right
~/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff/mongodb-linux-x86_64-3.5.4-15-ga271833/bin # ls -lah mongod
-rwxr-xr-x 1 root root 51.9M Mar 8 05:48 mongod
lets check if we are missing any dependencies
~/.mongodb-prebuilt/mongodb-download/aa13e8317260dd46c63a0ad1dd2bc2ff/mongodb-linux-x86_64-3.5.4-15-ga271833/bin # ldd mongod
/lib64/ld-linux-x86-64.so.2 (0x55bf92a4b000)
librt.so.1 => /lib64/ld-linux-x86-64.so.2 (0x55bf92a4b000)
libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x55bf92a4b000)
libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x55bf92a4b000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f06e93a5000)
libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x55bf92a4b000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x55bf92a4b000)
Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by mongod)
Error relocating mongod: __snprintf_chk: symbol not found
Error relocating mongod: __fprintf_chk: symbol not found
Error relocating mongod: __memset_chk: symbol not found
Error relocating mongod: __syslog_chk: symbol not found
Error relocating mongod: __memcpy_chk: symbol not found
Error relocating mongod: __open_2: symbol not found
Error relocating mongod: __sprintf_chk: symbol not found
Error relocating mongod: backtrace: symbol not found
Error relocating mongod: gnu_get_libc_version: symbol not found
Error relocating mongod: __strcat_chk: symbol not found
Error relocating mongod: __strcpy_chk: symbol not found
Error relocating mongod: __swprintf_chk: symbol not found
Error relocating mongod: __vsnprintf_chk: symbol not found
Error relocating mongod: __sbrk: symbol not found
Error relocating mongod: __fread_chk: symbol not found
Error relocating mongod: __rawmemchr: symbol not found
Error relocating mongod: __strncpy_chk: symbol not found
Error relocating mongod: __memmove_chk: symbol not found
Error relocating mongod: __printf_chk: symbol not found
Error relocating mongod: __vfprintf_chk: symbol not found
Error relocating mongod: strtoq: symbol not found
Error relocating mongod: strtouq: symbol not found
so issue is here:
Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by mongod)
i've attempted to add libc6-compat through apt, but that didn't solve this issue and after quick search I see that it is a pretty common issue, and by installing glibc resolves this problem
glibc installation for alpine linux borrowed from: https://github.com/jeanblanchard/docker-alpine-glibc/blob/master/Dockerfile
@winfinit Thank you so much! Worked like a charm. Ya, my example was simplistic. I was actually running into the issue using Mockgoose which uses the dbPath and options you described. I was just trying to get the simplest example to reproduce the issue. Putting in glibc solved the issue with mockgoose.
An additional step I did to leverage Docker caching a bit better was to run the mockgoose command that sets up the .mongodb-prebuild/
folder and storage stuff that mockgoose/mongodb-prebuild needs to run.
Man, I was banging my head against this so hard for so long yesterday. My lack of Linux knowledge is starting to bite me. I appreciate your detailed response. I'd like to compensate you in some way. What's the best way to give back?
@ksmithut I am glad it helped and that is my reward in itself :) Best compensation to me is people using this project, so thank you!
For me it does not really work, my tests keep hanging for ever on alpine