├── persistence ├── data │ └── .gitkeep ├── .gitignore ├── Dockerfile └── readme.md ├── hello-world ├── hello.C ├── Dockerfile └── readme.md ├── README.md └── notebooks ├── Dockerfile └── readme.md /persistence/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /persistence/.gitignore: -------------------------------------------------------------------------------- 1 | data/* 2 | !data/.gitkeep 3 | -------------------------------------------------------------------------------- /hello-world/hello.C: -------------------------------------------------------------------------------- 1 | void hello() 2 | { 3 | std::cout << "Hello world!" << std::endl; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /persistence/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rootproject/root-ubuntu16 2 | 3 | # Run the following commands as super user (root): 4 | USER root 5 | 6 | # Create a user that does not have root privileges 7 | ARG username=physicist 8 | RUN userdel builder && useradd --create-home --home-dir /home/${username} ${username} 9 | ENV HOME /home/${username} 10 | 11 | # Switch to our newly created user 12 | USER ${username} 13 | 14 | # Our working directory will be in a mounted directory named data 15 | WORKDIR /data 16 | 17 | # When starting the container and no command is started, run macro in ROOT and quit. 18 | CMD ["root.exe", "-q", "/usr/local/share/doc/root/tutorials/dataframe/tdf002_dataModel.C"] 19 | -------------------------------------------------------------------------------- /hello-world/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rootproject/root-ubuntu16 2 | 3 | # Run the following commands as super user (root): 4 | USER root 5 | 6 | # Create a user that does not have root privileges 7 | ARG username=physicist 8 | RUN userdel builder && useradd --create-home --home-dir /home/${username} ${username} 9 | ENV HOME /home/${username} 10 | 11 | # Switch to our newly created user 12 | USER ${username} 13 | 14 | # Our working directory will be in our home directory where we have permissions 15 | WORKDIR /home/${username} 16 | 17 | # Copy the hello.c file to our current working directory 18 | COPY hello.C . 19 | 20 | # When starting the container and no command is started, run hello.c in ROOT and quit. 21 | CMD ["root.exe", "-q", "hello.C"] 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Examples 2 | These examples shows how to use the [ROOT Docker containers](https://hub.docker.com/r/rootproject/root-ubuntu16/) in different use-cases. It is recommended to clone this repository when following these examples. These examples can also serve as basline for how other ROOT Dockerfiles are created as they strive to follow [best practices in regards to Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/). 3 | 4 | ### Hello-world 5 | Shows how to create a basic Dockerfile together with a hello world macro. 6 | 7 | ### Persistence 8 | Shows how to persist data in mounted directories. 9 | 10 | ### Notebooks 11 | Example on how to craete a Docker container that will host a notebook locally. 12 | 13 | -------------------------------------------------------------------------------- /hello-world/readme.md: -------------------------------------------------------------------------------- 1 | ## Hello-world 2 | This example shows how to create an image containing a simple macro printing a hello world in ROOT. It demonstrates how to extend the dockerfile on a basic level for distribution. 3 | 4 | ### Building 5 | To build the container: 6 | ``` 7 | $ docker build -t root-hello-world . 8 | ``` 9 | ### Running 10 | To run the container: 11 | ``` 12 | $ docker run --rm -it root-hello-world 13 | ``` 14 | This will run the command specified with the CMD directive in the Dockerfile (`root.exe -q hello.C`). 15 | It is also possible to specify the entire command to run in ROOT: 16 | ``` 17 | $ docker run --rm -it root-hello-world root.exe hello.C 18 | ``` 19 | This will run hello.C and leave the user in the ROOT prompt. 20 | Another possibility is to open a bash shell inside the hello-world image: 21 | ``` 22 | $ docker run --rm -it root-hello-world bash 23 | ``` 24 | -------------------------------------------------------------------------------- /notebooks/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rootproject/root-ubuntu16 2 | 3 | # Run the following commands as super user (root): 4 | USER root 5 | 6 | # Install required packages for notebooks 7 | RUN apt-get update && apt-get install -y python-pip && pip install --upgrade pip && pip install \ 8 | jupyter \ 9 | metakernel \ 10 | zmq \ 11 | && rm -rf /var/lib/apt/lists/* 12 | 13 | # Create a user that does not have root privileges 14 | ARG username=physicist 15 | RUN userdel builder && useradd --create-home --home-dir /home/${username} ${username} 16 | ENV HOME /home/${username} 17 | 18 | WORKDIR /home/${username} 19 | 20 | # Add some example notebooks 21 | ADD http://root.cern.ch/doc/master/notebooks/mp201_parallelHistoFill.C.nbconvert.ipynb mp201_parallelHistoFill.C.nbconvert.ipynb 22 | ADD http://root.cern.ch/doc/master/notebooks/tdf007_snapshot.py.nbconvert.ipynb tdf007_snapshot.py.nbconvert.ipynb 23 | 24 | # Create the configuration file for jupyter and set owner 25 | RUN echo "c.NotebookApp.ip = '*'" > jupyter_notebook_config.py && chown ${username} * 26 | 27 | # Switch to our newly created user 28 | USER ${username} 29 | 30 | # Allow incoming connections on port 8888 31 | EXPOSE 8888 32 | 33 | # Start ROOT with the --notebook flag to fire up the container 34 | CMD ["root", "--notebook"] 35 | -------------------------------------------------------------------------------- /persistence/readme.md: -------------------------------------------------------------------------------- 1 | ## Persistence 2 | This example show how data can be persisted outside the containers. With containers, persistent data should not be stored in the container itself. One approach is to mount a directory from the host and store the data there. Although application data is recommended to be stored in [data volumes](https://docs.docker.com/engine/admin/volumes/#more-details-about-mount-types), this example binds a `data` directory to the container and stores files in this directory. 3 | 4 | ### Building 5 | To build the container: 6 | ``` 7 | $ docker build -t root-persistence . 8 | ``` 9 | ### Running 10 | To run the container: 11 | ``` 12 | $ docker run --rm -v $(pwd)/data:/data -it root-persistence 13 | ``` 14 | This will run the [TDataFrame data model tutorial](https://root.cern/doc/master/tdf002__dataModel_8C.html) and save the output in ./data on the host: 15 | ``` 16 | docker-examples/persistence$ ls data 17 | tdf002_dataModel.root tracks_n.png tracks_pt.png tracks_Wpt.png 18 | ``` 19 | It is also possible to run other ROOT tutorials by specifying it to root.exe: 20 | ``` 21 | $ docker run --rm -v $(pwd)/data:/data -it root-persistence \ 22 | root.exe -q /usr/local/share/doc/root/tutorials/dataframe/tdf004_cutFlowReport.C 23 | ``` 24 | 25 | The previous command will store the output to tdf004_cutFlowReport.root under `data`. 26 | -------------------------------------------------------------------------------- /notebooks/readme.md: -------------------------------------------------------------------------------- 1 | ## Notebooks 2 | ROOT can also start with Jupyter notebooks [using the --notebook flag](https://root.cern.ch/how/how-create-rootbook). This example shows how to craete a Docker file that will act as a ROOT Jupyter web service listening on port 8888. 3 | 4 | ### Building 5 | To build the container: 6 | ``` 7 | $ docker build -t root-notebooks . 8 | ``` 9 | ### Running 10 | To run the container: 11 | ``` 12 | $ docker run --name root-notebooks -it root-notebooks 13 | ``` 14 | 15 | This will start the container listening on port 8888. Using the `--name root-notebooks` also makes it only possible to spawn one container of this image. Take note of the printed URL in the console. Instead entering http://localhost:8888/?token=secrettoken, localhost needs to be replaced by the IP address of the container. This can be found by opening a new terminal and find the newly spawned contained through `docker inspect root-notebook`: 16 | ``` 17 | $ docker inspect root-notebooks | grep IPAddress 18 | "SecondaryIPAddresses": null, 19 | "IPAddress": "172.17.0.2", 20 | "IPAddress": "172.17.0.2", 21 | ``` 22 | 23 | The IP address will differ depending on how many containers the host is running and/or which operating system it is running. Windows containers will always have a fixed IP address of 10.0.75.2. 24 | 25 | After exiting the container through Ctrl+C, the root-notebooks container can be spawned again by running: 26 | ``` 27 | $ docker start root-notebook 28 | ``` 29 | 30 | ### Note about persistence 31 | This tutorial does not focus on keeping the data in the docker container. It is therefore suggested to store the data having to be persistent either in a mounted directory or in a data volume. See the persistence example for more information. --------------------------------------------------------------------------------