Can't run mongodb-memory-server on Linux Alpine
Kostanos opened this issue · 18 comments
I got the error:
Cannot determine version string for {"os":"linux","dist":"Alpine Linux","release":"3.4.6"}
Can you take a look on https://github.com/nodkz/mongodb-memory-server/blob/master/src/util/MongoBinaryDownloadUrl.js and test for this file.
Will be awsome if you make Pull Request with fixing this error.
Thanks for help!
I'll check later, temporarily switched to docker image with mongo, need to finish my project first.
FYI for anyone running into this issue -- switching from the nodejs alpine image to the nodejs debian stretch image solved this for me (albeit with a MUCH larger image).
I'm getting an ENOENT error with the alpine image. This sums up why: https://stackoverflow.com/questions/32724556/execute-mongodb-binaries-on-alpine-linux
So if Mongo team makes alpine build we can easily add it to this package
https://www.mongodb.org/dl/linux
An opened issue in MongoDB: https://jira.mongodb.org/browse/SERVER-36790
At present it seems unlikely that MongoDB is going to release a separate Alpine Linux binary themselves. From their official documentation they direct users to the Alpine Linux mongodb package.
I would suggest that users who want to run their tests inside of an Alpine Linux container either add the specifically mentioned packages to their Dockerfile
or base their container on something like the alpine-mongo container that is already available on Docker Hub.
@jloveridge, you mention that I could use the apline-mongo image to run my tests but it still tries to download binaries inside that image (which it can't do since there aren't any official binaries...) is there a way (perhaps a combo of ENV vars) to tell mongodb-memory-server to use the installed system binaries instead of trying to download anything?
@jtbairdsr needs to create such var ;) Good feature request!
Firstly we should decide which name should have ENV variable which will point on the local installed mongod path. Currently available options are
binary: {
version?: string, // by default 'latest'
downloadDir?: string, // by default node_modules/.cache/mongodb-memory-server/mongodb-binaries
platform?: string, // by default os.platform()
arch?: string, // by default os.arch()
debug?: boolean, // by default false
skipMD5?: boolean, // by default false OR process.env.MONGOMS_SKIP_MD5_CHECK
},
Then improve getPath
method: https://github.com/nodkz/mongodb-memory-server/blob/master/src/util/MongoBinary.js#L26 with such logic:
- check local binary provided via the new a var
- if var non-empty
- check path availability and return it
- if not available drop a warning to console and run standard code (with download/cache)
- if var empty
- just run current standard code
Also, it should have different var names according to the current environment Mac, Linux or Win.
Or maybe it should be an array of paths for any OS. I think that the array of paths is more preferable.
Thougts?
@nodkz I don't know if I understand why we need different vars for each environment. This is one of those things that the environment is going to know about (a Mac environment will only know about its own path). If the path is different on a windows machine then on Mac, that should be reflected in the contents of the variable not in the name of the variable...
currently we pull the same variable regardless of the OS for all other env variables so I think that we should follow that same pattern...
some ideas for variable names are
systemBinary
-process.env.MONGOMS_SYSTEM_BINARY
systemBin
-process.env.MONGOMS_SYSTEM_BIN
sysBin
-process.env.MONGOMS_SYS_BIN
bin
-process.env.MONGOMS_BIN
if we really need to provide a different var for each OS, we could use the os as a key to get the correct path from the variable which would make it fairly simple to consume...
// binary.systemBinary = { darwin: '/usr/bin/mongod', debian: '/usr/local/bin/mongod' }
systemBinaryPath = binary.systemBinary[os.platform()]
// systemBinaryPath === '/usr/ bin/mongod'
we could maybe even provide a default config that knows where the default install is for each system (or at least some common systems like Mac and windows and linux) so that if it is available we consume the system binaries by default (although that seams like a lot of maintenance to me)
my next question is what do we do about version if a system binary is provided... Do we discard any version info passed? Do we try and check the system binary for version and see if they match? Do we discard system binary in favor of version? Do we just log that we have both settings and what there values are and then proceed with the system version?
I think I prefer the last option. Something like...
console.log(`
MongoMemoryServer: Possible version conflict
SystemBinary version: ${execSync('mongod --version')}
Requested version: ${binary.version}
`)
and then continue with the system version.
This last option lets the user decide how exact they want the match to be (if it needs to match on Major and minor and patch of just Major and minor or just Major etc.)
I also saves us from having to identify version matching edge cases...
@jtbairdsr open PR and let make it better via several iterations.
Firstly we should split getPath
method into several methods. And avoid using the hacking assignment of this.cache[version]
to systemBinary
. It will produce errors in the future, cause we make cache
variable unobvious.
Docker Alpine
There isn't currently an official MongoDB release for alpine linux. This means that we can't pull binaries for Alpine (or any other platform that isn't officially supported by MongoDB), but you can use a Docker image that already has mongod built in and then set the MONGOMS_SYSTEM_BINARY
variable to point at that binary. This should allow you to use mongodb-memory-server on any system on which you can install mongod.
All credits to @jtbairdsr for the excellent solution for the current problem!
PS. @jtbairdsr can you add a link for the recommended Docker container to README.md It helps to save time for many developers. Thanks again for amazing PR!
@jtbairdsr even more with provided image you can share your existed solution with docker file or bash command.
I am using this image. It is an image that I have created with the needed environment variables built right in. It is quite fast since it doesn't need any binaries to be downloaded and is only 158 MB. Here is the Dockerfile. Enjoy!
is this related to the environment I am currently using?
as per the documentation (and this issue's closing comment):
There are no official mongodb builds alpine, though there are some unoffical build of mongodb build for it which can be used
and there is #347
if you cant figure out why you are using alpine, please open a discussion or ask on our discord server.