Skip to content

Create Docker Image

nickilanger edited this page May 16, 2019 · 9 revisions

Here we describe an example how to containerize your matlab script as a Docker image.

The following matlab script runs 100x preprocessing with only PREP. This script is also available on OSF https://osf.io/5e74x/.

filepath = '/path/to/RAWformat/A77/';
fileName = 'A77_WI1_EEG.RAW';
iterationNB = 100;
locationFile = '/path/to/GSN-HydroCel-129.sfp';
locFileType = 'sfp';
powerLineFreq = 50;
highPassFreq = 0.5;


params = struct('FilterParams',     struct('high',  struct('freq',  highPassFreq, 'order', [])),...
             'CRDParams',           struct([]), ...
             'PrepParams',          struct(), ...
             'HighvarParams',       struct([]), ...
             'InterpolationParams', struct([]), ...
             'RPCAParams',          struct([]), ...
             'MARAParams',          struct([]), ...
             'EOGRegressionParams', struct([]), ...
             'ChannelReductionParams', struct('tobeExcludedChans', []), ...
             'EEGSystem',           struct('name', 'Others',...
                                           'sys10_20', 0, ...
                                           'locFile', locationFile, ...
                                           'refChan', struct('idx', []), ...
                                           'fileLocType', locFileType,...
                                           'eogChans', [], ...
                                           'powerLineFreq', powerLineFreq), ...
             'Settings',            struct('trackAllSteps', 0, ...
                                       'pathToSteps', '/allSteps.mat')...
             );
             
             
allBadChannels = {};
addAutomagicPaths();
EEG = pop_fileio([filepath fileName]);
for i = 1:iterationNB
    [EEG_out, plots] = preprocess(EEG, params);
    allBadChannels = [allBadChannels; EEG_out.automagic.autoBadChans];
    display(['Iteration ' num2str(i) ': ' num2str(EEG_out.automagic.autoBadChans)]);
end
save('allBadChannels.mat', 'allBadChannels');

channelTable = cell2table(allBadChannels);
if strcmp(class(channelTable.Variables), 'double')
    display('All are the same');
elseif strcmp(class(channelTable.Variables), 'cell')
    display('They are not the same. Please check why!');
else
    display('Should not happen');
end

Since we cannot run the matlab GUI inside a Docker, we need to create a standalone application from this matlab script. The instructions on the matlab website are quite clear, but some small details:

  • Select “Runtime downloaded from web”, since we will pre-install the runtime in the Docker container. Hence it does not need to be included.
  • Be sure to include all “Files required for your Automagic Preprocessing Pipeline”. This includes the preprocessing script and the the automagic folder.

After compilation, you only need the output in the for_docker_image_files_only directory.

Note: for this example, we used MATLAB R2017b running on OSX 10.11.6 64bit.

The Dockerfile should use the correct CentOS version, install the matlab runtime, and add the compiled script. Hence the Dockerfile looks like:

FROM centos:latest
MAINTAINER hjkuijf

RUN yum update -y \
 && yum install wget unzip libXext libXt-devel libXmu -y \
 && mkdir /mcr-install \
 && cd /mcr-install \
 && wget -nv http://www.mathworks.com/supportfiles/downloads/R2016a/deployment_files/R2016a/installers/glnxa64/MCR_R2016a_glnxa64_installer.zip \
 && unzip MCR_R2016a_glnxa64_installer.zip \
 && ./install -mode silent -agreeToLicense yes \
 && rm -Rf /mcr-install
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/MATLAB/MATLAB_Runtime/v901/runtime/glnxa64:/usr/local/MATLAB    /MATLAB_Runtime/v901/bin/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v901/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v901/sys/java/jre/glnxa64/jre/lib/amd64/native_threads:/usr/local/MATLAB/MATLAB_Runtime/v901/sys/java/jre/glnxa64/jre/lib/amd64/server:/usr/local/MATLAB/MATLAB_Runtime/v901/sys/java/jre/glnxa64/jre/lib/amd64
ENV XAPPLRESDIR=/usr/local/MATLAB/MATLAB_Runtime/v901/X11/app-defaults
ENV MCR_CACHE_VERBOSE=true
ENV MCR_CACHE_ROOT=/tmp

ADD matlab/example/_for_docker_image_files_only_ /docker_example
RUN ["chmod", "+x", "/docker_example/example"]

The middle block of code downloads and installs the matlab runtime and correctly updates the environment variables. Please note: combine all RUN-commands into a single statement and be sure to include the clean-up (rm)! The final ADD command copies our compiled code into the container at the location /docker_example. Finally we chmod the executable, so we can run it.

With the following command, we build a Docker container from our Dockerfile and the compiled matlab code:

docker build -f Dockerfile -t docker/[Docker-NAME] .

Once your container is ready, you can run it with the following command:

docker run -dit -v [TEST-ORIG]:/input/orig:ro -v [TEST-PRE]:/input/pre:ro -v /output docker/[Docker-NAME]

The -v options map the input folder into the container at /input, read-only. The last -v creates an output directory.

This command outputs the Container ID, which you can also look up with:

docker ps

Next, we will execute the example matlab script:

docker exec [CONTAINER-ID] /docker_example/example

Since this script is quite small, it doesn’t take long to finish. Next we copy the output from the container to our local machine:

docker cp [CONTAINER-ID]:/output [RESULT-LOCATION]

Finally, we shut down the running container. This also removes the created /output folder and any other changes made to the container.

docker rm -v [CONTAINER-ID]

This instruction is an adapted version of Hugo j. Kuif (UMC Utrecht). The source code can also be found on github: hjkuijf/wmhchallenge.