Docker-ized version of MaximaPool.
The MaximaPool creates a pool of maxima processes. This has a number of advantages on large production sites, including the ability to put maxima processes on a separate server, or servers. Also, pooling helps starting up maxima processes so that STACK does not need to wait for them, this may save over 250ms each time you have to call maxima.
STACK-maxima in this image is highly optimized. Before using the pool, one shell call to Maxima took around 4s, now it's at about 100ms, or 200ms with request overhead.
- Code on GitHub (Issues)
- Image on Docker Hub
- Author: Dockerization: Abt. Anwendungssysteme, ITZ Uni Halle; Image includes various open source software. See Dockerfile for details.
- Support: As a university or research facility you might be successful in requesting support through the ITZ Helpdesk (this can take some time) or contacting the author directly. For any other entity, including companies, see my home page for contact details and pricing. You may request hosting, support or customizations. Reporting issues and creating pull requests is always welcome and appreciated.
We are likely transitioning to the more efficient goemaxima by GWDG. We assume GWDG, as a multi educational institution service provider, will be able to provide long-term support with their permanent employees. This project will then be archived and won't receive further updates.
There are multiple versions/ tags available under dockerhub:unihalle/maximapool/tags/.
Tag | STACK version | OS/Tomcat/JRE | Maxima version | assStackQuestion | ILIAS | moodle-qtype_stack |
---|---|---|---|---|---|---|
latest |
2020101501 | debian 9.9/9/11 | 5.41.0-Linux | 4.3.7 | ||
stack-2020101501 |
2020101501 | debian 9.9/9/11 | 5.41.0-Linux | 4.3.7 | ||
stack-2020070100 |
2020070100 | debian 9.9/9/11 | 5.41.0-Linux | 4.3.4 | ||
stack-2020042000 |
2020042000 | debian 9.9/9/11 | 5.41.0-Linux | 4.3.1 | ||
stack-2019090200 |
2019090200 | debian sid/9/11 | 5.41.0-Linux | 4.2.2a | ||
stack-2018080600 |
2018080600 | debian sid/9/11 | 5.41.0-Linux | 4.2.1 | ||
stack-2018030500 |
2018030500 | debian sid/9/11 | 5.41.0-Linux | 4.1+ (9bf7a7f) | ||
stack-2017121800 |
2017121800 | debian sid/9/10 | 5.41.0-Linux | 12439ff | 5.3 | 4.1 |
stack-2014083000 |
2014083000 | debian sid/9/9 | 5.41.0-Linux | c23c787 / 9a42ef8 with patch | 5.0-5.1 / 5.2 | 3.3 |
ILIAS (assStackQuestion)
Run $(grep stackmaximaversion ${ILIAS_PLUGIN_STACK}/classes/stack/maxima/stackmaxima.mac | grep -oP "\d+")
with ${ILIAS_PLUGIN_STACK}
being an absolute or relative path to the assStackQuestion plugin directory.
Moodle (moodle-qtype_stack)
Run $(grep stackmaximaversion $MOODLE/question/type/stack/stack/maxima/stackmaxima.mac | grep -oP "\d+")
with $MOODLE
being the root directory of the moodle site on the server.
- Do not allow direct access from any untrusted users to services/containers created from this image. You may reverse proxy requests through HTTP (basic) auth. Example below.
- There might be trouble running with containers created from this image when
aufs
is docker's storage driver. You can check withdocker info
for your storage driver in use. For Debian and Ubuntu, as of 2018, we recommend overlay2 instead.
Create the following files:
volumes/pool.conf
(Please adjust the values as to meet your requirements and make sure the file is readeable by everyone [chmod o+r].):
# Configuration for maxima pool
# Times in milliseconds
# Size limits
size.min = 5
size.max = 15
# This is the limit of simultaneously starting processes this combined to the update frequency defines the maximum load
start.limit = 4
# Pool update cycle (ms between updates)
update.cycle = 500
# How big a data-set should be kept for estimates, do not make this too big if the usage is not nearly constant.
adaptation.averages.length = 5
# Pool size depends on the demand and startuptimes the system tries to maintain the minimum size but as demand may vary one should use a multiplier to play it safe.
adaptation.safety.multiplier = 3.0
.env
:
MAXIMAPOOL_ADMIN_PASSWORD=PUT A STRONG SECRET PASSWORD HERE!
docker run -d \
--name TestMaximaPool \
-e "MAXIMAPOOL_ADMIN_PASSWORD=PUT A STRONG SECRET PASSWORD HERE!" \
-p "8765:8080" \
-v "/path/to/volumes/pool.conf:/opt/maximapool/pool.conf:ro" \
unihalle/maximapool
You can now visit your pool at http://host:8765/MaximaPool/MaximaPool
Minimal example (binds port 8765 to localhost):
docker-compose.yaml
:
version: "2"
services:
maximal-pool:
image: unihalle/maximapool:stack-2017121800
restart: always
environment:
- MAXIMAPOOL_ADMIN_PASSWORD
ports:
- "127.0.0.1:8765:8080"
volumes:
- "./volumes/pool.conf:/opt/maximapool/pool.conf:ro"
You can now look at your pool at http://127.0.0.1:8765/MaximaPool/MaximaPool
Inside the docker-compose network, the URL is http://maximal-pool:8080/MaximaPool/MaximaPool
.
This is a complete example illustrating the use with a reverse proxy providing HTTP password authentication and encryption inside a network managed by docker-compose. Please replace $VIRTUAL_HOST
with an actual host name.
The disadvantage of HTTP basic auth is that the password is hashed on every request. If you choose more heavy hashing (>8) you are likely to slow down your web proxy.
# Create the pool.conf and .env as described in the minimal examples
# Create an htpasswd file (requires apache-utils installed)
mkdir -p passwords && htpasswd -cBC 8 passwords/$VIRTUAL_HOST ${USER}
# Alternatively use: docker run --rm httpd htpasswd -nbB ${USER} ${PASSWORD} > passwords/$VIRTUAL_HOST
# Add certificates so they can be read by the reverse proxy
mkdir -p certs && cp VIRTUAL_HOST.crt certs/ && cp VIRTUAL_HOST.key certs/
docker-compose.yaml
:
version: "2"
services:
maximal-pool:
image: unihalle/maximapool:stack-2018030500
restart: always
environment:
- MAXIMAPOOL_ADMIN_PASSWORD
- VIRTUAL_HOST=$VIRTUAL_HOST
- VIRTUAL_PORT=8080
volumes:
- "./volumes/pool.conf:/opt/maximapool/pool.conf:ro"
- "./volumes/logs/tomcat:/usr/local/tomcat/logs"
- "/etc/localtime:/etc/localtime:ro"
reverse-proxy:
image: jwilder/nginx-proxy:alpine
environment:
- DEFAULT_HOST=$VIRTUAL_HOST
ports:
- "8065:80"
- "8765:443"
restart: always
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs:/etc/nginx/certs:ro
- ./passwords:/etc/nginx/htpasswd:ro
Finally bring it up and watch the logs:
docker-compose up -d && docker-compose logs -f
You can now look at your pool at https://$VIRTUAL_HOST:8765/MaximaPool/MaximaPool after you were prompted for your password if you have configured everything correctly.
Hit Ctrl
+C
to detach from container output (logs). Tomcat's logs will be stored to ./volumes/logs/tomcat
. To control what is logged, override /usr/local/tomcat/conf/server.xml
(AccessLogValve) - mount a file or directory to that place, or override using a Dockerfile.
It is possible running this container with multiple versions of STACK or having multiple pools: Mount a volume with proper contents and permissions to /opt/maximapool/%%VERSION%%/
. You might use the container itself to generate your custom STACK-maxima pool. Toolchain, lisp and maxima are already installed.
It is also possible to build image for use with specific version of Moodle Question Type STACK plugin. Make sure that assets/moodle-qtype_stack
submodule is tracking commit that is matching the version of qtype_stack
plugin you have installed in Moodle, then build the image with --build-arg BUILD_FOR_MOODLE=1
parameter.
On the Moodle side, STACK configuration is located at Site Administration -> Plugins -> Question Type -> STACK plugin settings. To make it worh with MaximaPool Docker container, you need to set:
- Platform type: Server
- Maxima version: choose one matching the image in use (e.g. 5.41.0)
- Maxima command:
maxima-pool:8080/MaximaPool/MaximaPool
maxima-pool
is the hostname of Maxima container, it should be accessible by Moodle webserver.
- Advice on writing docker files.
- Releasing a new version:
- Release it to a new branch.
- Update this README.md's compatibility matrix.
- Generate a new
/data_dir/xqcas/stack/maximalocal.mac
through plugin update and re-configuration. - Update assets/maximalocal.mac.template and assets/optimize.mac with generated values from
/data_dir/xqcas/stack/maximalocal.mac
[ILIAS] or$MOODLEDATA/stack/**/maximalocal.mac
[Moodle].
- Moodle stackmaxima.mac: Last line
- ILIAS stackmaxima.mac: Last line
- Moodle:
cd assets/moodle-qtype_stack && git checkout [ref] && cd ../.. && git add assets/moodle-qtype_stack && git commit -m "Update to STACK [stackversion]"
Impacts moodle-qtype_stack [cd assets/moodle-qtype_stack && git log
] version. - ILIAS:
cd assets/assStackQuestion && git checkout [ref] && cd ../.. && git add assets/assStackQuestion && git commit -m "Update to STACK [stackversion]"
Impacts assStackQuestion [cd assets/assStackQuestion && git log
] and possibly ILIAS version. assStackQuestion has branches likemaster-ilias53
docker-compose exec [maximapool] bash -c 'cat /etc/debian_version'
- Look up in Wikipedia
- Depends on the base image used for Tomcat/JDK
- See Dockerfile first line.
- See Dockerfile and grep for "Maxima-Linux".
- assets/optimize.mac
- Watch for This variable controls which optional packages are supported by STACK.
- Moodle stack/cas/installhelper.class.php#L32
- ILIAS classes/stack/cas/installhelper.class.php#L37
- and ensure all these packages are loaded
- it's easier to look into an LMS generated stackmaxima.mac file.
- assets/maximalocal.mac.template
- Moodle stack/maxima/sandbox.wxm - only as a hint - you should really look into an LMS generated stackmaxima.mac file.
- ILIAS classes/stack/maxima/sandbox.wxm - only as a hint - you should really look into an LMS generated stackmaxima.mac file.
git clone --recurse-submodules -j4 git@github.com:uni-halle/maximapool-docker.git # you can omit the -j4 option if this causes issues
cd maximapool-docker
docker build . # or docker-compose build; you can ignore the warning about undefined environment variables
- Q: build.xml does not exist.
- A: Please make sure to clone and initialize the submodules as well:
git clone --recurse-submodules -j4 git@github.com:uni-halle/maximapool-docker.git
or, if you already cloned, change directory into the cloned git repo and fetch the submodulescd maximapool-docker && git submodule update --init --recursive
- A: Please make sure to clone and initialize the submodules as well: