Skip to content

Commit 9a36279

Browse files
epaganonggriffithsuk
authored andcommitted
Update non-interactive Dockerfile to use xvfb-run as the entrypoint
1 parent fb48cc7 commit 9a36279

File tree

8 files changed

+107
-15
lines changed

8 files changed

+107
-15
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ This repository shows you how to build and customize a Docker® container for
44

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

7-
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).
7+
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).
8+
9+
For alternative resources, see the [**alternates folder**](alternates) that contains the following Dockerfiles:
10+
11+
* 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`.
12+
* 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.
13+
* 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.
14+
* 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.
15+
16+
For more Docker related resources, see [More MATLAB Docker Resources](#more-matlab-docker-resources).
817

918
### Requirements
1019
* [A Running Network License Manager for MATLAB](https://www.mathworks.com/help/install/administer-network-licenses.html)
@@ -176,14 +185,6 @@ To learn more, see the documentation: [Commonly Used Startup Options](https://ww
176185
* Explore prebuilt MATLAB Docker Containers on Docker Hub: https://hub.docker.com/r/mathworks
177186
* [MATLAB Containers on Docker Hub](https://hub.docker.com/r/mathworks/matlab) hosts container images for multiple releases of MATLAB.
178187
* [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.
179-
180-
* This Dockerfile builds on the matlab-deps container image and installs MATLAB. For other possibilities,
181-
see the examples in the [**alternates folder**](alternates) of this repository:
182-
* [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.
183-
* [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.
184-
* [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.
185-
* [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.
186-
187188
* Enable additional capabilities using the [MATLAB Dependencies repository](https://github.com/mathworks-ref-arch/container-images/tree/master/matlab-deps).
188189
For some workflows and toolboxes, you must specify dependencies. You must do this if you want to do any of the following tasks:
189190
* Install extended localization support for MATLAB.

alternates/non-interactive/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \
3434
&& apt-get install --no-install-recommends --yes \
3535
wget \
3636
ca-certificates \
37+
xvfb \
3738
&& apt-get clean \
3839
&& apt-get autoremove \
3940
&& rm -rf /var/lib/apt/lists/*
@@ -72,3 +73,6 @@ RUN wget -q https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/glnxa64/ma
7273
# To learn more, see the Help Make MATLAB Even Better section in the accompanying README:
7374
# https://github.com/mathworks-ref-arch/matlab-dockerfile#help-make-matlab-even-better
7475
ENV MW_DDUX_FORCE_ENABLE=true MW_CONTEXT_TAGS=MATLAB:BATCHLICENSING:DOCKERFILE:V1
76+
77+
ENTRYPOINT ["xvfb-run"]
78+
CMD ["/bin/bash"]

tests/alternates/matlab-installer/test_mock_matlab_container.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
################################################################################
1919

2020

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

2424
@classmethod
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
workDir = setupExample(findExample('matlab/WriteATestForAnAppExample'));
2+
cd(workDir)
3+
assertSuccess(runtests("ConfigurePlotAppExampleTest"))

tests/alternates/non-interactive/test_matlabbatch.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
################################################################################
1414

1515

16-
class TestMatlabBatch(base.TestCase):
16+
class TestMATLABBatch(base.TestCase):
1717
"""Extend the test methods of the base TestCase class."""
1818

1919
@classmethod
@@ -25,7 +25,7 @@ def setUpClass(cls):
2525
image=image_name,
2626
detach=True,
2727
stdin_open=True,
28-
environment = {"MLM_LICENSE_TOKEN": os.getenv("BATCH_TOKEN")},
28+
environment={"MLM_LICENSE_TOKEN": os.getenv("BATCH_TOKEN")},
2929
)
3030
cls.expected_ddux_force_enable = "true"
3131
cls.expected_ddux_tags = [
@@ -46,13 +46,13 @@ def tearDownClass(cls):
4646

4747
def test_matlabbatch_runs(self):
4848
"""Test that matlab-batch runs successfully and that the matlab release is the correct one."""
49-
matlabbatch_cmd = 'matlab-batch "disp(version(\'-release\'))"'
49+
matlabbatch_cmd = "matlab-batch \"disp(version('-release'))\""
5050
cmd_output = self.host.run(matlabbatch_cmd)
5151
self.assertTrue(
5252
cmd_output.succeeded,
5353
f"Unable to run matlab-batch correctly: {cmd_output.stdout}",
5454
)
55-
expectedRelease=self.release_tag.strip().lstrip("Rr")
55+
expectedRelease = self.release_tag.strip().lstrip("Rr")
5656
self.assertRegex(cmd_output.stdout, expectedRelease)
5757

5858
def test_matlabbatch_version(self):
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Copyright 2024 The MathWorks, Inc.
2+
3+
"""
4+
Test class to validate the non-interactive dockerfile.
5+
6+
This test class will launch matlab-batch with a virtual display.
7+
"""
8+
9+
import unittest
10+
from utils import helpers
11+
import docker
12+
import os
13+
from pathlib import Path
14+
15+
16+
################################################################################
17+
class TestMATLABBatchDisplay(unittest.TestCase):
18+
"""Test that matlab-batch can run workflows requiring a virtual display"""
19+
20+
@classmethod
21+
def setUpClass(cls):
22+
"""Get the docker client and image to test"""
23+
cls.client = docker.from_env()
24+
cls.image_name = helpers.get_image_name()
25+
26+
@classmethod
27+
def tearDownClass(cls):
28+
"""Close the client"""
29+
cls.client.close()
30+
31+
############################################################################
32+
33+
@unittest.skipIf(
34+
helpers.get_release().lower() < "r2023b",
35+
"Release is too old. Only releases after r2023b are supported",
36+
)
37+
def test_display_workflow(self):
38+
"""
39+
Test that 'matlab -batch runDisplayTest' executes correctly.
40+
runDisplayTest will run some example tests that require a display.
41+
This is equivalent to running
42+
43+
docker run --init -it --rm -e MLM_LICENSE_TOKEN=... non-interactive:r2024a matlab-batch runDisplayTest
44+
"""
45+
cmd = "matlab-batch runDisplayTest"
46+
mtest_file_name = "runDisplayTest.m"
47+
timeout = 180
48+
49+
trg_mtest_file = f"/home/matlab/{mtest_file_name}"
50+
src_mtest_file = str(Path(__file__).parent.resolve() / mtest_file_name)
51+
test_mount = docker.types.Mount(
52+
target=trg_mtest_file,
53+
source=src_mtest_file,
54+
type="bind",
55+
)
56+
57+
self.container = self.client.containers.run(
58+
image=self.image_name,
59+
init=True,
60+
detach=True,
61+
stdin_open=True,
62+
environment={"MLM_LICENSE_TOKEN": os.getenv("BATCH_TOKEN")},
63+
mounts=[test_mount],
64+
command=cmd,
65+
)
66+
67+
self.addCleanup(lambda: self.container.remove(force=True))
68+
69+
result = self.container.wait(timeout=timeout)
70+
status_code = result.get("StatusCode")
71+
error = result.get("Error")
72+
logs = self.container.logs().strip().decode("utf-8")
73+
self.assertEqual(status_code, 0, logs)
74+
self.assertIsNone(error, logs)
75+
76+
77+
################################################################################
78+
79+
if __name__ == "__main__":
80+
unittest.main()

tests/test_running_matlab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
################################################################################
18-
class TestMatlab(unittest.TestCase):
18+
class TestMATLAB(unittest.TestCase):
1919
"""Test that MATLAB gets launched correctly"""
2020

2121
undesired_status = ["removing", "exited", "dead"]

tests/utils/helpers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ def get_release_from_string(string):
4545
return ""
4646

4747

48+
def get_release():
49+
return get_release_from_string(get_image_name())
50+
51+
4852
def get_release_tag(string):
4953
"""Get the docker tag from a string containing a release"""
5054
tag = get_release_from_string(string)

0 commit comments

Comments
 (0)