I didn't find any information on net about running Mathematica on Docker.
Is that possible? How to handler license? Someone here has succeed in do that?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityI didn't find any information on net about running Mathematica on Docker.
Is that possible? How to handler license? Someone here has succeed in do that?
After the release of wolfram engine I thought it is a good time to revisit this old answer and refine it a bit.
First install docker on your machine. Follow docker setup from old answer.
Create a file named Dockerfile
with following content.
FROM ubuntu
LABEL version = "1.0"
LABEL description = "Docker image for the Wolfram Engine"
ENV DEBIAN_FRONTEND noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN true
RUN apt update -yq \
&& apt-get install -yq curl gcc tzdata musl-dev python3-dev python3-pip clang \
&& dpkg-reconfigure tzdata \
&& apt-get install -y avahi-daemon wget sshpass sudo locales \
locales-all ssh nano expect libfontconfig1 libgl1-mesa-glx libasound2 \
build-essential mosquitto mosquitto-clients libnss-mdns mdns-scan nodejs \
&& apt-get clean \
&& apt-get autoremove -y
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
RUN wget https://account.wolfram.com/download/public/wolfram-engine/desktop/LINUX \
&& sudo bash LINUX -- -auto -verbose && rm LINUX
CMD ["/usr/bin/wolframscript"]
If you are installing full Mathematica just replace in the last line wolframscript
with wolfram
. Also in case of full Mathematica you can downlaod the large installer and have a COPY
command to link your Matheamtica .sh
installer in the dockerfile in place of the RUN wget ...
part. Rest all remains same.
Go to the directory where you saved the above Dockerfile
and use it to build the wolfram engine docker image. All necessary requirements are included (nodejs and python3, mqtt) along with base image Ubuntu.
Remove packages from dockerfile if not needed. Replace your_name
with whatever you prefer.
docker build -t your_name/mmadocker .
After this we can use the docker image later on.
docker run -it your_name/mmadocker
On the first run the user will need to login and get the free wolfram engine activated. Copy the license info from the container shell.
$PasswordFile // FilePrint
Now save the above data visible in console output in a file named mathpass
which should be located in the host system so that we can access it later via docker volume option. We need to do this as docker run
are forgetful.
Once we have a the mathpass
file in host system (say in the folder named host_system_folder
) we can always run it as follows.
docker run -it -v /host_system_folder:/root/.WolframEngine/Licensing your_name/mmadocker
Can be still valid. However check the updated Dockerfile
based solution above. It uses the new Wolfram Engine.
In case you have docker in your system you can just pull the base image from here and jump to section (Install Wolfram on the base image). To keep things self contained, in the following I build the base image from scratch and install docker on Linux.
apt
package index:sudo apt-get update
apt
to use a repository over HTTPS:sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Add The Docker Repository
For latest Ubuntu LTS 18.04 there was no stable version. Create a new file for the Docker repository at /etc/apt/sources.list.d/docker.list
. In that file, place one of the following lines choosing either stable, nightly or edge builds:
STABLE (NOT YET AVAILABLE!), please check availability before using:
deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable
EDGE:
deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic edge
NIGHTLY:
deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic nightly
Install Docker CE
You can simply install the Docker CE package.
sudo apt install docker-ce
Done. Check for docker version:
docker --version
Docker version 18.03.0-ce, build 0520e24
To create the docker
group and add your user:
docker
group.sudo groupadd docker
docker
group.sudo usermod -a -G docker $USER
Log out and log back in so that your group membership is re-evaluated.
If testing on a virtual machine, it may be necessary to restart the virtual machine for changes to take effect. Now we do a docker pull
of this image here. It comes with ssh installed and latest Ubuntu 18.04. Check the run example and log into docker console.
Once inside the docker console, now we install some necessary packages to make the wolfram base image. Also to directly run a command over ssh
one can use sshpass
.
apt-get -y install \
build-essential \
mosquitto \
mosquitto-clients \
avahi-daemon \
avahi-discover \
avahi-utils \
libnss-mdns \
mdns-scan \
sshpass
Install Node.js and pip3
for Python 3.6.5 inf you want the ExternalEvaluate
to work in Wolfram Mathematica 11.3.0.
curl -sL https://deb.nodesource.com/setup_10.x | bash -
You can successfully add Node.js PPA to Ubuntu system. Now execute the below command install Node on and Ubuntu using apt-get.
apt-get install nodejs
apt-get install python3-pip
Activate avahi-daemon
systemctl enable avahi-daemon
.
Now exit
from bash and commit the image and name it wolfram-base
docker commit f750854c1c60 wolfram-base
Run it with a host directory /host/directory/installer
mounted where the Mathematica installation file (Mathematica_11.3.0_LINUX.sh
) is. The installer now will be available in the mounted directory /mma
inside the docker container:
docker run -d -P -v "/host/directory/installer:/mma" wolfram-base
Now we should check the container ID (6daa3df35b93
) and go to Ubuntu bash
and install Mathematica inside the container.
$ docker ps
$ docker exec -it 6daa3df35b93 bash
$ cd /mma
$ bash ./Mathematica_11.3.0_LINUX.sh
Register Node.js and Python tag and commit docker image
If the Node.js and Python binding needs to be installed by default we can register them at this stage. Our base image was made to support this feature. Type wolfram
in the terminal and evaluate the following and quit wolfram.
FindExternalEvaluators["NodeJS"]
FindExternalEvaluators["Python"]
We should now exit
from the bash and do a docker commit
to save the state of the image.
$ docker commit 6daa3df35b93 wolfram-docker-11.3.0
At this point we will have these images.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wolfram-docker-11.3.0 latest 6daa3df35b93 2 minutes ago 10.9GB
wolfram-base latest dcd0a3d55be0 About an hour ago 685MB
rastasheep/ubuntu-sshd 18.04 08f01ce8fd9f 15 hours ago 234MB
Now just login( assuming userid
) to docker and tag your image and push it to the docker hub.
$ docker tag wolfram-docker-11.3.0:latest userid/wolfram-docker-11.3.0
$ docker push userid/wolfram-docker-11.3.0
Once the image is ready we should now tag it and push to docker hub. Docker may ask you to login if you have not already. The image is 11 GB and it can take time to upload to docker hub.
$ docker tag wolfram-docker-11.3.0:latest userid/wolfram-docker-11.3.0
$ docker push userid/wolfram-docker-11.3.0:latest
Now you can pull this docker image and run on may machine that has docker.
We can run now our docker container in a detached mode. Use docker ps
to note the container id. Note that we are mounting the host /home
directory as /mma
inside our docker. We will host networking here.
$ docker run -dti -P --network host -v "/home:/mma" wolfram-docker-11.3.0:latest bash
Now time to login to the console of the docker container.
$ docker exec -ti 602c2dbd8dce bash
Write some Wolfram language code.
To test the Python external connection a bit of code from doc section.
script=FileNameJoin[{$TemporaryDirectory,"functions.py"}];
Export[script,"def stringreverse(s):
return s[::-1]
def stringallcaps(s):
return s.upper()
","Text"];
session=StartExternalSession["Python"];
ExternalEvaluate[session,File[script]];
To test the Node.js connection a bit of code from doc section. Starting a server on port 8070.
webServerSession=StartExternalSession["NodeJS"->"String"];
ExternalEvaluate[webServerSession,"var http = require('http'); var url = require('url');"];
ExternalEvaluate[webServerSession,"var res = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Date from Node.js server on 8070 inside docker: '+url.parse(req.url,true).query.time);
}).listen(8070);"];
Now a small greetings service using the new SocketListen
functionality of 11.3.
image=ImageCollage[{Import["https://i.stack.imgur.com/EhQlR.png"],GeoImage[Here,"StreetMap"]}];
listener=SocketListen[8080,Function[{assoc},
With[{client=assoc["SourceSocket"]},
WriteString[client,
ExportString[
HTTPResponse@
TemplateApply[XMLTemplate["<h1><wolfram:slot id=1/></h1><wolfram:slot id=2/><h5><wolfram:slot id=3/></h5><h5><wolfram:slot id=4/></h5><wolfram:slot id=5/>"],
{"A Docker Hello from the Wolfram Language \[HappySmiley]️\[HappySmiley]️\n",
"<body>Today's date is : "<>DateString[]<>"</body>"<>"<h2>You are here with docker! </h2>",
"Reverse capitalized date from python inside docker : "<>ExternalEvaluate[session,"stringallcaps(stringreverse('"<>DateString[]<>"'))"<>"\n"],
URLRead[URLBuild["localhost:8070",<|"time"->DateString[]|>],"Body"],
image }]
,
"HTTPResponse"
]
];
Close[client]
]
]
]
Save the above code in a file hello.wl
anywhere in your /home
folder as we have mounted it in our docker run
command.
Going back to the console of the docker we can cd
to the /mma
directory and navigate to the directory in the host where we have saved the above Mathematica code as hello.wl
. Now in the docker console we can run wolfram
and load the hello.wl
file.
<<hello.wl
Now just open http://127.0.0.1:8080 and you will be greeted with something cool ✊🏄 from your docker container. It is a web page served by the Wolfram Mathematica from within your docker container.
Formatting of this post might be a bit crazy as I wrote it in a .md file editor and pasted here.
MathLinkFactory.createKernelLink("-linkmode launch -linkname 'math -mathlink'")
running on the host system that docker runs on. In that cases a JAVA programs can communicate with the mma docker instance as it does on a local mma installation on the host. This is something I would love to explore. $\endgroup$ – PlatoManiac Feb 15 '17 at 19:06