Docker, AlpineLinux and Ubuntu - why does `node_modules` different - node.js

Environment
I do use CI/CD of gitlab to bundle my application.
I do use node:14-alpine as image and do run yarn to build my app.
After build is finished, I do deploy my app via rsync to the target-server, which run's ubuntu 20.04.
On this server, I do use pm2 to start the app and keep it running.
Issue
If I look into the logs, I do see an error like this:
I've searched a bit, and found that the issue might be caused of musl-dev is missing.
I've installed it at my server, and into the docker-container, but with same result.
BUT, if I do delete the node_modules directory from server, and run yarn install right at the Server, the app run like expected
Question
So why does this issue happens here? Must I have the same distribution & version of linux in my docker-container to fit all dependencies?

Don't use an Alpine image if you're deploying on Ubuntu.
So why does this issue happens here?
The fundamental C standard library implementation is different on the two (Alpine uses musl libc; Ubuntu and more or less all other distros use GNU C Library (glibc)).
Trying to move binaries (such as those that might appear in node_modules for native modules) built against one libc implementation to a system using the other will likely be painful or not work at all (as you noticed).
Must I have the same distribution & version of linux in my docker-container to fit all dependencies?
If none of the dependencies use native code, then you should be able to just move things over without issues, but otherwise it'll be easiest (e.g. considering the versions of other libraries your dependencies may link against) to just use the same version as your target OS – or, if you don't want to think about that, just deploy your application as a Docker container.

Even if the suggestion from #AKX is a good answer, I've played a bit around to figure out how to solve this special case.
Here is my solution:
install musl-dev at the server
link it to /lib
apt-get install musl-dev
ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1
In my case it's only this single dependency which cause the trouble. If I got more of this, I will follow AKX's suggestion and choose a debian/ubuntu-like distribution to bundle it.

Related

How to build linux tools via MingW64 in 2021?

I'm trying to follow this example to build wget2:
https://gnutoolchains.com/building/
I've installed x86_64-8.1.0-win32-seh-rt_v6-rev0 preset (?) and first tried to build old version of wget1, but I've reached dead end. There is no way to run ./configure to create build target rules. Did I install something wrong? How I'm supposed to know what exactly is to install? Is it each new preset for each application I want to build? How I'm supposed to handle the insane list of requirements of wget2:
https://gitlab.com/gnuwget/wget2#build-requirements
And lastly - why is it so jank? Is it by design?
There is a way to run ./configure on Windows. You need MSYS2 for that, which will give you a bash shell and the tools needed by ./configure.
MSYS2 comes with a package manager (pacman) which allows you to install a more recent MinGW-w64.

Install an external library instance of libv8-3.14 to folder

I need libv8-3.14 to run some R packages on linux, but I don't have root access/sudo access on the linux computer I'm using so I'd like to install an external folder instance of libv8-3.14. I've seen R packages reference this as external as CDFLAG="folder/v8-3.14" so I know it is possible.
I'm new(ish) to linux but I've installed external libraries before with tar.gz files which then have a configure file in them, which I set the external folder with ./configure --prefix==/folder/loc, but the only downloads I can find of libv8 are .git (which I can't get to work either).
How can I install an libv8-3.14 to a folder and install so I can set:
export PATH=$PATH:/path/to/install/
and
export `LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/install/`
I had the exact same problem. In case somebody in the future comes across this post, I will leave my suggestions and how it worked out in the end. Also, all credits go to an experienced colleague of mine.
The most sure thing to do is to consult IT, or someone who has already had the same problem, there is usually a workaround these issues.
A way you can do it yourself:
Create an anaconda environment, you can name it 'V8' or something (make sure the environment is based on the latest python version, or recent enough for r-v8).
activate it
install the conda version of the V8 R interface with conda install -c conda-forge r-v8
That's it. Whenever you need V8, fire up your environment beforehand, and it should be A-OK.
Further advice: If you run into errors when installing r-v8, it may be a good idea to update your conda and all the packages. However, depending on your conda version conda update conda and conda upgrade --all MAY BREAK your conda installation, so be careful. (For further information on this problem, see the endless complaints of people in this issue: https://github.com/conda/conda/issues/8920).
V8 doesn't use autotools, so it has no ./configure. In fact, it provides no installation facilities at all, because it is meant for embedding, not installing.
What I would try is to download the Ubuntu package (guessing from your other question, you are on Ubuntu, right?) for the right architecture from https://packages.ubuntu.com/trusty/libv8-3.14.5, and extracting it manually. .deb files are just ZIP archives.
As a side note, there's no point in setting PATH, because libv8, being a library, provides no executables. LD_LIBRARY_PATH is all you need.

How do I switch between different versions of Julia (specifically between v0.3 and v0.4 on Ubuntu)?

I am working on some projects using Julia v0.3. However, I'd like to test my code in both v0.3 and v0.4 (since some of the people that are going to be using it are already using v0.4). I'm running Ubuntu 14.04 and have installed Julia using apt-get. I know v0.4 is available through the PPA julianightlies, but if I add this, v0.3 is replaced. Is there a way I can install and quickly switch between both versions for testing purposes?
You can install different versions of Julia in different locations and set separate symlinks.
For example, you could download the v0.3 Linux binaries and install them to one location, then clone the GitHub source for v0.4 and install that in another location. Then set symlinks such as julia3 for v0.3 and julia4 for v0.4.
Run your code like:
$ julia3 somefile.jl
$ julia4 somefile.jl
Install by compiling and then change your she-bang in the start of the file as
#!/path_to/julia3
or
#!/path_to/julia4
That will do the trick

Cross-compile node module with native bindings with node-gyp

I'm using AWS Lambda, which involves creating an archive of my node.js script, including the node_modules folder and uploading that to their infrastructure to run.
This works fine, except when it comes to node modules with native bindings (using node-gyp). Because the binding was complied and project archived on my local computer (OS X), it is not compatible with AWS's (Amazon Linux) servers.
How can I cross-compile/install a node module (specifically, node-sqlite3) so when I upload it to another server arch it runs?
While not really a solution to your problem, a very easy workaround could be to simply compile the native addons on a Linux machine.
For your particular situation, I would use Vagrant. Vagrant can create virtual machines and configure them within seconds.
Find an OS image that resembles Amazon's Linux distro (Fedora, CentOS, others that use yum as package manager - see Wiki)
Use a simple configuration script that, when run by Vagrant on machine startup, will run npm install (optionally it might also remove the node_modules folder before to ensure a clean installation)
For extra comfort, the script can also create the zip file for deployment
Once the installation finishes, the script will shutdown the VM to avoid unnecessary consumption of system resources
Deploy!
It might require some tuning if the linked libraries are not at the same place on the target machine but generally this seems to me like the best and quickest solution.
While installing the app using Vagrant might be sufficient in some cases, I have found it necessary to build the app on Linux which is as close to Lambda's Amazon Linux AMI as possible.
You can read the original answer here: https://stackoverflow.com/a/34019739/303184
Steps to make it work:
Spawn new EC2 instance. Make sure it is based on exactly the same image as your AWS Lambda runtime. You can review Lambda env details here: http://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html. In our case, it was Amazon Linux AMI called amzn-ami-hvm-2015.03.0.x86_64-gp2.
Install nvm and use it to install the same version of Node.js as on the AWS Lambda. At the time of writing this, it was v0.10.36. You can refer to http://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html again to find out.
You will probably need to install git & g++ compiler on the EC2. You can do this running
sudo yum install git gcc-c++
Finally, clone your app to your new EC2 and install your app's dependecies:
nvm use 0.10.36
npm install --production
You can then easily download the node_modules using scp or such.
Same lines as Robert's answer, when I had to work on my MAC in a different OS I use vm ware like Oracle's free virtualizer VirtualBox to get a linux on my mac, no cost to me. Or sign up for a new AWS account, you get a micro for a year free. Use that to get your linux box, do whatever you need there.
AWS has a page describing how to deal with native NPM modules: https://aws.amazon.com/blogs/compute/nodejs-packages-in-lambda/

CouchDB install multiple versions side-by-side

I attempt to install multiple versions of CouchDB databases, say 1.1.0 along side with 0.10.0.
By using build-couchdb I was able to get the latest version up and running with no problems, now I am trying with installing a second version (0.10.0) but with no success so far. Following with the instructions, I've tried:
rake git="git://git.apache.org/couchdb.git tags/0.10.0" install=/full/path/to/couchdb/dir
It does a bunch of installs but fails at the end with "rake aborted!".
Have anyone successfully done this ?
Build CouchDB can be slightly brittle. In production, what I've seen is a lot of complete wipes and complete rebuilds. Since people tend to build only once, the build time is not a huge pain-point.
Next, try to use the Erlang shortcut for installing side-by-side CouchDB builds. (Search for couchdb_build in the README).
rake git="git://git.apache.org/couchdb.git tags/0.10.0" \
install=/full/path/to/couch/dependencies \
couchdb_build=/full/path/to/couch/0.10.0
rake git="git://git.apache.org/couchdb.git tags/1.1.0" \
install=/full/path/to/couch/dependencies \
couchdb_build=/full/path/to/couch/1.1.0
With the install locations identical, Build CouchDB should skip the entire process to build and install dependencies when it builds 1.1.0. This includes:
Erlang
OTP
Javascript
I believe this technique is used more often than the simpler one for side-by-side builds. Therefore it is possible this workaround will fix your error.
If you still have issues, it is probably a bug. Would you please submit a Build CouchDB issue indicating your operating system version and also attach your rake.log file?

Resources