Skip to content
Sorina Pop edited this page Oct 17, 2025 · 11 revisions

VIP - Application packaging guide

This document describes how to package an application so that it can be imported into VIP.

In order to submit a new application to the platform, you must provide VIP support with at least:

  • a Docker image hosted in a standard image registry (e.g., Docker Hub) or in your own private registry. When possible, we recommend you also provide the Dockerfile along with the image
  • a boutiques descriptor defining the command line parameters of your application.
  • a set of input files suitable for a test run. You are responsible for ensuring that all provided input files have been legally allowed to be used in this context, and are properly anonymized. You can contact VIP support for any question regarding data usage.

The following extras are optional, but are appreciated to facilitate troubleshooting:

  • the Dockerfile used to build the image.
  • a link to your source code, if it is publicly available.

General notes

Whenever possible, please provide an estimate of minimal computing resources required by a typical execution (CPU time, number of cores, RAM and disk usage).

Your application must run within the following constraints:

  • Run in batch mode, i.e. without any user interaction.
  • Run with a regular user, not root. Runtime environments may impose arbitrary UIDs, so your app and all its dependencies must be world-readable by any limited user within the container.
  • Run with restricted filesystem writes. Runtime environments impose limitations on filesystem writes, so you apps and all its dependencies must avoid requiring write access to arbitrary directories.
  • Provide configurable command-line flags for all inputs and outputs, so that input/output directories can be decided at runtime. In a typical VIP runtime environment, only a few directories such as /tmp and explicitly configured outputs are writable, the rest of the filesystem may be read-only.
  • Restricted network environment: ideally, your app must run with no network at all. If network calls are really unavoidable, please provide a list of host:ports that your application is reaching, to allow traffic whitelisting.
  • For compiled applications, avoid using architecture-specific compilation flags (such as gcc -march=...), to favor compatibility with a large range of CPU models.

Docker image

To create a docker image, you must write a Dockerfile containing all the instructions to assemble the image, then use the docker build command:

# edit ./Dockerfile, then:
docker build . -t myname/example:v0.0.1

An example Dockerfile which can be used as a basis for new applications is available here. Once you have built an image for your app and verified that it works, you can either publish it on a registry with docker push, or save it locally with docker save.

Some recommendations for building the image:

  • Use an official image as your base image. Prefer images with an explicit version number, and with the smallest set of dependencies required by your app. For instance, if your app is Python-based, a good base image is python:3.10-slim.
  • Provide enough flexibility for runtime environments constraints (see also "General notes" above). Especially:
    • Create a non-root user to run your app within the container.
    • Use separate and configurable directories for inputs, outputs, and temporary files. They will be dynamically mounted at runtime (for instance docker run -v host_input:/input -v host_output:/output), and must be made configurable in the boutiques descriptor.
    • Do not use the /tmp directory to install any program or dependency: this directory is overridden at runtime, it is usable for temporary writes, but any file placed under /tmp/ in the Docker image won't be available.
    • WORKDIR, USER, CMD and ENTRYPOINT might all be overridden at runtime.
  • Once all dependencies have been installed, reduce the image size by purging any temporary installation file that is not needed at runtime (pip install --no-cache-dir, apt --no-install-recommends, rm -rf /var/lib/apt/lists/*, ...). This allows to deploy the image more efficiently to runtime environments.
  • Watch out for build reproducibility: it is recommended to freeze your dependencies when building the image (python requirements.txt, nodeJS package-lock.json, ...), so that future builds do not implicitly upgrade some dependencies, as this could lead to unexpected changes in your app behaviour.

Other useful links:

Docker Image Storage and Sharing

To ensure smooth and reproducible deployment on our platform, we recommend that all Docker images are stored and shared through an image registry. All images must be clearly tagged with their version number (note that "latest" tag is not allowed).

General Recommendation: whenever possible, please host images in a standard image registry (e.g., Docker Hub) or in your own private registry.

Public Images: if your image is publicly available (e.g., on Docker Hub), you only need to provide us with the image reference and version (e.g., dockerhubuser/imagename:tag), which should be present in the Boutiques descriptor.

Private Images: if your image is private and hosted in an image registry, in addition to the image reference and version (e.g., privatehub/imagename:tag), you will need to share access credentials with us so that we can pull the image. If you do not have the possibility to host your private image in a registry by yourself, we can provide a local registry solution. This requires an agreement on access rights, security, and confidentiality measures before we accept and host the image. In such cases, the concerned parties must contact the VIP team to evaluate and define the appropriate process.

Boutiques descriptor

The boutiques descriptor is a JSON file defining the command line parameters of your application, as well as some properties (app name, version, author...). VIP uses this file to build a web UI allowing to upload inputs, run the app, and download outputs.

A minimal example which can be used as a basis for new applications is available here. Boutiques comes with its own command-line tool, bosh, which can help testing the descriptor validity before submission, especially with these two commands:

  • bosh validate to check the descriptor validity
  • bosh exec to launch an execution

Other useful links:

Practical examples

Below, a few practical examples are provided to show how to build and run a container image with Docker and Boutiques.

The prerequisites to run these examples are git, docker and python3. To install Docker, follow the instructions at https://docs.docker.com/engine/install/.

Preparation:

# get the "packaging-example" directory from VIP repository:
git clone --depth=1 --branch=main https://github.com/virtual-imaging-platform/vip-apps-boutiques-descriptors
cd vip-apps-boutiques-descriptors/packaging-example

Docker commands:

# build docker image from Dockerfile
docker build . -t myname/example:v0.0.1

# save docker image to a local compressed archive
docker save myname/example:v0.0.1 | gzip > example-v0.0.1.tgz

# test "docker run", with limited user and files I/O within the container
docker run -it --rm --user=$(id -u):$(id -g) myname/example:v0.0.1 sh -c "python3 /app/example.py --input1=test --input2=/dev/null --output=/tmp/myoutput && cat /tmp/myoutput"

# test "docker run" with input/output files on host
echo "1234" >test_in.txt
docker run -it --rm --user=$(id -u):$(id -g) --workdir=/some_random_workdir --volume=$PWD:/some_random_workdir myname/example:v0.0.1 sh -c "python3 /app/example.py --input1=test --input2=test_in.txt --output=test_out.txt"
cat test_out.txt
rm -f test_in.txt test_out.txt

Boutiques bosh commands:

# create a Python venv and install boutiques inside
python3 -m venv ~/venv
source ~/venv/bin/activate
pip install boutiques

# use "bosh validate" to check a descriptor
bosh validate example.json

# "bosh exec" needs an invocation file to specify values for input parameters.
# When an app is executed through VIP, this is managed automatically, so you only need to provide the descriptor.
# To test bosh exec on your machine, you must generate this extra file:
# - either use "bosh example" to create an example invocation file:
bosh example example.json > invocation.json
# - or just directly create your own:
echo '{"input1":"test","input2":"test_in.txt","outname":"test_out.txt"}' >invocation.json

# use "bosh exec" to run a container image through Boutiques
echo 1234 >test_in.txt
bosh exec --user launch example.json invocation.json
cat test_out.txt
rm -f test_in.txt test_out.txt

Clone this wiki locally