Running Mathematica on Docker
Updated answer with Dockerfile
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.
Dockerfile
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"]
Note:
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.
Build the base image
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.
Run first time and persist license
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.
- Copy License Info by typing this on the activation dialog
$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.
Run later
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
Old answer
Can be still valid. However check the updated Dockerfile
based solution above. It uses the new Wolfram Engine.
Dockerizing Wolfram Mathematica
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.
Set up Docker in your system
- Update the
apt
package index:
sudo apt-get update
- Install packages to allow
apt
to use a repository over HTTPS:
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
- Add Docker’s official GPG key:
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
Create a base image for Wolfram
To create the docker
group and add your user:
- Create the
docker
group.
sudo groupadd docker
- Add your user to the
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 usesshpass
.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 theExternalEvaluate
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
Install Wolfram on the base image
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
Push your image to docker hub
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.
Test it!
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 ourdocker 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 ashello.wl
. Now in the docker console we can runwolfram
and load thehello.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.
Final outcome!
Formatting of this post might be a bit crazy as I wrote it in a .md file editor and pasted here.
I created public resources to simplify and automate PlatoManiac's answer for you and all of us:
TLDR
- https://account.wolfram.com/access/wolfram-engine/free?operatingSystem=LINUX
echo -n $'[email protected]\nYOUR-WOLFRAM-ID-PASSWORD-HERE\n' | sudo docker run --name my-wolfram-engine-container -i wolframlanguagefan/wolfram-engine-desktop-linux:latest
sudo docker commit my-wolfram-engine-container my-wolfram-engine-image
sudo docker run --rm -ti my-wolfram-engine-image
1. Create a Wolfram ID and Get a License
Visit
- https://account.wolfram.com/access/wolfram-engine/free?operatingSystem=LINUX
- OR https://www.wolfram.com/engine/ and press Linux, cancel the download and press "Get your license"
and create or/and log in (with) your Wolfram Account/Wolfram ID.
Press "Get license". You should see
Your license has been created.
Your account can now be used to activate wolfram-engine. No license file or key needs to be downloaded. The license is linked to your account.
License Note from Wolfram Research, Inc.:
The Free Wolfram Engine for Developers is available for non-production software development.
2. Build my-wolfram-engine-image
, activated with your Wolfram ID
Fill in the placeholders [email protected]
and YOUR-WOLFRAM-ID-PASSWORD-HERE
:
echo -n $'[email protected]\nYOUR-WOLFRAM-ID-PASSWORD-HERE\n' | sudo docker run --name my-wolfram-engine-container -i wolframlanguagefan/wolfram-engine-desktop-linux:latest
sudo docker commit my-wolfram-engine-container my-wolfram-engine-image
it should say
Wolfram Engine activated. See https://www.wolfram.com/wolframscript/ for more information.
3. Run
From now on, you can run an interactive session of your registered & activated wolfram-engine container with
sudo docker run --rm -ti my-wolfram-engine-image
example session:
Wolfram Language 12.2.0 Engine for Linux x86 (64-bit)
Copyright 1988-2021 Wolfram Research, Inc.
In[1]:= Solve[a*x^2 + b*x + c == 0, x] //InputForm
Out[1]//InputForm= {{x -> (-b - Sqrt[b^2 - 4*a*c])/(2*a)}, {x -> (-b + Sqrt[b^2 - 4*a*c])/(2*a)}}
PS
This method does not require you to manually/interactively enter anything, or run commands like $PasswordFile // FilePrint
and mount /root/.WolframEngine/Licensing/mathpass
, so it is probably more suitable for use in automated workflows on remote machines (where allowed by the license).
See:
- https://hub.docker.com/r/wolframlanguagefan/wolfram-engine-desktop-linux
- https://github.com/wolframlanguagefan/wolfram-engine-desktop-linux
- https://mathematica.stackexchange.com/a/173662/76995
- https://support.wolfram.com/46072