├── .gitignore ├── Dockerfile ├── README.md ├── connect_container_linux.sh ├── connect_container_mac.sh ├── run_docker.sh ├── run_screens_docker.sh └── set_up.sh /.gitignore: -------------------------------------------------------------------------------- 1 | gitconfig 2 | docker_identity 3 | docker_identity.pub 4 | authorized_keys -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nvidia/cuda:9.1-cudnn7-devel-ubuntu16.04 2 | 3 | MAINTAINER Aleksei Tiulpin, University of Oulu, Version 3.0 4 | 5 | 6 | # Parameters to re-create the user teh same way as in the system 7 | ARG HOST_USER 8 | ARG UID 9 | ARG GID 10 | 11 | # Setting up the system 12 | RUN apt-get update 13 | RUN apt-get upgrade -y 14 | RUN apt-get install -y libgtk2.0-dev 15 | RUN apt-get update && apt-get install -y --no-install-recommends \ 16 | build-essential \ 17 | cmake \ 18 | git \ 19 | curl \ 20 | vim \ 21 | ca-certificates \ 22 | libjpeg-dev \ 23 | libpng-dev \ 24 | unzip \ 25 | zip \ 26 | locales \ 27 | emacs \ 28 | libgl1-mesa-glx \ 29 | openssh-server \ 30 | screen \ 31 | libturbojpeg \ 32 | rsync \ 33 | wget 34 | 35 | RUN locale-gen --purge en_US.UTF-8 36 | RUN echo -e 'LANG="en_US.UTF-8"\nLANGUAGE="en_US:en"\n' > /etc/default/locale 37 | RUN dpkg-reconfigure --frontend=noninteractive locales 38 | 39 | # SSH access 40 | RUN mkdir /var/run/sshd 41 | RUN echo 'root:67923hjksdii$66%4!0+92' | chpasswd 42 | RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config 43 | 44 | # SSH login fix. Otherwise user is kicked off after login 45 | RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd 46 | 47 | ENV NOTVISIBLE "in users profile" 48 | RUN echo "export VISIBLE=now" >> /etc/profile 49 | RUN mkdir -p /root/.ssh/ 50 | 51 | # Creating the user 52 | RUN groupadd -g $GID $HOST_USER 53 | RUN useradd --create-home --home-dir /home/${HOST_USER}/ -u $UID -g $GID -s /bin/bash $HOST_USER 54 | RUN chown -R $UID:$GID /home/${HOST_USER}/ 55 | 56 | # Uner host's username privided we will setup anaconda and stuff 57 | USER $HOST_USER 58 | 59 | RUN mkdir -p /home/${HOST_USER}/.ssh/ 60 | RUN echo "export PATH=/home/${HOST_USER}/conda/bin:${PATH}" >> /home/${HOST_USER}/.bashrc 61 | 62 | # Getting conda 63 | RUN curl -o ~/miniconda.sh -O https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh 64 | RUN chmod +x ~/miniconda.sh && ~/miniconda.sh -b -p /home/${HOST_USER}/conda && rm ~/miniconda.sh 65 | ENV PATH=/home/${HOST_USER}/conda/bin:${PATH} 66 | RUN conda update -n base conda 67 | 68 | RUN conda install -y python=3.6 69 | RUN conda install -y numpy pyyaml scipy ipython openblas mkl matplotlib cython 70 | 71 | RUN pip install --ignore-installed pip -U -v 72 | RUN pip install --ignore-installed jpeg4py 73 | RUN pip install --ignore-installed tensorflow tensorboardx scikit-learn pandas jupyterlab keras 74 | RUN pip install --ignore-installed termcolor tqdm 75 | RUN pip install --ignore-installed opencv-python 76 | RUN pip install --ignore-installed http://download.pytorch.org/whl/cu91/torch-0.4.0-cp36-cp36m-linux_x86_64.whl 77 | RUN pip install --ignore-installed torchvision 78 | RUN pip install --ignore-installed pydicom 79 | RUN pip install --ignore-installed pretrainedmodels 80 | 81 | USER root 82 | RUN echo "${HOST_USER}" >> /etc/sudoers 83 | 84 | EXPOSE 22 85 | ENTRYPOINT ["/usr/sbin/sshd", "-D"] 86 | 87 | 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YADDL (Yet Another Docker for Deep Learning) 2 | ## Description 3 | 4 | Minimalistic docker environment for running deep learning experiments. It is built on top of nvidia-docker and has tensorflow, keras and pytorch 0.4.0 installed. Furthermore, it automatically runs Tensorboard and Jupyter lab when the container starts. The key feature of this project is a minimal manual configuration (network and folder to save your data). 5 | 6 | 7 | ## Installation 8 | ### Dependencies 9 | 10 | * Install latest nvidia drivers 11 | * Install Docker as described in `https://docs.docker.com/install/linux/docker-ce/ubuntu/`. Don't forget to add your username to a group `docker` as follows: `sudo usermod -aG docker $USER`. 12 | * Enable docker to start on boot: `sudo systemctl enable docker` 13 | * Install nvidia-docker as described in `https://github.com/NVIDIA/nvidia-docker` 14 | * Reboot 15 | 16 | ### Identities 17 | 18 | By the default, the docker will import `.gitconfig` from your home directory, however, you can manually place it in the folder. The same goes for the keypairs of the image. By the default the setup script will check if `docker_identity` exists, and if not will create one. To make sure that you can access the running container from the other machines than the current one, you should create your own `authorized_keys`. By the default, the setup script will copy only the default identity `~/.ssh/id_rsa.pub`. If the latter does not exist, it will be created. 19 | 20 | To summarize, if you want a predefined docker identity, authorized hosts list and gitconfig, just place the corresponding files into this folder. Do not forget to add your generated `docker_identity.pub` to your GitHub. 21 | 22 | 23 | 24 | ## Network settings 25 | 26 | If you are running the container within a network behind some firewall with a custom DNS, them you should edit `/etc/docker/daemon.json`. In order to know yoru DNS, you can execute the following command if you use Network Manager: 27 | 28 | ``` 29 | nmcli dev show | grep 'IP4.DNS' 30 | ``` 31 | 32 | Let's say the command has returned you two DNS addresses `x.x.x.x` and `y.y.y.y`. Then the config (given that nvidia-docker is installed) would look like this: 33 | 34 | ``` 35 | { 36 | "runtimes": { 37 | "nvidia": { 38 | "path": "/usr/bin/nvidia-container-runtime", 39 | "runtimeArgs": [] 40 | } 41 | }, 42 | "dns":["x.x.x.x", "y.y.y.y"] 43 | } 44 | ``` 45 | 46 | ### Building the image 47 | 48 | Now, when everything is set, simply run the following: 49 | 50 | ``` 51 | sh set_up.sh 52 | ``` 53 | 54 | ## Using the image 55 | 56 | To use the pre-built image, run the following command 57 | 58 | ``` 59 | DATADIR= sh run_docker.sh 60 | ``` 61 | 62 | After this, your local machine will have the following ports reserved: 63 | 64 | * 1231 - SSH 65 | * 1232 - Jupyter lab (password `deep_docker`) 66 | * 1233 - Tensorboard 67 | 68 | Tensorboard is configured to save the logs into `/data/tb_logs_docker` within your container filesystem. The actual files will eventually be stored in `$DATADIR/tb_logs_docker/` 69 | 70 | You can test the connections by typing `ssh localhost -p 1231` 71 | 72 | 73 | ### Connecting from a thin client 74 | If you want to connect from a remote machine, you can run SSH tunnels to the host. Furthermore, you will need to manually the lists of accepted identities in `authorized_keys`. The host machine, where you launch your Docker container, should have the OpenSSH server installed. Then, from a client machine, you can execute the following script: 75 | 76 | ``` 77 | sh connect_container_linux.sh 78 | ``` 79 | 80 | The same works for Mac: 81 | 82 | 83 | ``` 84 | sh connect_container_mac.sh 85 | ``` 86 | 87 | To execute these scripts you should have `screen` installed. Be careful: these scripts kill all the running screens currently running on the client machine 88 | 89 | -------------------------------------------------------------------------------- /connect_container_linux.sh: -------------------------------------------------------------------------------- 1 | for scr in $(ls /tmp/uscreens/S-$USER) 2 | do 3 | screen -X -S $scr quit 4 | done 5 | 6 | screen -dmS ssh_tunnel && screen -S ssh_tunnel -X stuff "ssh -N -L 1231:localhost:1231 $1@$2 >/dev/null 2>&1\n" 7 | screen -dmS jupyter_tunnel && screen -S jupyter_tunnel -X stuff "ssh -N -L 1232:localhost:1232 $1@$2 >/dev/null 2>&1\n" 8 | screen -dmS tboard_tunnel && screen -S tboard_tunnel -X stuff "ssh -N -L 1233:localhost:1233 $1@$2 >/dev/null 2>&1\n" 9 | -------------------------------------------------------------------------------- /connect_container_mac.sh: -------------------------------------------------------------------------------- 1 | for scr in $(ls /tmp/uscreens/S-$USER) 2 | do 3 | screen -X -S $scr quit 4 | done 5 | screen -dmS ssh_tunnel && screen -S ssh_tunnel -X stuff "ssh -N -L 1231:localhost:1231 $1@$2 >/dev/null 2>&1\n" 6 | screen -dmS jupyter_tunnel && screen -S jupyter_tunnel -X stuff "ssh -N -L 1232:localhost:1232 $1@$2 >/dev/null 2>&1\n" 7 | screen -dmS tboard_tunnel && screen -S tboard_tunnel -X stuff "ssh -N -L 1233:localhost:1233 $1@$2 >/dev/null 2>&1\n" 8 | -------------------------------------------------------------------------------- /run_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CONTAINER="dl_container_$USER" 4 | 5 | # Stop and kill the container if it is running 6 | if [ "$(docker ps -q -f name=$CONTAINER)" ]; then 7 | echo "Terminating the container" 8 | docker stop $CONTAINER 9 | fi 10 | if [ "$(docker ps -aq -f status=exited -f name=$CONTAINER)" ]; then 11 | echo "Deleting the container" 12 | docker rm $CONTAINER 13 | fi 14 | 15 | # Run the container 16 | nvidia-docker run --ipc=host -d --mount type=bind,src=$DATADIR,dst=/data \ 17 | -P -p 1231:22 -p 1232:8888 -p 1233:6006 \ 18 | --name $CONTAINER deep_docker 19 | 20 | # Setting the scripts to setup the environment 21 | docker cp authorized_keys $CONTAINER:$HOME/.ssh/authorized_keys 22 | docker cp docker_identity $CONTAINER:$HOME/.ssh/id_rsa 23 | docker cp docker_identity.pub $CONTAINER:$HOME/.ssh/id_rsa.pub 24 | docker cp run_screens_docker.sh $CONTAINER:$HOME/run_screens_docker.sh 25 | docker cp gitconfig $CONTAINER:$HOME/.gitconfig 26 | 27 | docker exec -d $CONTAINER chown -R `id -u`:`id -g` $HOME/ 28 | docker exec -d $CONTAINER chmod -R 700 $HOME/ 29 | docker exec -d $CONTAINER su - $USER -c "sh $HOME/run_screens_docker.sh" 30 | 31 | 32 | docker cp authorized_keys $CONTAINER:/root/.ssh/authorized_keys 33 | docker exec -d $CONTAINER chown -R root:root /root 34 | docker exec -d $CONTAINER chmod -R 600 /root 35 | docker exec -d $CONTAINER systemctl restart ssh 36 | 37 | -------------------------------------------------------------------------------- /run_screens_docker.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Lanunching jupyter lab 4 | CMD="jupyter lab --ip=0.0.0.0 --allow-root --NotebookApp.password='sha1:9b0f8b295713:38b3706f9716be3febcf1bd31ae03b74718fa5d7'" 5 | SCR_NAME="jpnb" 6 | screen -dmS $SCR_NAME 7 | screen -S $SCR_NAME -X stuff "export PATH=/home/$USER/conda/bin/:$PATH\n" 8 | screen -S $SCR_NAME -X stuff "cd /\n" 9 | screen -S $SCR_NAME -X stuff "$CMD\n" 10 | 11 | # Launching tensorboard 12 | CMD="tensorboard --logdir /data/tb_logs_docker" 13 | SCR_NAME="tboard" 14 | screen -dmS $SCR_NAME 15 | screen -S $SCR_NAME -X stuff "export PATH=/home/$USER/conda/bin/:$PATH\n" 16 | screen -S $SCR_NAME -X stuff "$CMD\n" 17 | -------------------------------------------------------------------------------- /set_up.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copying the git settings 4 | cp ~/.gitconfig gitconfig 5 | 6 | # Generating identity keys 7 | if [ ! -f docker_identity ]; then 8 | echo "==> Generating docker identity" 9 | ssh-keygen -t rsa -f docker_identity -q -N "" 10 | ssh-keygen -f "$HOME/.ssh/known_hosts" -R [localhost]:1231 11 | fi 12 | 13 | # Checking the authorized keys 14 | if [ ! -f authorized_keys ]; then 15 | # Checking if the user has identity 16 | if [ ! -f $HOME/.ssh/id_rsa.pub ]; then 17 | echo "==> User identity does not exist! Generating..." 18 | ssh-keygen -t rsa -q -N "" 19 | fi 20 | 21 | # Creating the *authorized keys* 22 | echo "==> Making the user to be authorized to login into the image" 23 | cat $HOME/.ssh/id_rsa.pub > authorized_keys 24 | echo "\n" >> authorized_keys 25 | 26 | fi 27 | 28 | ssh-keygen -f "$HOME/.ssh/known_hosts" -R [localhost]:1231 29 | 30 | # Building the Docker image 31 | docker build --build-arg HOST_USER=$USER --build-arg UID=`id -u` --build-arg GID=`id -g` -t deep_docker . 32 | --------------------------------------------------------------------------------