Skip to content

Commit

Permalink
Update non-interactive Dockerfile to use xvfb-run as the entrypoint
Browse files Browse the repository at this point in the history
  • Loading branch information
epaganon authored and ggriffithsuk committed Sep 4, 2024
1 parent fb48cc7 commit 9a36279
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 15 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ This repository shows you how to build and customize a Docker® container for

You can use this container image as a scalable and reproducible method to deploy and test your MATLAB code.

You can also download prebuilt images based on this Dockerfile from [here](https://github.com/mathworks-ref-arch/matlab-dockerfile/pkgs/container/matlab-dockerfile%2Fmatlab). For alternative resources, see [More MATLAB Docker Resources](#more-matlab-docker-resources).
Use the [Dockerfile](Dockerfile) in this top-level repository if you want a lightweight and simple way to create a MATLAB container image. You can also download prebuilt images based on this Dockerfile from [here](https://github.com/mathworks-ref-arch/matlab-dockerfile/pkgs/container/matlab-dockerfile%2Fmatlab).

For alternative resources, see the [**alternates folder**](alternates) that contains the following Dockerfiles:

* The Dockerfile in [matlab-installer](alternates/matlab-installer) uses the MATLAB installer rather than `mpm` to install MATLAB in the container. This allows you to install toolboxes that are not currently supported by mpm. Use this Dockerfile if you prefer using the MATLAB installer workflow, instead of `mpm`.
* The Dockerfile in [building-on-matlab-docker-image](alternates/building-on-matlab-docker-image) shows you how to build on top of the [MATLAB Container Image on Docker Hub](https://hub.docker.com/r/mathworks/matlab). Use this Dockerfile if you want to install extra toolboxes on top of the `mathworks/matlab` container image. This Dockerfile contains the features of the MATLAB image on Docker Hub, allowing you to access the dockerised MATLAB through a browser, batch mode, or an interactive command prompt.
* The Dockerfile in [non-interactive](alternates/non-interactive) allows you run MATLAB in non-interactive environments. This Dockerfile requires that you have a MATLAB batch licensing token to license MATLAB in the container. Use this Dockerfile in continuous integration and continuous delivery (CI/CD) pipelines or other automated environments where interactive licensing is not possible.
* The Dockerfile in [matlab-container-offline-install](alternates/matlab-container-offline-install/) shows you how to build and customize a Docker container for MATLAB and its toolboxes in an offline environment. Use this Dockerfile if you must build your container image in an offline environment.

For more Docker related resources, see [More MATLAB Docker Resources](#more-matlab-docker-resources).

### Requirements
* [A Running Network License Manager for MATLAB](https://www.mathworks.com/help/install/administer-network-licenses.html)
Expand Down Expand Up @@ -176,14 +185,6 @@ To learn more, see the documentation: [Commonly Used Startup Options](https://ww
* Explore prebuilt MATLAB Docker Containers on Docker Hub: https://hub.docker.com/r/mathworks
* [MATLAB Containers on Docker Hub](https://hub.docker.com/r/mathworks/matlab) hosts container images for multiple releases of MATLAB.
* [MATLAB Deep Learning Containers on Docker Hub](https://hub.docker.com/r/mathworks/matlab-deep-learning) hosts container images with toolboxes suitable for Deep Learning.
* This Dockerfile builds on the matlab-deps container image and installs MATLAB. For other possibilities,
see the examples in the [**alternates folder**](alternates) of this repository:
* [matlab-installer](alternates/matlab-installer) is an example of a Dockerfile that uses the matlab installer rather than mpm to install MATLAB in the container, allowing the installation of some toolboxes that are not currently supported by mpm.
* [building-on-matlab-docker-image](alternates/building-on-matlab-docker-image) is an example of a Dockerfile that builds on top of the [MATLAB Container Image on Docker Hub](https://hub.docker.com/r/mathworks/matlab), to install extra toolboxes.
* [non-interactive](alternates/non-interactive) is an example of a Dockerfile that licenses MATLAB using MATLAB batch licensing tokens, facilitating the execution of MATLAB in non-interactive environments.
* [matlab-container-offline-install](alternates/matlab-container-offline-install/) shows you how to build and customize a Docker container for MATLAB and its toolboxes in an offline environment.
* Enable additional capabilities using the [MATLAB Dependencies repository](https://github.com/mathworks-ref-arch/container-images/tree/master/matlab-deps).
For some workflows and toolboxes, you must specify dependencies. You must do this if you want to do any of the following tasks:
* Install extended localization support for MATLAB.
Expand Down
4 changes: 4 additions & 0 deletions alternates/non-interactive/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get install --no-install-recommends --yes \
wget \
ca-certificates \
xvfb \
&& apt-get clean \
&& apt-get autoremove \
&& rm -rf /var/lib/apt/lists/*
Expand Down Expand Up @@ -72,3 +73,6 @@ RUN wget -q https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/glnxa64/ma
# To learn more, see the Help Make MATLAB Even Better section in the accompanying README:
# https://github.com/mathworks-ref-arch/matlab-dockerfile#help-make-matlab-even-better
ENV MW_DDUX_FORCE_ENABLE=true MW_CONTEXT_TAGS=MATLAB:BATCHLICENSING:DOCKERFILE:V1

ENTRYPOINT ["xvfb-run"]
CMD ["/bin/bash"]
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
################################################################################


class TestMockMatlabContainer(base.TestCase):
class TestMockMATLABContainer(base.TestCase):
"""Test class to test the non-MATLAB related features of the Docker image"""

@classmethod
Expand Down
3 changes: 3 additions & 0 deletions tests/alternates/non-interactive/runDisplayTest.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
workDir = setupExample(findExample('matlab/WriteATestForAnAppExample'));
cd(workDir)
assertSuccess(runtests("ConfigurePlotAppExampleTest"))
8 changes: 4 additions & 4 deletions tests/alternates/non-interactive/test_matlabbatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
################################################################################


class TestMatlabBatch(base.TestCase):
class TestMATLABBatch(base.TestCase):
"""Extend the test methods of the base TestCase class."""

@classmethod
Expand All @@ -25,7 +25,7 @@ def setUpClass(cls):
image=image_name,
detach=True,
stdin_open=True,
environment = {"MLM_LICENSE_TOKEN": os.getenv("BATCH_TOKEN")},
environment={"MLM_LICENSE_TOKEN": os.getenv("BATCH_TOKEN")},
)
cls.expected_ddux_force_enable = "true"
cls.expected_ddux_tags = [
Expand All @@ -46,13 +46,13 @@ def tearDownClass(cls):

def test_matlabbatch_runs(self):
"""Test that matlab-batch runs successfully and that the matlab release is the correct one."""
matlabbatch_cmd = 'matlab-batch "disp(version(\'-release\'))"'
matlabbatch_cmd = "matlab-batch \"disp(version('-release'))\""
cmd_output = self.host.run(matlabbatch_cmd)
self.assertTrue(
cmd_output.succeeded,
f"Unable to run matlab-batch correctly: {cmd_output.stdout}",
)
expectedRelease=self.release_tag.strip().lstrip("Rr")
expectedRelease = self.release_tag.strip().lstrip("Rr")
self.assertRegex(cmd_output.stdout, expectedRelease)

def test_matlabbatch_version(self):
Expand Down
80 changes: 80 additions & 0 deletions tests/alternates/non-interactive/test_matlabbatch_display.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright 2024 The MathWorks, Inc.

"""
Test class to validate the non-interactive dockerfile.
This test class will launch matlab-batch with a virtual display.
"""

import unittest
from utils import helpers
import docker
import os
from pathlib import Path


################################################################################
class TestMATLABBatchDisplay(unittest.TestCase):
"""Test that matlab-batch can run workflows requiring a virtual display"""

@classmethod
def setUpClass(cls):
"""Get the docker client and image to test"""
cls.client = docker.from_env()
cls.image_name = helpers.get_image_name()

@classmethod
def tearDownClass(cls):
"""Close the client"""
cls.client.close()

############################################################################

@unittest.skipIf(
helpers.get_release().lower() < "r2023b",
"Release is too old. Only releases after r2023b are supported",
)
def test_display_workflow(self):
"""
Test that 'matlab -batch runDisplayTest' executes correctly.
runDisplayTest will run some example tests that require a display.
This is equivalent to running
docker run --init -it --rm -e MLM_LICENSE_TOKEN=... non-interactive:r2024a matlab-batch runDisplayTest
"""
cmd = "matlab-batch runDisplayTest"
mtest_file_name = "runDisplayTest.m"
timeout = 180

trg_mtest_file = f"/home/matlab/{mtest_file_name}"
src_mtest_file = str(Path(__file__).parent.resolve() / mtest_file_name)
test_mount = docker.types.Mount(
target=trg_mtest_file,
source=src_mtest_file,
type="bind",
)

self.container = self.client.containers.run(
image=self.image_name,
init=True,
detach=True,
stdin_open=True,
environment={"MLM_LICENSE_TOKEN": os.getenv("BATCH_TOKEN")},
mounts=[test_mount],
command=cmd,
)

self.addCleanup(lambda: self.container.remove(force=True))

result = self.container.wait(timeout=timeout)
status_code = result.get("StatusCode")
error = result.get("Error")
logs = self.container.logs().strip().decode("utf-8")
self.assertEqual(status_code, 0, logs)
self.assertIsNone(error, logs)


################################################################################

if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion tests/test_running_matlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


################################################################################
class TestMatlab(unittest.TestCase):
class TestMATLAB(unittest.TestCase):
"""Test that MATLAB gets launched correctly"""

undesired_status = ["removing", "exited", "dead"]
Expand Down
4 changes: 4 additions & 0 deletions tests/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def get_release_from_string(string):
return ""


def get_release():
return get_release_from_string(get_image_name())


def get_release_tag(string):
"""Get the docker tag from a string containing a release"""
tag = get_release_from_string(string)
Expand Down

0 comments on commit 9a36279

Please sign in to comment.