2016-03-19

GNU Octave via Docker & X11

GNU Octave can be run on OS X, Windows, or Linux via Docker and X11. X11 provides a better local development experience than sending it through VNC in my opinion. We'll use the octave-x11-novnc-docker, but skip VNC and use X11 directly based on info gathered from this issue. I'm on a Mac, so I'll be documenting how to make this work with XQuartz, an X11 display server for OS X. On Windows, Xming is reported to work.

Skipping to the end, here are the commands I can run on my iMac to launch Octave and display a parallel coordinate plot from these examples. I'll explain the setup details in the sections that follow.

open -a XQuartz

$ xhost + $(docker-machine ip)

$ ip=$(ifconfig vnic0 | grep inet | awk '$1=="inet" {print $2}')

$ git clone https://github.com/VictoriaLynn/plotting-examples.git

$ docker run --rm -t -e DISPLAY=$ip:0 -v $PWD/plotting-examples:/scripts/plotting-examples epflsti/octave-x11-novnc-docker:latest octave

>> cd /scripts/plotting-examples/parallel_coordinate

>> parallel_coordinate


Docker Machine

Before you can run `docker`, you need to create a virtual machine that will host docker. The easiest way to setup the VM is to install Docker Toolbox and use `docker-machine`. Docker Toolbox comes with VirtualBox, but it also supports many other drivers. I have Parallels Desktop Pro, so I installed the driver for it. I removed the default VM setup for VirtualBox and replaced it with a beefier VM. The 50 GB is just the limit I set for the expanding disk. It doesn't allocate the space upfront.

$ docker-machine rm default

$ docker-machine create --driver=parallels --parallels-cpu-count 2 --parallels-memory 2048 --parallels-disk-size 51200 default

$ docker-machine ls



Now that the VM is created, you set environment variables so that `docker` knows to use it as its host. Running `docker-machine env default` will print the env vars that need to be set as well as how to set them for your environment. On OS X, the command to set them is simply `eval $(docker-machine env default)`. After that is set, we can check our setup by running `docker info`.

$ docker-machine env default

$ eval $(docker-machine env default)

$ docker info



X11 Display Server: XQuartz

The usual X11 display server to use on a Mac is XQuartz. You can download the installer from their website or install it with Homebrew by doing `brew cask install xquartz`. When `octave` is started, it will use the `DISPLAY` environment variable to send the GUI windows to that display server. We want it to send the windows to XQuartz, so we need to allow connections to XQuartz from network clients, allow connection to XQuartz from the docker VM, and determine the IP address of the host.

In XQuartz preferences, select the second checkbox of `Allow connection from network clients. This makes it so that it listens on TCP port 6000. That is the TCP port for display port 0, just like TCP port 6001 is for display port 1, and so on. You can see that it is listening on that port by running `lsof -i :6000`.





You use `xhost` to allow connection from other IPs. By default nothing is enabled, and you can enable everything with `xhost +`, but to enable just the IP for the default VM, we can do `xhost + $(docker-machine ip)`.





To determine the IP address I used a Parallels utility `prlsrvctl` to determine that the `vnic0` network interface that was being used and then did a little shell scripting to get just the IP address.


Run Octave via Docker

$ docker run --rm -t -e DISPLAY=$ip:0 -v $PWD/plotting-examples:/scripts/plotting-examples epflsti/octave-x11-novnc-docker:latest octave

`--rm` is passed in so that the new container is removed after each run. Every run of docker will create a new container otherwise.

`-t` means to allocate a pseudo-TTY. The output from the running Octave will be displayed in Terminal. Octave wouldn't start without this.

`-e DISPLAY=$ip:0` The environment variable `DISPLAY` is set to the host IP address and display port 0 or TCP port 6000.

`-v $PWD/plotting-examples:/scripts/plotting-examples` mounts a directory from the host computer to the mount point in the running docker image so that it accessible from Octave. Multiple volumes can be mounted.

`epflsti/octave-x11-novnc-docker:latest` specifies the docker image to get. Since no docker repository is specified, it default to pulling the image from the Docker Hub here.

`octave` is the command to run in the docker container to start Octave.