diff --git a/.github/workflows/README-from-matlab-docker.md b/.github/workflows/README-from-matlab-docker.md index 3521124..32657c0 100644 --- a/.github/workflows/README-from-matlab-docker.md +++ b/.github/workflows/README-from-matlab-docker.md @@ -8,7 +8,7 @@ The workflow in this folder builds and tests the Dockerfile found in `alternates The workflow is scheduled to run every Monday at 00:00. -Additionally, the workflow is triggered each time you push a change in the [`Dockerfile`](../../alternates/building-on-matlab-docker-image/Dockerfile) or in the [`tests` directory](../../tests/alternates/building-on-matlab-docker-image) to the repository. +Additionally, the workflow is triggered each time you push a change in the [`Dockerfile`](../../alternates/building-on-matlab-docker-image/Dockerfile) or in the [`tests` directory](../../tests) to the repository. You can also trigger the workflow from the "Actions" tab. @@ -17,13 +17,12 @@ You can also trigger the workflow from the "Actions" tab. This workflow consists of the following steps: 1. Check-out the repository into a GitHub Actions runner. -2. Install Python and the PyPi packages listed in [`requirements.txt`](../../tests/requirements.txt). -3. Run the [test file](../../tests/alternates/building-on-matlab-docker-image/test_build.py) to check the messages displayed during the build phase. -4. Build the image from the Dockerfile. -5. Run the other test files stored in [tests/alternates/matlab-installer](../../tests/alternates/matlab-installer). +2. Build the image from the Dockerfile. +3. Install Python and the PyPi packages listed in [`requirements.txt`](../../tests/requirements.txt). +4. Run the test files stored in [tests/alternates/building-on-matlab-docker-image](../../tests/alternates/building-on-matlab-docker-image). --- -Copyright 2023 The MathWorks, Inc. All rights reserved. +Copyright 2023-2024 The MathWorks, Inc. All rights reserved. --- diff --git a/.github/workflows/README-matlab-container-offline-install.md b/.github/workflows/README-matlab-container-offline-install.md new file mode 100644 index 0000000..8f2b1ab --- /dev/null +++ b/.github/workflows/README-matlab-container-offline-install.md @@ -0,0 +1,29 @@ +# Build and Test the alternates/matlab-container-offline-install/Dockerfile + +> This folder is intended only for the administrators of the matlab-dockerfile repository. + +The workflow in this folder builds and tests the Dockerfiles found in `alternates/matlab-container-offline-install`. + +## Triggers and Scheduled Jobs + +The workflow is scheduled to run every Monday at 00:00. + +Additionally, the workflow is triggered each time you push a change in the [`archive.Dockerfile`](../../alternates/matlab-container-offline-install/archive.Dockerfile), the [`Dockerfile`](../../alternates/matlab-container-offline-install/Dockerfile) or in the [`tests` directory](../../tests/) to the repository. + +You can also trigger the workflow from the "Actions" tab. + +## Workflow Description + +This workflow consists of the following steps: + +1. Check-out the repository into a GitHub Actions runner. +2. Build the archive image. +3. Build the product image, in an offline environment. +4. Install Python and the PyPi packages listed in [`requirements.txt`](../../tests/requirements.txt). +5. Run the test files stored in [tests/alternates/matlab-container-offline-install](../../tests/alternates/matlab-container-offline-install). + +--- + +Copyright 2024 The MathWorks, Inc. All rights reserved. + +--- diff --git a/.github/workflows/README-matlab-installer.md b/.github/workflows/README-matlab-installer.md index c87a512..bf97a01 100644 --- a/.github/workflows/README-matlab-installer.md +++ b/.github/workflows/README-matlab-installer.md @@ -8,7 +8,7 @@ The workflow in this folder builds and tests the Dockerfile found in `alternates The workflow is scheduled to run every Monday at 00:00. -Additionally, the workflow is triggered each time you push a change in the [`Dockerfile`](../../alternates/matlab-installer/Dockerfile) or in the [`tests` directory](../../tests/alternates/matlab-installer) to the repository. +Additionally, the workflow is triggered each time you push a change in the [`Dockerfile`](../../alternates/matlab-installer/Dockerfile) or in the [`tests` directory](../../tests) to the repository. You can also trigger the workflow from the "Actions" tab. @@ -25,6 +25,6 @@ This workflow consists of the following steps: --- -Copyright 2023 The MathWorks, Inc. All rights reserved. +Copyright 2023-2024 The MathWorks, Inc. All rights reserved. --- diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 09cadf1..402eb97 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -10,8 +10,9 @@ on: # Trigger the workflow is the Dockerfile or any file under tests/ is modified paths: - "Dockerfile" - - "tests/**" - - "!tests/**.md" + - "tests/*" + - "tests/utils/**" + - "!**.md" schedule: # Run at 00:00 on every Monday (1st Day of the Week) - cron: "0 0 * * 1" diff --git a/.github/workflows/from-matlab-docker-build-test.yml b/.github/workflows/from-matlab-docker-build-test.yml index c50761f..fe2b810 100644 --- a/.github/workflows/from-matlab-docker-build-test.yml +++ b/.github/workflows/from-matlab-docker-build-test.yml @@ -10,8 +10,9 @@ on: # Trigger the workflow when the Dockerfile or any file under tests/ is modified paths: - "alternates/building-on-matlab-docker-image/Dockerfile" - - "tests/**" - - "!tests/**.md" + - "tests/alternates/building-on-matlab-docker-image/*" + - "tests/utils/**" + - "!**.md" schedule: # Run at 00:00 on every Monday (1st Day of the Week) - cron: "0 0 * * 1" diff --git a/.github/workflows/matlab-container-offline-install-build-test.yml b/.github/workflows/matlab-container-offline-install-build-test.yml new file mode 100644 index 0000000..ba6e967 --- /dev/null +++ b/.github/workflows/matlab-container-offline-install-build-test.yml @@ -0,0 +1,92 @@ +# Copyright 2024 The MathWorks, Inc. + +name: Build and Test the "MATLAB Container Offline Install" Dockerfiles + +# Trigger this workflow either manually or when a new change is pushed to the +# repo (except .md files) +on: + workflow_dispatch: + push: + # Trigger the workflow when the Dockerfile or any file under tests/ is modified + paths: + - "alternates/matlab-container-offline-install/archive.Dockerfile" + - "alternates/matlab-container-offline-install/Dockerfile" + - "tests/alternates/matlab-container-offline-install/*" + - "tests/utils/**" + - "!**.md" + schedule: + # Run at 00:00 on every Monday (1st Day of the Week) + - cron: "0 0 * * 1" + +env: + ARCHIVE_BASE_NAME: mpm-archive + IMAGE_BASE_NAME: matlab + ALT_PATH: alternates/matlab-container-offline-install + MATLAB_PRODUCT_LIST: "MATLAB Symbolic_Math_Toolbox Deep_Learning_Toolbox_Model_for_ResNet-50_Network" + LICENSE_FILE_PATH: ${{ github.workspace }}/license.lic + +jobs: + build-test-image: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + matlab-release: [r2024a, r2023b, r2023a, r2022b, r2022a, r2021b, r2021a, r2020b] + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver: docker + + - name: Build archive image + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64 + context: ${{ env.ALT_PATH }} + file: ${{ env.ALT_PATH }}/archive.Dockerfile + load: true + build-args: | + MATLAB_RELEASE=${{ matrix.matlab-release }} + MATLAB_PRODUCT_LIST=${{ env.MATLAB_PRODUCT_LIST }} + tags: | + ${{ env.ARCHIVE_BASE_NAME }}:${{ matrix.matlab-release }} + + - name: Build final image offline + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64 + context: ${{ env.ALT_PATH }} + load: true + network: none + build-args: | + MATLAB_RELEASE=${{ matrix.matlab-release }} + MATLAB_PRODUCT_LIST=${{ env.MATLAB_PRODUCT_LIST }} + ARCHIVE_BASE_IMAGE=${{ env.ARCHIVE_BASE_NAME }}:${{ matrix.matlab-release }} + tags: | + ${{ env.IMAGE_BASE_NAME }}:${{ matrix.matlab-release }} + + - name: Set up Python 3 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install test dependencies + run: | + python -m pip install --upgrade pip + if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi + + + - name: Generate license file + run: echo '${{ secrets.MATLAB_LICENSE_FILE_R2024A }}' > ${{ env.LICENSE_FILE_PATH }} + + - name: Test container + working-directory: tests + env: + IMAGE_NAME: ${{ env.IMAGE_BASE_NAME }}:${{ matrix.matlab-release }} + run: | + python -m unittest ${{ env.ALT_PATH }}/test_container.py + python -m unittest ${{ env.ALT_PATH }}/test_installed_products.py diff --git a/.github/workflows/matlab-installer-build-test.yml b/.github/workflows/matlab-installer-build-test.yml index d31b99f..afca407 100644 --- a/.github/workflows/matlab-installer-build-test.yml +++ b/.github/workflows/matlab-installer-build-test.yml @@ -10,8 +10,9 @@ on: # Trigger the workflow when the Dockerfile or any file under tests/ is modified paths: - "alternates/matlab-installer/Dockerfile" - - "tests/**" - - "!tests/**.md" + - "tests/alternates/matlab-installer/*" + - "tests/utils/**" + - "!**.md" schedule: # Run at 00:00 on every Monday (1st Day of the Week) - cron: "0 0 * * 1" diff --git a/.github/workflows/non-interactive-build-test.yml b/.github/workflows/non-interactive-build-test.yml index 018449e..1e38b81 100644 --- a/.github/workflows/non-interactive-build-test.yml +++ b/.github/workflows/non-interactive-build-test.yml @@ -10,8 +10,9 @@ on: # Trigger the workflow when the Dockerfile or any file under tests/ is modified paths: - "alternates/non-interactive/Dockerfile" - - "tests/**" - - "!tests/**.md" + - "tests/alternates/non-interactive/*" + - "tests/utils/**" + - "!**.md" schedule: # Run at 00:00 on every Monday (1st Day of the Week) - cron: "0 0 * * 1" diff --git a/Dockerfile b/Dockerfile index 6afa518..d805989 100644 --- a/Dockerfile +++ b/Dockerfile @@ -62,7 +62,7 @@ RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ --destination=${MATLAB_INSTALL_LOCATION} \ --products ${MATLAB_PRODUCT_LIST} \ || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ - && sudo rm -rf mpm /tmp/mathworks_root.log ${HOME}/.MathWorks \ + && sudo rm -rf mpm /tmp/mathworks_root.log \ && sudo ln -s ${MATLAB_INSTALL_LOCATION}/bin/matlab /usr/local/bin/matlab # Note: Uncomment one of the following two ways to configure the license server. diff --git a/README.md b/README.md index b1ef02c..05c0233 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ 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). +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). ### Requirements * [A Running Network License Manager for MATLAB](https://www.mathworks.com/help/install/administer-network-licenses.html) - * For more information, see [Using the Network License Manager](#use-the-network-license-manager) + * For more information, see [Using the Network License Manager](#use-the-network-license-manager) * Docker ## Build Instructions @@ -60,7 +60,7 @@ The [Dockerfile](https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/ma | [MATLAB_RELEASE](#build-an-image-for-a-different-release-of-matlab) | r2024a | The MATLAB release you want to install, in lower-case. For example: `r2019b`| | [MATLAB_PRODUCT_LIST](#build-an-image-with-a-specific-set-of-products) | MATLAB | Products to install as a space-separated list. For more information, see [MPM.md](https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/MPM.md). For example: `MATLAB Simulink Deep_Learning_Toolbox Fixed-Point_Designer`| | [MATLAB_INSTALL_LOCATION](#build-an-image-with-matlab-installed-to-a-specific-location) | /opt/matlab/r2024a | The path to install MATLAB. | -| [LICENSE_SERVER](#build-an-image-with-license-server-information) | *unset* | The port and hostname of the machine that is running the Network License Manager, using the `port@hostname` syntax. For example: `27000@MyServerName` | +| [LICENSE_SERVER](#build-an-image-configured-to-use-a-license-server) | *unset* | The port and hostname of the machine that is running the Network License Manager, using the `port@hostname` syntax. For example: `27000@MyServerName` | Use these arguments with the the `docker build` command to customize your image. Alternatively, you can change the default values for these arguments directly in the [Dockerfile](https://github.com/mathworks-ref-arch/matlab-dockerfile/blob/main/Dockerfile). @@ -83,7 +83,7 @@ For example, to build an image with MATLAB installed at /opt/matlab, use this co docker build --build-arg MATLAB_INSTALL_LOCATION='/opt/matlab' -t matlab:r2024a . ``` -#### Build an Image with License Server Information +#### Build an Image Configured to Use a License Server Including the license server information with the `docker build` command means you do not have to pass it when running the container. ```bash @@ -182,6 +182,7 @@ 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: diff --git a/alternates/building-on-matlab-docker-image/Dockerfile b/alternates/building-on-matlab-docker-image/Dockerfile index 069c88c..488f7bc 100755 --- a/alternates/building-on-matlab-docker-image/Dockerfile +++ b/alternates/building-on-matlab-docker-image/Dockerfile @@ -46,7 +46,7 @@ RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ --release=${MATLAB_RELEASE} \ --products ${ADDITIONAL_PRODUCTS} \ || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ - && sudo rm -rf mpm /tmp/mathworks_root.log ${HOME}/.MathWorks + && sudo rm -rf mpm /tmp/mathworks_root.log # When running the container a license file can be mounted, # or a license server can be provided as an environment variable. diff --git a/alternates/matlab-container-offline-install/Dockerfile b/alternates/matlab-container-offline-install/Dockerfile new file mode 100644 index 0000000..fdda7a9 --- /dev/null +++ b/alternates/matlab-container-offline-install/Dockerfile @@ -0,0 +1,84 @@ +# Copyright 2024 The MathWorks, Inc. +# This Dockerfile allows you to build a Docker® image with MATLAB® installed using the MATLAB Package +# Manager. Use the optional build arguments to customize the version of MATLAB, list of products to +# install, and the location at which to install MATLAB. + +# Here is an example docker build command with the optional build arguments. +# docker build --build-arg MATLAB_RELEASE=r2024a +# --build-arg MATLAB_PRODUCT_LIST="MATLAB Deep_Learning_Toolbox Symbolic_Math_Toolbox" +# --build-arg MATLAB_INSTALL_LOCATION="/opt/matlab/R2024a" +# -t my_matlab_image_name . + +# To specify which MATLAB release to install in the container, edit the value of the MATLAB_RELEASE argument. +# Use lowercase to specify the release, for example: ARG MATLAB_RELEASE=r2021b +ARG MATLAB_RELEASE=r2024a + +# Specify the list of products to install into MATLAB. +ARG MATLAB_PRODUCT_LIST="MATLAB" + +# Specify the MATLAB Install Location. +ARG MATLAB_INSTALL_LOCATION="/opt/matlab/${MATLAB_RELEASE}" + +# Specify the archive image containing the installation files +ARG ARCHIVE_BASE_IMAGE="mpm-archive:${MATLAB_RELEASE}" + +# Specify license server information using the format: port@hostname +ARG LICENSE_SERVER + +# Specify the archive base image as a stage to allow it to be mounted in a later stage +FROM ${ARCHIVE_BASE_IMAGE} AS archive + +# When you start the build stage, this Dockerfile by default uses the Ubuntu-based matlab-deps image. +# To check the available matlab-deps images, see: https://hub.docker.com/r/mathworks/matlab-deps +FROM mathworks/matlab-deps:${MATLAB_RELEASE} + +# Declare build arguments to use at the current build stage. +ARG MATLAB_PRODUCT_LIST +ARG MATLAB_INSTALL_LOCATION +ARG LICENSE_SERVER + +# Add "matlab" user and grant sudo permission. +RUN adduser --shell /bin/bash --disabled-password --gecos "" matlab \ + && echo "matlab ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/matlab \ + && chmod 0440 /etc/sudoers.d/matlab + +# Set user and work directory. +USER matlab +WORKDIR /home/matlab + +# Run mpm to install MATLAB in the target location and delete the mpm installation afterwards. +# If mpm fails to install successfully, then print the logfile in the terminal, otherwise clean up. +# Pass in $HOME variable to install support packages into the user's HOME folder. +RUN --mount=type=bind,from=archive,source=/,target=/mpm-download/ \ + sudo HOME=${HOME} /mpm-download/mpm install \ + --source=/mpm-download/archives \ + --destination=${MATLAB_INSTALL_LOCATION} \ + ${MATLAB_PRODUCT_LIST} \ + || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ + && sudo rm -rf /tmp/mathworks_root.log \ + && sudo ln -s ${MATLAB_INSTALL_LOCATION}/bin/matlab /usr/local/bin/matlab + + +# Note: Uncomment one of the following two ways to configure the license server. + +# Option 1. Specify the host and port of the machine that serves the network licenses +# if you want to store the license information in an environment variable. This +# is the preferred option. You can either use a build variable, like this: +# --build-arg LICENSE_SERVER=27000@MyServerName or you can specify the license server +# directly using: ENV MLM_LICENSE_FILE=27000@flexlm-server-name +ENV MLM_LICENSE_FILE=$LICENSE_SERVER + +# Option 2. Alternatively, you can put a license file into the container. +# Enter the details of the license server in this file and uncomment the following line. +# COPY network.lic ${MATLAB_INSTALL_LOCATION}/licenses/ + +# The following environment variables allow MathWorks to understand how this MathWorks +# product is being used. This information helps us make MATLAB even better. +# Your content, and information about the content within your files, is not shared with MathWorks. +# To opt out of this service, delete the environment variables defined in the following line. +# See the Help Make MATLAB Even Better section in the accompanying README to learn more: +# https://github.com/mathworks-ref-arch/matlab-dockerfile/alternates/matlab-container-offline-install#help-make-matlab-even-better +ENV MW_DDUX_FORCE_ENABLE=true MW_CONTEXT_TAGS=$MW_CONTEXT_TAGS,MATLAB:FROM_SOURCE:DOCKERFILE:V1 + +ENTRYPOINT ["matlab"] +CMD [""] \ No newline at end of file diff --git a/alternates/matlab-container-offline-install/README.md b/alternates/matlab-container-offline-install/README.md new file mode 100644 index 0000000..1b255ee --- /dev/null +++ b/alternates/matlab-container-offline-install/README.md @@ -0,0 +1,149 @@ +# Install MATLAB and Add-Ons in Containers in an Offline Environment + +The Dockerfiles in this subfolder show you how to build and customize a Docker® container for MATLAB® and its toolboxes, using the [MATLAB Package Manager (*mpm*)](../../MPM.md) in an offline environment where *mpm* is not able to download the toolbox installation files. Use this solution only if you need to install MATLAB, toolboxes, and support packages in an air-gapped environment. Otherwise, use the [`Dockerfile`](../../Dockerfile) in the top-level repository. + +The solution uses two Docker images. The first image (archive image) contains the installation files that are required by *mpm* to install from source. The second image (product image) uses the archive image to get the installation files for MATLAB, toolboxes and support packages that you want to install. + +### Requirements +* [A Running Network License Manager for MATLAB](https://www.mathworks.com/help/install/administer-network-licenses.html) + * For more information, see [Use the Network License Manager](../../README.md#use-the-network-license-manager) +* Docker >= 20.10 + +## Build Instructions + +### Get the Dockerfiles + +Access the Dockerfiles either by directly downloading this repository from GitHub®, or by cloning this repository and then navigating to the appropriate subfolder. You must have a working internet connection to perform this action. + +```bash +git clone https://github.com/mathworks-ref-arch/matlab-dockerfile.git +cd matlab-dockerfile/alternates/matlab-container-offline-install +``` +### Build the Archive Docker Image +> :warning: Note: You must run this step in an online environment. + +You can then store the generated Docker build and copy it to the offline or air-gapped environment for the next step. + +Build the archive image with a name and tag. +```bash +docker build -t mpm-archive:r2024a -f archive.Dockerfile . +``` + +By default, the [archive.Dockerfile](archive.Dockerfile) downloads the latest available MATLAB release without any additional toolboxes or products. + +To customize the build of the archive image, refer to [Customize the Archive Docker Image](#customize-the-archive-docker-image). + +### Build the Product Docker Image +To run this step in an offline or air-gapped environment, you need: +* The [mathworks/matlab-deps](https://hub.docker.com/r/mathworks/matlab-deps) image in your local Docker registry. +* The mpm-archive image in your local Docker registry. +* A Docker environment with [BuildKit enabled](https://docs.docker.com/build/buildkit/#getting-started). + +Build a container with a name and tag. +```bash +DOCKER_BUILDKIT=1 docker build -t matlab-from-source:r2024a . +``` + +To customize the build of the product image, refer to [Customize the Product Docker Image](#customize-the-product-docker-image). + +## Customization Instructions +Follow these instructions if you want to customize the build of the archive and product Docker images. + +### Customize the Archive Docker Image +The [archive.Dockerfile](archive.Dockerfile) supports the following Docker build-time variables: + +| Argument Name | Default value | Effect | +|---|---|---| +| [MATLAB_RELEASE](#build-an-archive-image-for-a-different-release-of-matlab) | r2024a | The MATLAB release you want to install, in lower-case. For example: `r2022a` | +| [MATLAB_PRODUCT_LIST](#build-an-archive-image-with-a-specific-set-of-products) | MATLAB | Products to install as a space-separated list. For more information, see [MPM.md](../../MPM.md). For example: `MATLAB Simulink Deep_Learning_Toolbox Fixed-Point_Designer` | + +Use these arguments with the `docker build` command to customize your image. +Alternatively, you can change the default values for these arguments directly in the [archive.Dockerfile](archive.Dockerfile). + +#### Build an Archive Image for a Different Release of MATLAB + +For example, to build an archive image for MATLAB R2023b installation files, use the following command. +```bash +docker build --build-arg MATLAB_RELEASE=r2023b -t mpm-archive:r2023b -f archive.Dockerfile . +``` + +#### Build an Archive Image with a specific set of products + +For example, to build an image with MATLAB and the Statistics and Machine Learning Toolbox™ installation files, use this command. +```bash +docker build --build-arg MATLAB_PRODUCT_LIST="MATLAB Statistics_and_Machine_Learning_Toolbox" -t mpm-archive:r2024a -f archive.Dockerfile . +``` + +### Customize the Product Docker Image +The [Dockerfile](Dockerfile) supports the following Docker build-time variables: + +| Argument Name | Default value | Effect | +|---|---|---| +| [MATLAB_RELEASE](#build-an-image-for-a-different-release-of-matlab) | r2024a | The MATLAB release you want to install, in lower-case. For example: `r2022a`. :warning: This release must match the `MATLAB_RELEASE` you use to build the archive image. | +| [MATLAB_PRODUCT_LIST](#build-an-image-with-a-specific-set-of-products) | MATLAB | Products to install as a space-separated list. For more information, see [MPM.md](../../MPM.md). For example: `MATLAB Simulink Deep_Learning_Toolbox Fixed-Point_Designer`. The list of products to install must be a subset of the installation files available in the archive image. | +| [MATLAB_INSTALL_LOCATION](#build-an-image-with-matlab-installed-to-a-specific-location) | /opt/matlab/r2024a | The path to install MATLAB. | +| [ARCHIVE_BASE_IMAGE](#build-an-image-from-a-different-archive) | mpm-archive:r2024a | The name of the Docker® image containing the product installation files. | +| [LICENSE_SERVER](#build-an-image-configured-to-use-a-license-server) | *unset* | The port and hostname of the machine that is running the Network License Manager, using the `port@hostname` syntax. For example: `27000@MyServerName` | + +Use these arguments with the `docker build` command to customize your image. +Alternatively, you can change the default values for these arguments directly in the [Dockerfile](Dockerfile). + + +### Build an Image for a Different Release of MATLAB + +For example, to build an image for MATLAB R2023b, use the following command. +```bash +docker build --build-arg MATLAB_RELEASE=r2023b --build-arg ARCHIVE_BASE_IMAGE=mpm-archive:r2023b -t matlab-from-source:r2023b . +``` +Ensure that the release of the archive base image you set in `ARCHIVE_BASE_IMAGE` matches the one in `MATLAB_RELEASE`. + +### Build an Image with a Specific Set of Products + +For example, to build an image with MATLAB and the Statistics and Machine Learning Toolbox, use this command. +```bash +docker build --build-arg MATLAB_PRODUCT_LIST="MATLAB Statistics_and_Machine_Learning_Toolbox" -t matlab-stats-from-source:r2024a . +``` + +### Build an Image with MATLAB Installed to a Specific Location + +For example, to build an image with MATLAB installed at `/opt/matlab`, use this command. +```bash +docker build --build-arg MATLAB_INSTALL_LOCATION="/opt/matlab" -t matlab-from-source:r2024a . +``` + +### Build an Image from a Different Archive + +For example, to build an image using a different archive image, use the following command. +```bash +docker build --build-arg ARCHIVE_BASE_IMAGE=my-archive -t matlab-from-source:r2024a . +``` + +#### Build an Image Configured to Use a License Server + +Including the license server information with the `docker build` command means you do not have to pass it when running the container. +```bash +# Build container with the License Server. +docker build --build-arg LICENSE_SERVER=27000@MyServerName -t matlab-from-source:r2024a . + +# Run the container, without needing to pass license information. +docker run --init --rm matlab-from-source:r2024a -batch ver +``` + +For more information, see [Use the Network License Manager](../../README.md#use-the-network-license-manager). + +## More MATLAB Docker Resources +For more MATLAB Docker resources, see [More MATLAB Docker Resources](../../README.md#more-matlab-docker-resources). + +## Help Make MATLAB Even Better +You can help improve MATLAB by providing user experience information on how you use MathWorks products. Your participation ensures that you are represented and helps us design better products. To opt out of this service, delete the following line in the Dockerfile: +```Dockerfile +ENV MW_DDUX_FORCE_ENABLE=true MW_CONTEXT_TAGS=MATLAB:FROM_SOURCE:DOCKERFILE:V1 +``` + +To learn more, see the documentation: [Help Make MATLAB Even Better - Frequently Asked Questions](https://www.mathworks.com/support/faq/user_experience_information_faq.html). + +## Feedback +We encourage you to try this repository with your environment and provide feedback. If you encounter a technical issue or have an enhancement request, create an issue [here](https://github.com/mathworks-ref-arch/matlab-dockerfile/issues). + +--- +Copyright 2024 The MathWorks, Inc. diff --git a/alternates/matlab-container-offline-install/archive.Dockerfile b/alternates/matlab-container-offline-install/archive.Dockerfile new file mode 100644 index 0000000..64d07fe --- /dev/null +++ b/alternates/matlab-container-offline-install/archive.Dockerfile @@ -0,0 +1,55 @@ +# Copyright 2024 The MathWorks, Inc. + +# Here is an example docker build command with the optional build arguments. +# docker build --build-arg MATLAB_RELEASE=r2024a +# --build-arg MATLAB_PRODUCT_LIST="MATLAB Deep_Learning_Toolbox Symbolic_Math_Toolbox" +# -f archive.Dockerfile +# -t mpm-archive . + +# To specify which MATLAB release to install in the container, edit the value of the MATLAB_RELEASE argument. +# Use lowercase to specify the release, for example: ARG MATLAB_RELEASE=r2021b +ARG MATLAB_RELEASE=r2024a + +# Specify the list of products to install into MATLAB. +ARG MATLAB_PRODUCT_LIST="MATLAB" + +# The staging location used to store the downloaded mpm archives +ARG MPM_DOWNLOAD_DESTINATION="/usr/local/src" + +# Download MPM and installation files in a mathworks/matlab-deps Docker image +# This guarantees that all dependencies are already installed +FROM mathworks/matlab-deps:${MATLAB_RELEASE} AS download + +# Declare build arguments to use at the current build stage. +ARG MATLAB_RELEASE +ARG MATLAB_PRODUCT_LIST +ARG MPM_DOWNLOAD_DESTINATION + +# Install mpm dependencies. +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install --no-install-recommends --yes \ + wget \ + ca-certificates \ + && apt-get clean \ + && apt-get autoremove \ + && rm -rf /var/lib/apt/lists/* + +# Run mpm to install MATLAB in the target location. +# If mpm fails to install successfully, then print the logfile in the terminal, otherwise clean up. +RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ + && chmod +x mpm \ + && ./mpm download \ + --release=${MATLAB_RELEASE} \ + --destination=${MPM_DOWNLOAD_DESTINATION} \ + --products ${MATLAB_PRODUCT_LIST} \ + || (echo "MPM Download Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) + +# Move MPM and the installation files to a scratch image +FROM scratch + +# Declare build arguments to use at the current build stage. +ARG MPM_DOWNLOAD_DESTINATION + +COPY --from=download ${MPM_DOWNLOAD_DESTINATION} / +COPY --from=download mpm /mpm diff --git a/alternates/non-interactive/Dockerfile b/alternates/non-interactive/Dockerfile index 71e571d..f8bf7c5 100644 --- a/alternates/non-interactive/Dockerfile +++ b/alternates/non-interactive/Dockerfile @@ -57,7 +57,7 @@ RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm \ --destination=${MATLAB_INSTALL_LOCATION} \ --products ${MATLAB_PRODUCT_LIST} \ || (echo "MPM Installation Failure. See below for more information:" && cat /tmp/mathworks_root.log && false) \ - && sudo rm -rf mpm /tmp/mathworks_root.log ${HOME}/.MathWorks \ + && sudo rm -rf mpm /tmp/mathworks_root.log \ && sudo ln -s ${MATLAB_INSTALL_LOCATION}/bin/matlab /usr/local/bin/matlab # Install matlab-batch to enable the use of MATLAB batch licensing tokens. diff --git a/tests/alternates/matlab-container-offline-install/productsTest.m b/tests/alternates/matlab-container-offline-install/productsTest.m new file mode 100644 index 0000000..92f3d6f --- /dev/null +++ b/tests/alternates/matlab-container-offline-install/productsTest.m @@ -0,0 +1,29 @@ +% Copyright 2024 The MathWorks, Inc. + +classdef productsTest < matlab.unittest.TestCase + + + methods(Test) + function testInstalledToolboxesMatchExpected( testCase ) + import matlab.unittest.constraints.IsSameSetAs + + % names of the expected toolboxes + expectedTbxNames = [... + "Deep Learning Toolbox",... + "Symbolic Math Toolbox"... + ]; + installedTbxNames = matlab.addons.installedAddons().Name; + testCase.verifyThat(installedTbxNames, IsSameSetAs(expectedTbxNames)); + end + function testInstalledSupportPackagesMatchExpected( testCase ) + import matlab.unittest.constraints.IsSameSetAs + + % names of the expected support packages + expectedSpkgNames = [... + "Deep Learning Toolbox Model for ResNet-50 Network"... + ]; + installedSpkgNames = matlabshared.supportpkg.getInstalled().Name; + testCase.verifyThat(installedSpkgNames, IsSameSetAs(expectedSpkgNames)); + end + end +end diff --git a/tests/alternates/matlab-container-offline-install/test_container.py b/tests/alternates/matlab-container-offline-install/test_container.py new file mode 100644 index 0000000..4a9f884 --- /dev/null +++ b/tests/alternates/matlab-container-offline-install/test_container.py @@ -0,0 +1,77 @@ +# Copyright 2024 The MathWorks, Inc. + +""" +Test class to validate the "matlab-container-offline-install" Dockerfile. + +This test suite will launch the container and test some features, e.g. users +permissions, the apt cache, the matlab executable... +These tests do not require a license file to run. +""" + +from utils import base, helpers +import docker +import unittest + +################################################################################ + + +class TestContainer(base.TestCase): + """Extend the test methods of the base TestCase class.""" + + expected_ddux_force_enable = "true" + expected_ddux_tags = ["MATLAB:FROM_SOURCE:DOCKERFILE:V1"] + + @classmethod + def setUpClass(cls): + """Run the container""" + cls.client = docker.from_env() + image_name = helpers.get_image_name() + cls.container = cls.client.containers.run( + image=image_name, + detach=True, + stdin_open=True, + entrypoint="/bin/bash", + ) + cls.install_dirname = "work" + cls.release_tag = helpers.get_release_tag(image_name) + super().setUpClass() + + @classmethod + def tearDownClass(cls): + """Stop and remove the container""" + cls.container.stop() + cls.container.remove() + cls.client.close() + + ############################################################################ + + def test_cannot_run_matlab_without_license(self): + """Test that matlab cannot be run without mounting a valid license file.""" + matlab_cmd = "matlab" + self.assertFalse(self.host.run(matlab_cmd).succeeded) + + def test_mpm_not_present(self): + """Test that MPM is not present""" + find_mpm = "find / -type f -name mpm -print" + mpm_path = self.host.run(find_mpm).stdout.strip() + self.assertEqual(mpm_path, "", f"Found mpm at path {mpm_path}") + + def test_installation_files_not_present(self): + """Test that the installation files are not present""" + archive_dir = "/archives" + inst_files_format = "enc" + find_installation_files = ( + f"find / -path '{archive_dir}/*.{inst_files_format}' -type f -print" + ) + inst_files_paths = self.host.run(find_installation_files).stdout.strip() + self.assertEqual( + inst_files_paths, + "", + f"Found *.{inst_files_format} files in {archive_dir}:\n{inst_files_paths}", + ) + + +################################################################################ + +if __name__ == "__main__": + unittest.main() diff --git a/tests/alternates/matlab-container-offline-install/test_installed_products.py b/tests/alternates/matlab-container-offline-install/test_installed_products.py new file mode 100644 index 0000000..7c71824 --- /dev/null +++ b/tests/alternates/matlab-container-offline-install/test_installed_products.py @@ -0,0 +1,28 @@ +# Copyright 2024 The MathWorks, Inc. + +"""Test runner for the productsTest.m test file""" + +from utils import dockertool +from pathlib import Path +import unittest + + +class TestInstalledProducts(unittest.TestCase): + """A test runner class for the productsTest.m test file""" + + def run_matlab_test(self, m_filename): + m_filepath = str(Path(__file__).parent.resolve() / m_filename) + + runner = dockertool.MATLABTestRunner(m_filepath) + + exit_code, error, logs = runner.run() + self.assertEqual(exit_code, 0, logs) + self.assertIsNone(error, logs) + + def test_installed_products(self): + m_filename = "productsTest.m" + self.run_matlab_test(m_filename) + + +if __name__ == "__main__": + unittest.main()