rstudio / shiny-server

Host Shiny applications over the web.
https://rstudio.com/shiny/server
Other
712 stars 291 forks source link

Instructions on building from source are specific to X86_64 #524

Open mtbakerguy opened 2 years ago

mtbakerguy commented 2 years ago

Trying to compile on Oracle Linux 8 AARM64 architecture. The https://github.com/rstudio/shiny-server/wiki/Building-Shiny-Server-from-Source page references a private copy of Node.js which is compiled for the Intel architecture.

NOTE: this issue appears to be a distinct from https://github.com/rstudio/shiny-server/issues/523.

mtbakerguy commented 2 years ago

I got it to install by doing a combination of the following (I can't be more specific because there was one weirdness; see steps 3 and 4):

  1. dnf install @node:16 (the base level of node was 10.X).
  2. (cd .. && npm install) (NOTE the explicit relative path is removed). It failed.
  3. npm update
  4. (cd .. && npm install) and it worked the second time.

I'm not a javascript/node person so I suspect there's a way to simplify the above.

mtbakerguy commented 2 years ago

https://github.com/rstudio/shiny-server/tree/binaries#configuration is a broken link and referenced from the building from source document.

mtbakerguy commented 2 years ago

While it built and installed, it's installed incorrectly as the launcher is erroring out:

541012 execve("/usr/local/shiny-server/ext/node/bin/shiny-server", ["/usr/local/shiny-server/ext/node"..., "/usr/local/shiny-server/lib/main"...], 0xffffc7416718 /* 18 vars */) = -1 ENOENT (No such file or directory)

as the /usr/local/shiny-server/ext directory only has a pandoc directory in it.

mtbakerguy commented 2 years ago

Running the ../external/node/install-node.sh combined with make install gives me the right directory structure in /usr/local/shiny-server/ext but it's unhelpful as it's an unstripped x86-64 executable.

I used the following commands to fix this:

rm /usr/local/shiny-server/ext/bin/node
rm /usr/local/shiny-server/ext/bin/shiny-server
ln /bin/node /usr/local/shiny-server/ext/bin/node
ln /bin/node /usr/local/shiny-server/ext/bin/shiny-server

and got the following:

[shiny@instance-20210525-1046 ~]$ shiny-server
[2022-05-22T17:05:37.939] [INFO] shiny-server - Shiny Server v1.5.19.0 (Node.js v16.14.0)
[2022-05-22T17:05:37.942] [INFO] shiny-server - Using config file "/etc/shiny-server/shiny-server.conf"
[2022-05-22T17:05:37.974] [INFO] shiny-server - Starting listener on http://[::]:3838
mtbakerguy commented 2 years ago

Finally, you need to validate it's working by installing the welcome.html + sample-apps:

cp -r ~/shiny-server/samples /srv/shiny-server

Using a browser, visit the welcome.html page and follow its instructions. Beyond the post-install configuration steps above, I needed to run the following commands to get the hello application to work:

sudo mkdir /var/lib/shiny-server/bookmarks
sudo mkdir /var/lib/shiny-server/bookmarks/shiny

To get the markdown panel to work, I did the following in an R instance executing as root: install.packages('rmarkdown'). I also needed to remove the pandoc executable installed (it's a X86-64 binary) and replace it with an appropriate link:

dnf install pandoc
rm /usr/local/shiny-server/ext/pandoc/pandoc
ln /bin/pandoc /usr/local/shiny-server/ext/pandoc/pandoc

# optional
# rm /usr/local/shiny-server/ext/pandoc/pandoc-citeproc
mtbakerguy commented 2 years ago

Editorial note: this would've been significantly easier if the documentation/code took the least astonishing route and recommended users install node and pandoc as prerequisites and use the executables in the user's path instead of the ext directory (NOTE: without using strace this would've been significantly more painful to debug).

If you want to make AARM64 a first-class citizen, Oracle Cloud Infrastructure's "Always Free" plan (possibly bad assumption: capacity's available) allows you to have 4-cores and 24GB of RAM for free (you also get 2 IP addresses; one permanent and the other ephemeral).

mickeykawai commented 2 months ago

Hi @mtbakerguy, thank you very much for this very helpful issue.

Similarly I succeeded on Apple silicon ARM-based M2 mac (macos Sonoma 14.4.1 Apple M2). For M2 mac, in addition to the 3 files mentioned as above (ext/node/bin/node, ext/node/bin/shiny-server, ext/pandoc/pandoc), bin/shiny-server also need to be replaced (as noted at 5th point below).

  1. I used node 20.13.1 by installing nvm, instead of brew-installed node 22.2.0.
# install cmake, pandoc
brew install cmake
brew install pandoc

# install nvm and node
#followed by the instruction `Install & Update Script` at https://github.com/nvm-sh/nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

node 22.2.0 installed with brew caused error, which might be a general problem regarding nan module? (e.g. https://github.com/nodejs/nan/issues/936) (but not sure as I'm not node person either).

% (cd .. && npm install) 

> shiny-server@1.5.23 install
> node-gyp rebuild

gyp info it worked if it ends with ok
gyp info using node-gyp@10.1.0
gyp info using node@22.2.0 | darwin | arm64
...
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
  CXX(target) Release/obj.target/posix/src/posix.o
In file included from ../src/posix.cc:24:
../node_modules/nan/nan.h:2548:8: error: no matching member function for call to 'SetAccessor'
  tpl->SetAccessor(
  ~~~~~^~~~~~~~~~~
...
  1. Installed at /opt/ instead of /usr/local/
cmake -DCMAKE_INSTALL_PREFIX=/opt ../
#cmake -DCMAKE_INSTALL_PREFIX=/usr/local ../
  1. Used cp -p instead of ln

Both works, though, but followed the way of intel version to isolate node for this shiny-server.

# Do after cmake step, as 
#  - during `../external/node/install-node.sh` step, ext/node/bin/{node,shiny-server} for intel are downloaded. 
#  - during cmake step, pandoc for intel is downloaded. 

# Compile native code and install npm dependencies
make
mkdir ../build

cd ..
cd ext/node/bin
mv node node.x86_64
mv shiny-server shiny-server.x86_64
cp -p `which node` node
cp -p `which node` shiny-server
#cp -p /Users/mickey/.nvm/versions/node/v20.13.1/bin/node node
#cp -p /Users/mickey/.nvm/versions/node/v20.13.1/bin/node shiny-server

cd ../../..
cd ext/pandoc
mv pandoc pandoc.x86_64
cp -p /opt/homebrew/bin/pandoc pandoc

cd ../..
cd tmp
(cd .. && ./bin/npm install)
  1. At the step of npm install, did npm audit fix as suggested by npm.
% (cd .. && ./bin/npm install)
...
2 moderate severity vulnerabilities

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
% npm audit
# npm audit report

express  <4.19.2
Severity: moderate
Express.js Open Redirect in malformed URLs - https://github.com/advisories/GHSA-rv95-896h-c2vc
fix available via `npm audit fix`
node_modules/express

follow-redirects  <=1.15.5
Severity: moderate
follow-redirects' Proxy-Authorization header kept across hosts - https://github.com/advisories/GHSA-cxjh-pqwp-8mfp
fix available via `npm audit fix`
node_modules/follow-redirects

2 moderate severity vulnerabilities

To address all issues, run:
  npm audit fix

% npm audit fix
...
found 0 vulnerabilities
  1. bin/shiny-server has to be replaced to a shell script such as as follows.
#!/bin/sh
if [ $# -eq 0 ]; then
    exec "/opt/shiny-server/bin/node" "/opt/shiny-server/lib/main.js" "/opt/local/etc/shiny-server/shiny-server.conf"
    #exec "#{HOMEBREW_PREFIX}/bin/node" "#{prefix}/shiny-server/lib/main.js" "#{etc}/shiny-server/shiny-server.conf"
else
    exec "/opt/shiny-server/bin/node" "/opt/shiny-server/lib/main.js" "$@"
    #exec "#{HOMEBREW_PREFIX}/bin/node" "#{prefix}/shiny-server/lib/main.js" "$@"
fi

c.f. https://github.com/brewsci/homebrew-base, Formula/shiny-server.rb

ok_shiny-server_M2mac

mickeykawai commented 2 months ago

One further step brew install python-setuptools was necessary on my setting on the same M2 mac with macos Sonoma 14.5 released recently, in addition to what described as above.

brew install python-setuptools
# distutils package is removed in python version 3.12
# I don't know why it succeeded without this yesterday where the same python 3.12.3 was used.. 

Otherwise (cd .. && ./bin/npm install) failed as ModuleNotFoundError: No module named 'distutils'.

My default python3 is brew-installed one.

% python3 --version                        
Python 3.12.3
% which python3    
/opt/homebrew/bin/python3