How to Run R Scripts on Servers Without X11

How to run R scripts on servers without X11

I answered this once before -- can cannot make a program which expects X11 to certainly forget about it, but you can use the virtual framebuffer to 'pretend' X11 is present.

So see this older SO question for details and an example.

How to run R on a server without X11, and avoid broken dependencies

Use the virtual framebuffer X11 server -- we do the same to build packages requiring X11 for R builds in headless chroots. Taking e.g. pars of the Build-Depends from rggobi:

xvfb xauth xfonts-base

After installing these you can use the xvfb-run command. If you start R via e.g.

xvfb-run R --no-save

you should now be able to use routines and commands requiring X11 as e.g. some of the plotting devices, or the tcl/tk initialization which also insists on having X11.

The same trick is useful for web servers.

Compile R with Cairo support without X11

In the most narrow sense, Cairo appears to require x11 headers.

In a wider sense, look into the various answers detailing use of the xvfb virtual x11 server -- they allow you headless use.

Also, you could try building without x11, png, cairo -- and then use one of the two cairo packages from CRAN to create graphs. In Debian/Ubuntu we also have at least the cairoDevice package pre-build for you.

How to recover X11 connection without exiting R on remote server

For anyone bumping into this post, I ended up finding a super simple solution: you just need to start a new ssh -Y connection in parallel of your current session. Then you can redirect the DISPLAY parameter in the current session to the value in the new connection.

Here is a more detailed example.
In the current session (before starting the new ssh connection), if you try in R terminal :

> capabilites()             # returns X11 = FALSE 
> Sys.getenv('DISPLAY') # returns localhost:xx.0
localhost:12.0
> x11('localhost:12.0') # returns error message

Now you start the new ssh connection in parallel: ssh -Y login@remote.server. You need to find the value of DISPLAY in this new session, eg:

In bash:

$ echo $DISPLAY
localhost:13.0

Or in R:

> Sys.getenv('DISPLAY')
localhost:13.0

Finally, in the original R terminal, set the DISPLAY parameter to the new connection value:

> Sys.setenv('DISPLAY' = 'localhost:13.0')
> x11('localhost:13.0') # or x11() - both should work

There is also another option, is to modify the value of ForwardX11Timeout in ssh config file (~/.ssh/config). It is usually set to ~20 min by default (see man ssh). You can try set this to one day (or more), eg: ForwardX11Timeout 1d. This will prevent X11 to stop during any work session if it's opened less than 24 hours. You can even set ForwardX11Trusted yes in this config file. However, these options can lead to security leaks, so they need to be considered with care.

Alias function name in .Rprofile so that it is used by all R Scripts

Add a message statement so when R starts we can verify that the .Rprofile did, in fact, run. Also use library instead of require because library will give an error right at that point if it fails making it easier to debug. Then instead of putting png in the global environment insert it into the grDevices namespace. To do that it must be unlocked first.

# This code goes in .Rprofile file
message("Hello")
library("Cairo")
unlockBinding("png", asNamespace("grDevices"))
utils::assignInNamespace("png", CairoPNG, "grDevices")

For a different approach check out:

How to run R on a server without X11, and avoid broken dependencies

R unable to start device PNG - capabilities() has TRUE for PNG?

In case anyone ever finds this on google, the solution is

png("abc", type="cairo")


Related Topics



Leave a reply



Submit