<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Joesterle</id>
	<title>AG Euler Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Joesterle"/>
	<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php/Special:Contributions/Joesterle"/>
	<updated>2026-05-17T09:23:00Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=199</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=199"/>
		<updated>2025-10-28T13:12:08Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1: 172.29.0.161&lt;br /&gt;
* eul2: 172.29.0.162&lt;br /&gt;
* eul3: 172.29.0.163&lt;br /&gt;
* eul4: 172.29.0.164&lt;br /&gt;
* eul5: 172.29.0.165&lt;br /&gt;
* eul6: 172.29.0.166&lt;br /&gt;
* gpu1: 172.29.0.51&lt;br /&gt;
* gpu2: 172.29.0.52&amp;lt;br /&amp;gt;&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=198</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=198"/>
		<updated>2025-10-28T13:09:47Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1: 172.29.0.161&lt;br /&gt;
* eul2: 172.29.0.162&lt;br /&gt;
* eul3: 172.29.0.163&lt;br /&gt;
* eul4: 172.29.0.164&lt;br /&gt;
* eul5: 172.29.0.165&lt;br /&gt;
* eul5: 172.29.0.166&lt;br /&gt;
* gpu1: 172.29.0.51&lt;br /&gt;
* gpu2: 172.29.0.52&amp;lt;br /&amp;gt;&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=197</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=197"/>
		<updated>2023-12-20T10:10:15Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1: 172.29.0.148&lt;br /&gt;
* eul2: 172.29.0.149&lt;br /&gt;
* eul3: 172.29.0.150&lt;br /&gt;
* eul4: 172.29.0.184&lt;br /&gt;
* eul5: 172.29.0.185&lt;br /&gt;
* gpu4: 172.29.0.54 (Use only for GPU computation)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=196</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=196"/>
		<updated>2023-12-20T10:09:24Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Accessing the cluster nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1: 172.29.0.148&lt;br /&gt;
* eul2: 172.29.0.149&lt;br /&gt;
* eul3: 172.29.0.150&lt;br /&gt;
* eul4: 172.29.0.184&lt;br /&gt;
* eul5: 172.29.0.185&lt;br /&gt;
* gpu4: 172.29.0.54 (Shared among multiple CIN groups!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=195</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=195"/>
		<updated>2023-01-10T16:12:13Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1: 172.29.0.148&lt;br /&gt;
* eul2: 172.29.0.149&lt;br /&gt;
* eul3: 172.29.0.150&lt;br /&gt;
* gpu3: 172.29.0.53 (Shared among multiple CIN groups!)&lt;br /&gt;
* gpu4: 172.29.0.54 (Shared among multiple CIN groups!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --jupytertoken some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=194</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=194"/>
		<updated>2022-11-28T09:57:36Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1: 172.29.0.148&lt;br /&gt;
* eul2: 172.29.0.149&lt;br /&gt;
* eul3: 172.29.0.150&lt;br /&gt;
* gpu3: 172.29.0.53 (Shared among multiple CIN groups!)&lt;br /&gt;
* gpu4: 172.29.0.54 (Shared among multiple CIN groups!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=193</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=193"/>
		<updated>2022-11-28T09:57:09Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Accessing the cluster nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1: 172.29.0.148&lt;br /&gt;
* eul2: 172.29.0.149&lt;br /&gt;
* eul3: 172.29.0.150&lt;br /&gt;
* gpu3: 172.29.0.53&lt;br /&gt;
* gpu4: 172.29.0.54&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=192</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=192"/>
		<updated>2022-11-21T15:38:03Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Starting docker containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -d --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -d --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=191</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=191"/>
		<updated>2022-11-07T10:38:18Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Stimulus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations on how your stimulus will therefore look on the retina:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
Igor (ScanM) will save the absolute positions of the recording in XCoord_um and YCoord_um.&lt;br /&gt;
This is how these axes are relative to the chamber and retina;&lt;br /&gt;
&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;br /&gt;
&lt;br /&gt;
If you open a ScanM file in Igor on your computer and display it with e.g. Automated Cell Lab, it will look something like this (the colormap and contrast will be different per default). &lt;br /&gt;
The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
&lt;br /&gt;
[[File:SetupViewIgor.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
In the setup rooms there is another flip of left and right to align what you see on the screen with the chamber:&lt;br /&gt;
On the setup PCs (setup 1 and setup 3), the light artifact will appear on the right, whereas the light artifact will be on the left if you open the files on your PC.&lt;br /&gt;
&lt;br /&gt;
[[File:SetupVSdefaultViewIgor.png|thumb|none|upright=0.35]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=190</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=190"/>
		<updated>2022-11-07T10:34:51Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Igor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
Igor (ScanM) will save the absolute positions of the recording in XCoord_um and YCoord_um.&lt;br /&gt;
This is how these axes are relative to the chamber and retina;&lt;br /&gt;
&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;br /&gt;
&lt;br /&gt;
If you open a ScanM file in Igor on your computer and display it with e.g. Automated Cell Lab, it will look something like this (the colormap and contrast will be different per default). &lt;br /&gt;
The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
&lt;br /&gt;
[[File:SetupViewIgor.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
In the setup rooms there is another flip of left and right to align what you see on the screen with the chamber:&lt;br /&gt;
On the setup PCs (setup 1 and setup 3), the light artifact will appear on the right, whereas the light artifact will be on the left if you open the files on your PC.&lt;br /&gt;
&lt;br /&gt;
[[File:SetupVSdefaultViewIgor.png|thumb|none|upright=0.35]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=189</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=189"/>
		<updated>2022-11-07T10:34:28Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Igor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
Igor (ScanM) will save the absolute positions of the recording in XCoord_um and YCoord_um (see also above).&lt;br /&gt;
This is how these axes are relative to the chamber and retina.&lt;br /&gt;
&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;br /&gt;
&lt;br /&gt;
If you open a ScanM file in Igor on your computer and display it with e.g. Automated Cell Lab, it will look something like this (the colormap and contrast will be different per default). &lt;br /&gt;
The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
&lt;br /&gt;
[[File:SetupViewIgor.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
In the setup rooms there is another flip of left and right to align what you see on the screen with the chamber:&lt;br /&gt;
On the setup PCs (setup 1 and setup 3), the light artifact will appear on the right, whereas the light artifact will be on the left if you open the files on your PC.&lt;br /&gt;
&lt;br /&gt;
[[File:SetupVSdefaultViewIgor.png|thumb|none|upright=0.35]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=188</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=188"/>
		<updated>2022-11-07T10:33:45Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Igor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor on your computer and display it with e.g. Automated Cell Lab, it will look something like this (the colormap and contrast will be different per default). &lt;br /&gt;
The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
&lt;br /&gt;
[[File:SetupViewIgor.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
In the setup rooms there is another flip of left and right to align what you see on the screen with the chamber:&lt;br /&gt;
On the setup PCs (setup 1 and setup 3), the light artifact will appear on the right, whereas the light artifact will be on the left if you open the files on your PC.&lt;br /&gt;
&lt;br /&gt;
[[File:SetupVSdefaultViewIgor.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
Igor (ScanM) will save the absolute positions of the recording in XCoord_um and YCoord_um (see also above).&lt;br /&gt;
This is how these axes are relative to the chamber and retina.&lt;br /&gt;
&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=187</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=187"/>
		<updated>2022-11-07T10:30:44Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Igor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor on your computer and display it with e.g. Automated Cell Lab, it will look something like this (the colormap and contrast will be different per default). &lt;br /&gt;
The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
&lt;br /&gt;
[[File:SetupViewIgor.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
In the setup rooms there is another flip of left and right to align what you see on the screen with the chamber:&lt;br /&gt;
On the setup PCs (setup 1 and setup 3), the light artifact will appear on the right, whereas the light artifact will be on the left if you open the files on your PC.&lt;br /&gt;
&lt;br /&gt;
[[File:SetupVSdefaultViewIgor.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:SetupVSdefaultViewIgor.png&amp;diff=186</id>
		<title>File:SetupVSdefaultViewIgor.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:SetupVSdefaultViewIgor.png&amp;diff=186"/>
		<updated>2022-11-07T10:30:05Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SetupVSdefaultViewIgor&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:SetupViewIgor.png&amp;diff=185</id>
		<title>File:SetupViewIgor.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:SetupViewIgor.png&amp;diff=185"/>
		<updated>2022-11-07T10:28:30Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SetupViewIgor&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:DefaultViewIgor.png&amp;diff=184</id>
		<title>File:DefaultViewIgor.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:DefaultViewIgor.png&amp;diff=184"/>
		<updated>2022-11-07T10:28:18Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DefaultViewIgor&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=183</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=183"/>
		<updated>2022-11-07T10:09:17Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Igor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
The Igor configuration in the Setup rooms are different from the default settings, i.e. the settings on you computer.&lt;br /&gt;
On the setup PCs (setup 1 and setup 3), the light artifact will appear on the right, whereas the light artifact will be on the left if you open the files on your PC.&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor on your computer and display it with e.g. Automated Cell Lab, it will look something like this (the colormap and contrast will be different per default). &lt;br /&gt;
The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
Here are how the axis are relative to the retina:&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=182</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=182"/>
		<updated>2022-11-07T09:40:24Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Igor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Lab, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
Here are how the axis are relative to the retina:&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=181</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=181"/>
		<updated>2022-11-07T09:36:48Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Igor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
Here are how the axis are relative to the retina:&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
So if you subtract the position of the optic-disk to go from absolute values for XCoord_um and YCoord_um to relative values rel_XCoord_um and rel_YCoord_um:&lt;br /&gt;
&lt;br /&gt;
# rel_XCoord_um &amp;lt; 0 means dorsal&lt;br /&gt;
# rel_XCoord_um &amp;gt; 0 means ventral&lt;br /&gt;
# rel_YCoord_um &amp;lt; 0 means temporal (right retina) or nasal (left retina)&lt;br /&gt;
# rel_YCoord_um &amp;gt; 0 means nasal (right retina) or temporal (left retina)&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=180</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=180"/>
		<updated>2022-11-07T09:33:11Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs:&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
Here are how the axis are relative to the retina:&lt;br /&gt;
[[File:SetupOrientationRetina.png|thumb|none|upright=0.35]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:SetupOrientationRetina.png&amp;diff=179</id>
		<title>File:SetupOrientationRetina.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:SetupOrientationRetina.png&amp;diff=179"/>
		<updated>2022-11-07T09:32:39Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SetupOrientationRetina&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=178</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=178"/>
		<updated>2022-11-04T14:49:35Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Stimulus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Per default the stimulus will look as follows in QDSPy on your own screen:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from bottom to top&lt;br /&gt;
&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs.&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb|none|upright=0.35]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=177</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=177"/>
		<updated>2022-11-04T14:48:00Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 3:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs.&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb|none|upright=0.35]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=176</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=176"/>
		<updated>2022-11-04T14:47:41Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
Setup 2:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb|none|upright=0.35]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs.&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=175</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=175"/>
		<updated>2022-11-04T14:46:46Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
Setup 1:&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb]]&lt;br /&gt;
Setup 2:&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs.&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=174</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=174"/>
		<updated>2022-11-04T14:38:30Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
Here are visual explanations:&lt;br /&gt;
&lt;br /&gt;
[[File:Setup1StimulusOrientation.png|thumb]]&lt;br /&gt;
[[File:Setup3StimulusOrientation.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs.&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Setup3StimulusOrientation.png&amp;diff=173</id>
		<title>File:Setup3StimulusOrientation.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Setup3StimulusOrientation.png&amp;diff=173"/>
		<updated>2022-11-04T14:38:05Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Setup3StimulusOrientation&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Setup1StimulusOrientation.png&amp;diff=172</id>
		<title>File:Setup1StimulusOrientation.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Setup1StimulusOrientation.png&amp;diff=172"/>
		<updated>2022-11-04T14:37:44Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Setup1StimulusOrientation&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=171</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=171"/>
		<updated>2022-11-04T13:59:47Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs.&lt;br /&gt;
[[File:IgorRecCenterNew.png|thumb]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:IgorRecCenterNew.png&amp;diff=170</id>
		<title>File:IgorRecCenterNew.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:IgorRecCenterNew.png&amp;diff=170"/>
		<updated>2022-11-04T13:59:36Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Igor coordinates&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=169</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=169"/>
		<updated>2022-11-04T13:29:47Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this.&lt;br /&gt;
Note the flip of x and y and the signs.&lt;br /&gt;
&lt;br /&gt;
[[File:Igor rec center.png|thumb|Center of channel in Igor.]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=168</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=168"/>
		<updated>2022-11-04T13:28:51Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this:&lt;br /&gt;
&lt;br /&gt;
[[File:Igor rec center.png|thumb|Center of channel in Igor.]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=167</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=167"/>
		<updated>2022-11-04T13:28:10Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Stimulus ==&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
&lt;br /&gt;
== Igor ==&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this:&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=166</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=166"/>
		<updated>2022-11-04T13:27:44Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Stimulus&lt;br /&gt;
&lt;br /&gt;
Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;br /&gt;
&lt;br /&gt;
# Igor&lt;br /&gt;
&lt;br /&gt;
If you open a file in Igor (ScanM) and display it with e.g. Automated Cell Label, it will look something like this. The center coordinates (which is also the stimulus center) will be like this:&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Igor_rec_center.png&amp;diff=165</id>
		<title>File:Igor rec center.png</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Igor_rec_center.png&amp;diff=165"/>
		<updated>2022-11-04T13:26:59Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Recording center of Igor file&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Main_Page&amp;diff=164</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Main_Page&amp;diff=164"/>
		<updated>2022-11-04T12:46:13Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Experimental */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the AG Euler wiki. &lt;br /&gt;
Feel free to contribute additional content.&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
&lt;br /&gt;
* [[Email Addresses]]&lt;br /&gt;
** needs update&lt;br /&gt;
* [[Internal Phone Numbers]]&lt;br /&gt;
** needs update&lt;br /&gt;
&lt;br /&gt;
==Experimental==&lt;br /&gt;
&lt;br /&gt;
*[[Ringer Solution]]&lt;br /&gt;
* [[Dissection]]&lt;br /&gt;
* [[Data Storage and Data Structure]]&lt;br /&gt;
* [[Orientation]]&lt;br /&gt;
&lt;br /&gt;
==Computational==&lt;br /&gt;
&lt;br /&gt;
* [[Docker Containers]]&lt;br /&gt;
* [[Igor]]&lt;br /&gt;
* [[Cluster]]&lt;br /&gt;
** needs update&lt;br /&gt;
* [[Datajoint]]&lt;br /&gt;
** needs update&lt;br /&gt;
* [[Jupyter]]&lt;br /&gt;
** needs update&lt;br /&gt;
* [[MATLAB]]&lt;br /&gt;
** needs update&lt;br /&gt;
* [[Python]]&lt;br /&gt;
** needs update&lt;br /&gt;
* [[PyCharm]]&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=163</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=163"/>
		<updated>2022-11-04T12:45:47Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you design a stimulus in QDSpy you can check its orienation by playing these stimuli and your stimulus.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=162</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=162"/>
		<updated>2022-11-04T12:44:36Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
&lt;br /&gt;
- MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
&lt;br /&gt;
- MB90_deg: goes from right to left&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=161</id>
		<title>Orientation</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Orientation&amp;diff=161"/>
		<updated>2022-11-04T12:43:55Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: Created page with &amp;quot;Setup 1 and setup 3 have different stimulus orientation. The following two stimuli can get used to test the stimulus orientation on a setup. [[File:Test orientation.zip|thumb]...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Setup 1 and setup 3 have different stimulus orientation.&lt;br /&gt;
The following two stimuli can get used to test the stimulus orientation on a setup.&lt;br /&gt;
[[File:Test orientation.zip|thumb]]&lt;br /&gt;
&lt;br /&gt;
In 2022, the orientation of the stimulus as seen by the retina were as follows:&lt;br /&gt;
&lt;br /&gt;
Setup 1:&lt;br /&gt;
MB0_deg: goes from front (ventral / curtain) to back (dorsal)&lt;br /&gt;
MB90_deg: goes from right to left&lt;br /&gt;
&lt;br /&gt;
Setup 3:&lt;br /&gt;
MB0_deg: goes from back (dorsal) to front (ventral / curtain)&lt;br /&gt;
MB90_deg: goes from right to left&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Test_orientation.zip&amp;diff=160</id>
		<title>File:Test orientation.zip</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=File:Test_orientation.zip&amp;diff=160"/>
		<updated>2022-11-04T12:42:15Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Stimuli to test orienation of setup.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=159</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=159"/>
		<updated>2022-04-05T14:47:26Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources:/gpfs01/euler/data/Resources:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=158</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=158"/>
		<updated>2022-03-28T09:49:22Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Starting docker containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=157</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=157"/>
		<updated>2022-03-28T09:49:01Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Starting docker containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** This should be a number well above 1000.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. &lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=156</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=156"/>
		<updated>2022-03-28T09:48:23Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Instructions to build and run docker containers on cluster nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. Usually it should also be well above 1000.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport pppp --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=155</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=155"/>
		<updated>2022-03-28T09:47:35Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Instructions to build and run docker containers on cluster nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;6789&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. Usually it should also be well above 1000.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=154</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=154"/>
		<updated>2022-03-28T09:46:29Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
TLDR:&lt;br /&gt;
```bash&lt;br /&gt;
ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xxx:pppp&lt;br /&gt;
ssh eulX&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh eulX&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;eul1&amp;lt;/code&amp;gt;).&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command: &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/code&amp;gt; where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below):&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication run &amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;6789&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. Usually it should also be well above 1000.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=153</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=153"/>
		<updated>2022-03-28T09:38:29Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Starting docker containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh nodename&amp;lt;/code&amp;gt;.&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command&lt;br /&gt;
&amp;lt;pre&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/pre&amp;gt;&lt;br /&gt;
where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below).&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication just run &lt;br /&gt;
&amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this. You have use a script of the group you are in (AG Euler: agte_xx, AG Berens. agpb_xx)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;6789&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. Usually it should also be well above 1000.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=152</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=152"/>
		<updated>2022-03-28T09:35:17Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh nodename&amp;lt;/code&amp;gt;.&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command&lt;br /&gt;
&amp;lt;pre&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/pre&amp;gt;&lt;br /&gt;
where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below).&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication just run &lt;br /&gt;
&amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;6789&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. Usually it should also be well above 1000.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=151</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=151"/>
		<updated>2022-03-28T09:33:29Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: /* Starting docker containers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh nodename&amp;lt;/code&amp;gt;.&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command&lt;br /&gt;
&amp;lt;pre&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/pre&amp;gt;&lt;br /&gt;
where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below).&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication just run &lt;br /&gt;
&amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;6789&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. Usually it should also be well above 1000.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
** If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error. You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;. This can happen for several reasons. Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
	<entry>
		<id>https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=150</id>
		<title>Docker Containers</title>
		<link rel="alternate" type="text/html" href="https://cin-10.medizin.uni-tuebingen.de/eulerwiki/index.php?title=Docker_Containers&amp;diff=150"/>
		<updated>2022-03-28T09:29:37Z</updated>

		<summary type="html">&lt;p&gt;Joesterle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you want to visit the old page: [[Docker (deprecated)]]&lt;br /&gt;
&lt;br /&gt;
== Instructions to build and run docker containers on cluster nodes ==&lt;br /&gt;
=== Accessing the cluster nodes ===&lt;br /&gt;
To access the cluster nodes you need to establish a ssh connection. This can be done from the terminal (natively under Ubuntu or using Cygwin under Windows). You first need to ssh to the cluster headnode (&amp;lt;code&amp;gt;ssh 172.25.250.112 -p 60222&amp;lt;/code&amp;gt;). Authentication works with your LDAP/CIN useraccount and password. If your local username differs from your LDAP account name you have to use &amp;lt;code&amp;gt;ssh username@172.25.250.112 -p 60222&amp;lt;/code&amp;gt;. From there you can access the cluster nodes via &amp;lt;code&amp;gt;ssh nodename&amp;lt;/code&amp;gt;.&lt;br /&gt;
If you want to run a docker container with a jupyter notebook server on the cluster node and want to access it from your browser the usual way (opening [http://localhost:8888 localhost:8888]), a ssh tunnel to this cluster node is needed. Therefore you ssh to the cluster using the command&lt;br /&gt;
&amp;lt;pre&amp;gt;ssh username@172.25.250.112 -p 60222 -L 8888:172.29.0.xx:pppp&amp;lt;/pre&amp;gt;&lt;br /&gt;
where the second IP address has to be the one corresponding to the clusternode and &amp;lt;code&amp;gt;pppp&amp;lt;/code&amp;gt; is the port number used by your docker container (see below).&lt;br /&gt;
&lt;br /&gt;
Cluster node IPs:&lt;br /&gt;
* eul1 172.29.0.148&lt;br /&gt;
* eul2 172.29.0.149&lt;br /&gt;
* eul3 172.29.0.150&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have troubles with the ssh key authentication just run &lt;br /&gt;
&amp;lt;pre&amp;gt; ssh-keygen -R &amp;quot;hostname&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
(with hostname = eulX) and accept the new key when you ssh to the respective node.&lt;br /&gt;
&lt;br /&gt;
Tip: You can also find the node IP by calling &amp;lt;code&amp;gt;ip a | grep 172.29&amp;lt;/code&amp;gt; when you are on that node.&lt;br /&gt;
&lt;br /&gt;
=== Building and running docker containers ===&lt;br /&gt;
Disclaimer: Our docker containers contain special functionality to integrate LDAP user accounts and our home directories. The following instruction doesn&#039;t work out of the box with any random docker container.&lt;br /&gt;
==== Building a docker container ====&lt;br /&gt;
To check which docker images are available on a cluster node call &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on that node.&lt;br /&gt;
&lt;br /&gt;
If you want to build an image that does not yet exist do the following:&lt;br /&gt;
&lt;br /&gt;
* Clone this https://github.com/eulerlab/docker (or this https://github.com/berenslab/docker) GitHub repo to a folder &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt; where you want to have your docker files stored.&lt;br /&gt;
** This is a private repo, so you need to be a member of eulerlab (or berenslab).&lt;br /&gt;
*** The eulerlab repo is based on the berenslab repo.&lt;br /&gt;
** You may want to fork the repo before you clone it. This might not be necessary for many users, though.&lt;br /&gt;
* Go to &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Run e.g. &amp;lt;code&amp;gt;docker build -t berenslab/deeplearning:latest ./berenslab/deeplearning&amp;lt;/code&amp;gt; which builds the container called &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt; with the tag &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; from the directory &amp;lt;code&amp;gt;./berenslab/deeplearning.&amp;lt;/code&amp;gt;&lt;br /&gt;
** If you don&#039;t state a tag, it will default to &amp;lt;code&amp;gt;latest&amp;lt;/code&amp;gt; which is fine, but if there are multiple similar images, please use tags.&lt;br /&gt;
* Run &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; to see your docker image listed&lt;br /&gt;
&lt;br /&gt;
Some docker images depend on other local images, meaning that you have to build the images they depend on first. For example &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt; requires an existing image &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Otherwise they typically depend on remote images, e.g. &amp;lt;code&amp;gt;berenslab/deeplearning&amp;lt;/code&amp;gt;, you typically do not want to build a container from scratch. If you want to create a new docker file and its respective image, first have a look at how the files are structured in https://github.com/eulerlab/docker.&lt;br /&gt;
&lt;br /&gt;
* Then create a folder that is or includes your username within &amp;lt;code&amp;gt;your-docker-folder&amp;lt;/code&amp;gt;, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton&amp;lt;/code&amp;gt;&lt;br /&gt;
* Within create a folder with a name that describes your image, e.g. &amp;lt;code&amp;gt;your-docker-folder/inewton/deeplearning&amp;lt;/code&amp;gt;&lt;br /&gt;
* To create the image from this dockerfile call &amp;lt;code&amp;gt;docker build -t inewton/deeplearning ./inewton/deeplearning&amp;lt;/code&amp;gt; to have an image name everyone else on this node can interpret.&lt;br /&gt;
* Sometimes you may want to save this image to a tar file on your harddrive for reproducibility using &amp;lt;code&amp;gt;docker save image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you just want to build the standard images (no debugging etc.), it makes sense to use &amp;lt;code&amp;gt;--no-cache&amp;lt;/code&amp;gt; to save space on the node and don&#039;t store intermediate images from the build steps&lt;br /&gt;
&lt;br /&gt;
==== Starting docker containers ====&lt;br /&gt;
&lt;br /&gt;
TLDR:&lt;br /&gt;
To start a new container call the following command replacing the arguments with meaningful values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix -v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info:&lt;br /&gt;
To start a docker container with a running jupyter notebook server and correct user permissions, we use one of the scripts &amp;lt;code&amp;gt;agte-docker&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agte-docker_gpu&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;agpb-docker&amp;lt;/code&amp;gt;.&lt;br /&gt;
Note that only the second and third support GPU usage. For this reason they also only work on nodes with GPUs.&lt;br /&gt;
Calling the script will look something like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The last argument (e.g. &amp;lt;code&amp;gt;berenslab/datajoint&amp;lt;/code&amp;gt;) specifies the image the container will be based on.&lt;br /&gt;
** You can list all available images calling &amp;lt;code&amp;gt;docker images&amp;lt;/code&amp;gt; on a node. If no images are available you have to build them first (see below).&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--name&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;container_name_suffix&amp;lt;/code&amp;gt;) should be a suffix that helps to identify specific containers for yourself.&lt;br /&gt;
** The script will automatically add your username to the container name.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterport&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;6789&amp;lt;/code&amp;gt;) is the port number used for the ssh tunnel that allows you to access the jupyter notebook server.&lt;br /&gt;
** It has to be free, i.e. not used by other container. You can check this by running &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt; to list allrunning containers on that node. Usually it should also be well above 1000.&lt;br /&gt;
* The argument after &amp;lt;code&amp;gt;--jupyterpass&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;some_password&amp;lt;/code&amp;gt;) can be used to specify a passwort to access the jupyter notebook later in the server.&lt;br /&gt;
&lt;br /&gt;
If you want to use a GPU you want to ensure that you are the only one on a specific GPU and that your calculations use only one of the two GPUs of the node. Therefore run the script with&lt;br /&gt;
&amp;lt;pre&amp;gt;GPU=X python agte-docker run -ti --jupyterport 6789 --jupyterpass some_password --name container_name_suffix berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
with either &amp;lt;code&amp;gt;GPU=0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GPU=1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The container name is then automatically set as &amp;lt;code&amp;gt;gpuX-username&amp;lt;/code&amp;gt; and everyone can see which GPUs are already taken.&lt;br /&gt;
&lt;br /&gt;
To start a container in interactive mode with bash and no jupyter notebook server call&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python agte-docker run -ti --jupyterport pppp --name container_name berenslab/datajoint bash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Accessing additional directories =====&lt;br /&gt;
To work with datajoint and any experimental data you need to make two additional directories available from inside the docker container, therefore include &amp;lt;pre&amp;gt;-v /gpfs01/euler/data/Data:/gpfs01/euler/data/Data:ro -v /gpfs01/euler/data/Resources/Stimulus:/gpfs01/euler/data/Resources/Stimulus:ro&amp;lt;/pre&amp;gt; in the run command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Limit the container to a certain number of CPUs =====&lt;br /&gt;
Often it is useful to constrain your container such that it doesn&#039;t use all CPUs. For example, if someone else wants to access the GPUs they need at least 1 CPU.&lt;br /&gt;
Therefore, when stating a container add the following to use e.g. only first 30 CPUs.&lt;br /&gt;
&amp;lt;pre&amp;gt;--cpuset-cpus 0-29&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The whole command might look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;python agte-docker run -d --cpuset-cpus X-Y --jupyterport pppp --jupyterpass some_password --name container_name berenslab/datajoint&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Trouble-Shooting =====&lt;br /&gt;
&lt;br /&gt;
* Always make sure the jupyterport is not already used.&lt;br /&gt;
* Always make sure the container_name is not already used.&lt;br /&gt;
* Do not state parameters after the image name (only before).&lt;br /&gt;
* Container stops directly after creating it:&lt;br /&gt;
If you create a new container with &amp;lt;code&amp;gt;agte-docker run&amp;lt;/code&amp;gt; it may happen that the docker stops directly because of an error.&lt;br /&gt;
You will not find it with &amp;lt;code&amp;gt;docker ps&amp;lt;/code&amp;gt;, but only with &amp;lt;code&amp;gt;docker ps -a&amp;lt;/code&amp;gt;.&lt;br /&gt;
This can happen for several reasons.&lt;br /&gt;
Use &amp;lt;code&amp;gt;docker container logs container_name&amp;lt;/code&amp;gt; to check the logs.&lt;br /&gt;
&lt;br /&gt;
==== Interactive container mode ====&lt;br /&gt;
These commands starts the docker container in the detached mode which means it runs in the background. If in addition you want to enter the docker container with a bash you can call&lt;br /&gt;
&amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Creating an image from a container ===&lt;br /&gt;
Sometimes you install things not using a docker file but within a container. While this should be avoided when it can be, sometimes this is very useful. If you have done so, you may want to create an image from your container, to be able to reuse it. Make sure to document what changes you have done to your container if it was anything non trivial.&lt;br /&gt;
&lt;br /&gt;
To create an image of the container first do the following to create an image:&lt;br /&gt;
*&amp;lt;code&amp;gt;docker commit your_container_name&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;docker tag id_of_the_just_created_container your_image_name&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Saving an image to your harddrive ===&lt;br /&gt;
To save an image call: &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a tar file of you docker image.&lt;br /&gt;
&lt;br /&gt;
=== Copying an image to another note ===&lt;br /&gt;
If you want to copy an image to another node you can do the following:&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt;to a node with an image you want&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt;to some folder you created for docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker save some_image_name &amp;gt; some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ssh&amp;lt;/code&amp;gt; to another node&lt;br /&gt;
* &amp;lt;code&amp;gt;cd&amp;lt;/code&amp;gt; to the same folder again with the docker images&lt;br /&gt;
* &amp;lt;code&amp;gt;docker load --input some_filename.tar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basic usage of containers==&lt;br /&gt;
&lt;br /&gt;
===Install packages in running containers===&lt;br /&gt;
Typically you want to add all (python etc) packages you will need to your Dockerfile before creating your Docker image. &lt;br /&gt;
In practice however, you might want to install packages in running containers, to extent their functionality.&lt;br /&gt;
To do this execute you docker container: &amp;lt;pre&amp;gt;docker exec -u username -ti container_name bash&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your docker container, you almost &#039;&#039;&#039;always&#039;&#039;&#039; want to install packages using &amp;lt;code&amp;gt;sudo&amp;lt;/code&amp;gt;, because then they will be installed in the container only, and not in your home directory which will then be visible in other containers too, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;sudo pip install numpy&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Trouble shooting===&lt;br /&gt;
To check which python and pip version you are using type &amp;lt;code&amp;gt;python -V&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;pip -V&amp;lt;/code&amp;gt;. The pip python version should match your python version, and if not, set an alias or always use &amp;lt;code&amp;gt;pip3&amp;lt;/code&amp;gt; (not recommended).&lt;br /&gt;
&lt;br /&gt;
Inside your notebooks you can run &amp;lt;code&amp;gt;!python -V&amp;lt;/code&amp;gt; and check if the versions are matching.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip list -v&amp;lt;/code&amp;gt; lists all packages and their installation locations. Verify that packages you only want inside you docker containers are not installed in you home directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pip check&amp;lt;/code&amp;gt; checks for broken dependencies.&lt;/div&gt;</summary>
		<author><name>Joesterle</name></author>
	</entry>
</feed>