6 Docker app cookbook
David Anderson edited this page 2024-12-12 20:37:43 -08:00

The easiest way to run Docker apps on BOINC is BUDA.

BUDA has the advantage that scientists can deploy Docker apps and submit batches of jobs to them entirely through a web interface. They don't have to log in the BOINC server, or know anything about BOINC.

BUDA has two limitations:

  • jobs must be submitted to a particular 'variant' (CPU or GPU).
  • Input and applications files are copied to the slot directory, rather than linked. This imposes overhead if the files are large.

If either of these is a deal-breaker, you can create Docker apps in the standard way, in which there is one BOINC app per science app. You need to create new BOINC app versions each time your science app changes. This means your science app developers must have login access to the BOINC server, and must learn BOINC's command-line tools.

This cookbook shows how to do this. We're going to make a Docker app for Windows; the Linux and Mac OS cases are similar. For background, please read about how Docker apps work. We assume you already have created a BOINC project.

Docker app jobs are sent only to BOINC 9.0+ clients that have Docker. On Windows this requires that

  • WSL is enabled
  • The host has the 'BOINC WSL distro' installed from the Windows Store (or has another WSL distro with either Docker or Podman installed).

Our "science executable" is an x64/Intel program that runs inside a Docker container. This program is called worker; it converts a file to upper case and optionally uses some CPU time.

worker --nsecs 60 infile outfile

Get "worker"

Log in to your BOINC server. You can download worker:

wget https://boinc.berkeley.edu/worker_4_x86_64-pc-linux-gnu
chmod +x worker_4_x86_64-pc-linux-gnu

or build it in the BOINC source tree:

cd samples/worker
make

and rename it to worker_4_x86_64-pc-linux-gnu. (The '4' is a version number; in general all files should have version numbers in case they change).

Verify that is works:

echo "test" > infile
./worker_4_x86_64-pc-linux-gnu infile outfile
cat outfile
# it should print TEST

Get docker_wrapper

Download it:

wget https://boinc.berkeley.edu/docker_wrapper_2_windows_x86_64.exe

Other files

Make a file Dockerfile_worker_1:

FROM debian
WORKDIR /app
CMD ./main.sh

Make a file job_1.toml:

project_dir_mount = "/project"

Make a file main_2.sh:

#! /bin/bash

resolve () {
    sed 's/<soft_link>..\/..\/projects\/[^\/]*\//\/project\//; s/<\/soft_link>//' $1 | tr -d '\r\n'
}

$(resolve worker) --nsecs 60 $(resolve in) out

Create the app

  • Go to your project's admin web interface
  • Click on Manage applications
  • Add an application with name 'worker' and description 'Test app'.

Create input and output templates

In ~/projects/<proj_name>/templates/, create a file worker_in:

<input_template>
    <file_info>
    </file_info>
    <workunit>
        <file_ref>
            <open_name>in</open_name>
        </file_ref>
    </workunit>
</input_template>

and worker_out:

<output_template>
    <file_info>
        <name><OUTFILE_0/></name>
        <generated_locally/>
        <upload_when_present/>
        <max_nbytes>5000000</max_nbytes>
        <url><UPLOAD_URL/></url>
    </file_info>
    <result>
        <file_ref>
            <file_name><OUTFILE_0/></file_name>
            <open_name>out</open_name>
            <copy_file/>
        </file_ref>
    </result>
</output_template>

Create an app version for Windows

Using the above files, create the following directory structure:

~/projects/<proj_name>/apps/
    worker/
        1.0/
            windows_x86_64__docker/
                Dockerfile_worker_1
                docker_wrapper_1.exe
                job_1.toml
                main_2.sh
                worker_4_x86_64-pc-linux-gnu
                version.xml

where version.xml contains

<version>
    <file>
        <physical_name>docker_wrapper_1.exe</physical_name>
        <main_program/>
    </file>
    <file>
        <physical_name>worker_3_x86_64-pc-linux-gnu</physical_name>
        <logical_name>worker</logical_name>
    </file>
    <file>
        <physical_name>main_2.sh</physical_name>
        <logical_name>main.sh</logical_name>
        <copy_file/>
    </file>
    <file>
        <physical_name>Dockerfile_worker_1</physical_name>
        <logical_name>Dockerfile</logical_name>
        <copy_file/>
    </file>
    <file>
        <physical_name>job_1.toml</physical_name>
        <logical_name>job.toml</logical_name>
        <copy_file/>
    </file>
    <is_wrapper/>
</version>

In your project's main directory:

bin/update_version --noconfirm

Set up a validator and assimilator

Edit your project's config.xml and add the following to the <daemons> section:

<daemon>
  <cmd>script_validator --app worker --init_script "validate_init.py" --compare_script "validate_compare.py"</cmd>
</daemon>
<daemon>
  <cmd>script_assimilator -d 3 --app worker --script "sample_assimilate.py wu_name batch_id files"</cmd>
</daemon>

Test

In your project's main directory:

bin/stop
bin/start

Create a file infile with some mixed-case text. Run

bin/submit_job worker infile

It will print a job name.

Go to a Windows computer that has Docker enabled (see above) and has a BOINC 9.0+ client running and attached to your project. Update the project. It should fetch the job you just created, run it (takes about 1 minute) and upload the output file.

When the job is done, run

bin/query_job <job_name>

This should show that the job is completed, and display its output file.