ADRIA Docker Setup
This repo contains a multistage Dockerfile for generating containerised applications based on the ADRIA source code in this repository.
Docker configuration
The following build args and defaults are available to configure the build behaviour.
ARG SANDBOX_FROM="adria-dev": What base image should be used for the sandbox
ARG ADRIA_VERSION="0.11.0": What version of ADRIA from package registry to install in adria-base
ARG JULIA_VERSION="1.10.4": See https://hub.docker.com/*/julia for valid versions.
adria-base
The adria-base
image variant is a Julia image with ADRIA.jl installed to a shared environment that is included in the Julia LOAD_PATH directly from it's github origin.
The Docker entrypoint for the adria-base
image is the julia
binary, so you can run just this base container if you want to invoke julia commands, including commands that depend on the ADRIA package being installed.
It can also be used as a base-image for any Julia application that needs to use ADRIA.
A note about platform build targets
This line in the Dockerfile prompts Julia to precompile the ADRIA package and it's predependencies for a larger range of target platforms. Given that the building of the image could occur on any host, we need to specify a range of platforms so that precompilation (which is CPU architecture dependent) does not need to reoccur when the Docker image is run on the user's system.
The below list came from here and is confirmed to work for a x86_64
based architecture.
# Try to coerce Julia to build across multiple targets
ENV JULIA_CPU_TARGET=x86_64;haswell;skylake;skylake-avx512;tigerlake
If more platforms are needing to be targeted, please lodge a pull request with the output of uname -m
and other details, and we can expand this list of target platforms.
Published base images
This repository uses GitHub actions to publish, upon version release, the adria-base
image - see .github/workflows/PublishDockerImage.yml
. The below commands such as running and using the ADRIA base image apply to these published images, replacing your locally tagged image with the GitHub Container Registry label e.g. the following will run in an interactive Julia shell, a precompiled terminal with ADRIA
installed, ready to be used.
docker run --tty --interactive ghcr.io/open-aims/adria.jl/adria-base:latest
Building adria-base
# EITHER using docker compose:
docker compose build adria-base
# OR using just `docker build`:
docker build --target "adria-base" --tag ADRIA.jl/adria-base:latest .
You can also opt to specify some custom build arguments to change the versions of Julia or ADRIA.jl that get installed. Supported arguments are:
ADRIA_REPO
: URL for the repository that ADRIA.jl should be cloned from. Defaults to https://github.com/open-AIMS/ADRIA.jl.gitADRIA_REFSPEC
: the branch-name or tag of theADRIA_REPO
that you want to install. Defaults tomain
.JULIA_VERSION
: The version of the Julia platform you want to install ADRIA.jl into. This must be one of the versions available for the official Julia base image. Defaults to1.10.1
.
See the docker-compose.yaml
file for an example of how to specify build arguments in docker compose.
Running adria-base
with a non-interactive Julia command
e.g. to list the packages installed in the @adria
shared environment:
# EITHER using docker compose:
docker compose run --rm adria-base --project=@adria -e 'using Pkg; Pkg.status()'
# OR using just docker run:
docker run --rm ADRIA.jl/adria-base:latest --project=@adria -e 'using Pkg; Pkg.status()'
Running adria-base
as an interactive Julia shell
To launch an interactive Julia shell:
# EITHER using docker compose:
docker compose run --rm adria-base
# OR using just docker run:
docker run --rm --interactive --tty ADRIA.jl/adria-base:latest
In both cases, type CTRL-d
to exit the shell and stop the container.
Running adria-base
with a non-Julia entrypoint
If you want to use this image to run something other than a Julia command, you can specify an alternate entrypoint at runtime as well as an alternate command. e.g. to launch an interactive bash
shell in the container for checking filesystem permissions or similar:
# EITHER using docker compose:
docker compose run --rm --entrypoint /bin/bash adria-base
# OR using just docker run:
docker run --rm --interactive --tty --entrypoint /bin/bash ADRIA.jl/adria-base:latest
Deriving an image from adria-base
To make a derived ADRIA application:
- Use
FROM ADRIA.jl/adria-base:latest
(or a related tag) - Include a
CMD
line in your Dockerfile that provides appropriate arguments to thejulia
command line to invoke your application.
The section of the Dockerfile
that defines the adria-sandbox
target described below might be useful inspiration.
adria-dev
The adria-dev
image variant is an alternative to the adria-base
image, not a derived application. Instead of installing ADRIA.jl as a normal package, it looks for the ADRIA.jl source code in a local subdirectory, and installs that as a Julia development package.
This allows you to use the adria-dev
container as an ADRIA.jl
development environment: you can run tests, bind-mount and edit the code, re-resolve dependencies and all sorts of other useful things without needing to a native installation of Julia.
Building adria-dev
From within the root of the ADRIA.jl
project, you can build the adria-dev
image like so:
# EITHER using docker compose:
docker compose build adria-dev
# OR using just `docker build`:
docker build --target "adria-dev" --tag ADRIA.jl/adria-dev:latest .
The same JULIA_VERSION
build argument that works with adria-base
will also work with adria-dev
.
Running adria-dev
as an interactive Julia shell
Very useful for running commands to update Package manifests and similar! The command will activate the shared @adria
environment by default, but you can switch to any other environment as you need to.
# EITHER using docker compose:
docker compose run --rm adria-dev
# OR using just docker run:
docker run --rm --interactive --tty \
--mount type=bind,source="$(pwd)"/ADRIA.jl/,target=/usr/local/src/adria/
ADRIA.jl/adria-dev:latest
In both cases, type CTRL-d
to exit the shell and stop the container.
Running ADRIA tests with adria-dev
ADRIA tests can be run like any other Julia command, but the GOTCHA is that they need to run in the local project environment, NOT in the shared @adria
environment:
# EITHER using docker compose:
docker compose run --rm adria-dev --project=. -e 'using Pkg; Pkg.test();'
# OR using just docker run:
docker run --rm ADRIA.jl/adria-dev:latest --project=. -e 'using Pkg; Pkg.test();'
This method of running tests is suitable to use in a containerised continuous integration pipeline.
adria-sandbox
The adria-sandbox
image variant is set up to run the sandbox
Julia application which has its source code in this repository.
This application uses the pre-installed ADRIA package, and can be built on either of adria-base
or adria-dev
, depending on whether you want the development version of the package or not.
It depends on input and output data files which must be provided at runtime.
Building adria-sandbox
The sandbox build supports an optional SANDBOX_FROM
build argument which is used to specify a base image. Supported values are adria-dev
(the default) or adria-base
.
# EITHER using docker compose (edit the compose file to specify which base image to use):
docker compose build adria-sandbox
# OR using just `docker build`:
docker build --build-arg SANDBOX_FROM=adria-dev --target "adria-sandbox" --tag ADRIA.jl/adria-sandbox:latest .
Running adria-sandbox
The adria-sandbox
image is configured to automatically run the dev.jl
script when a container made from that image runs.
For that script to be useful, though, you must first mount two filesystem locations to the container:
- A directory containing your input data files should be mounted at
/data/input
- A directory where the sandbox application can create output files should be mounted at
/data/output
This documentation and the docker-compose.yaml
file in the repository demonstrate using bind mounts to data-directories which are local to your current working directory for this purpose, but docker volumes with any supported storage driver should also work fine.
# EITHER using docker compose (which has the bind-mounts predefined):
docker compose up adria-sandbox
# OR using docker run:
docker run --rm \
--mount type=bind,source="$(pwd)"/input,target=/data/input \
--mount type=bind,source="$(pwd)"/output,target=/data/output \
ADRIA.jl/adria-sandbox:latest
The dev.jl
script should run with any files you have provided in your input volume, and will create and output files in your output volume. The container will be removed once the script completes.
Interacting with adria-sandbox
If you prefer to work with the sandbox code from an interactive shell, then you will need to override the default entrypoint and command combination to make the container launch your preferred shell at startup.
In this case, you may also like to bind-mount your sandbox and/or ADRIA.jl source code into the container, so that you can edit it without having to re-build the container each time.
e.g. to launch the sandbox container as a development environment with an interactive bash shell and use:
# EITHER using docker compose:
docker compose run --rm --entrypoint /bin/bash adria-sandbox
# OR using just docker run:
docker run --rm --interactive --tty --entrypoint /bin/bash \
--mount type=bind,source="$(pwd)"/input,target=/data/input \
--mount type=bind,source="$(pwd)"/output,target=/data/output \
--mount type=bind,source="$(pwd)"/sandbox,target=/opt/adria-sandbox/src \
--mount type=bind,source="$(pwd)"/ADRIA.jl,target=/usr/local/src/adria \
ADRIA.jl/adria-sandbox:latest
In both cases, the initial working directory will be the installation-location for the sandbox application's source code, and you can invoke any command you like from that shell prompt, e.g:
julia --project=@. dev.jl
Warning: For julia
commands, you will probably need to use the --project=@.
argument. This tells Julia that it's working environment is based in a parent directory of the one the sandbox source code is installed to, which is where the build configured all the precompiled dependencies. If you omit this, the pre-installed packages may not all be available.