Skip to content

kmihak/developWithDocker

Repository files navigation

Develop With Docker

Table of Contents

Install Docker (Locally, Linux, Windows, WSL2, Macintosh)

Follow the tutorial to install on your machine:

Use existing installation on one of the servers: bea.zel.lo, or abacus1.zel.lo, or jane.zel.lo, ask system admin for group permissions. For complete server names checkout the department wiki pages http://zel.irb.hr/wiki/tutorials:supercomputers.

Building a Docker Image

  • Examples of Dockerfile files dependent on your preferences are in this GitHub repository. create virtual image

At what point are docker and singularity commands applied and what do they create.

Docker images are located online on docker hub repository. After logging in, you can upload your image as well. In order to create an image we use Dockerfile and a set of standard commands. Docker image is the first step to create your fully reproducible environment. Basic setup is by using Dockerfile.

  • Dockerfile contains procedure/code to build a docker image, minimal dockerfile examples are in repository,
  • cuda > 11.3 doesnt work on srce based on documentation (check) and cuda > 11.6 doesn't work on orthus our
  • Understanding the Dockerfile syntax and commands:
# # is the comment character

# FROM: Specifies the base image for the Dockerfile.
FROM <image>[:<tag>] [AS <name>] # e.g. rstudio/rstudio-server-pro:1.2.5033-1, or pytorch/pytorch:2.2.2-cuda12.1-cudnn8-devel
# cuda > 11.3 doesnt work on srce based on documentation (check) and cuda > 11.6 doesn't work on orthus

# ARG: Arguments from the "docker build ..." command
# Or some other arguments you need for Dockerfile build
ARG USER_ID
ARG GROUP_ID

# RUN: Executes commands in the Docker image. Makes image snapshot.
RUN <command>

# COPY: Copies files or directories from the host into the Docker image.
COPY <src> <dest>

# WORKDIR: Sets the working directory for subsequent instructions.
WORKDIR /path/to/directory

# CMD: Specifies the default command to run when the container starts.
CMD ["executable", "param1", "param2"]

# ENTRYPOINT: Specifies the command to run when the container starts, which cannot be overridden by CMD.
ENTRYPOINT ["executable", "param1", "param2"]

# ENV: Sets environment variables in the Docker image.
ENV <key> <value>
...

Basic Docker Commands

  1. docker build ... --> change : (:) to something to make the image recognizable, e.g. smith/gpu:ver1, creates builds the image from Dockerfile:
docker build -t <ime>:<verzija> --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) .
  1. docker run ... --> creates a container ~ virtual machine, opens linux terminal:
docker run -it --rm --user $(id -u):$(id -g) <ime>:<verzija> /bin/bash
  1. docker exec ... existing container terminal:
docker exec -u $(id -u) -g $(id -g) -it rm <container_id_or_name> bash

Flags used for this initial example were in docker build ... flags used:

  • -t tag the image with : in the docker images table the columns REPOSITORY will display and TAG will display , use something to recognize your images.
  • --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) send your server user id and group id to initialized arguments of the Dockerfile.

Flags used for this initial example were in docker run ... flags used:

  • -it This combines two flags: -i (interactive) and -t (pseudo-TTY). It allows you to interact with the container through the terminal.
  • --rm This flag tells Docker to automatically remove the container when it exits. It helps in cleaning up after the container stops running, avoiding accumulation of stopped containers.
  • --user $(id -u):$(id -g) This sets the user inside the container to the same user and group as the user running the docker run command on the host system. \$(id -u) returns the user ID of the current user, and \$(id -g) returns the group ID of the current user.

Navigating the docker images and containers

  1. docker images: docker images - shows table of pulled and built images,

  2. docker ps: docker ps - shows table of active containers (inactive containers are dangling somewhere within the system),

  3. docker pull download image to docker, the downloaded image will show in table docker images with columns REPOSITORY will display name pytorch/pytorch and column TAG will display 1.13.1-cuda11.6-cudnn8-runtime:

docker pull pytorch/pytorch:1.13.1-cuda11.6-cudnn8-runtime
  1. docker rmi remove docker image
  2. ...

docker images

Show docker images from build command using: docker images.

Show docker ps

Shows docker containers from run command using docker ps.

  • Some more basic operations with images & containers:
  1. Delete Image Command:

    • Removes a Docker image forcefully: docker image rm -f f8fcad3b680c
  2. Tagging Image with Custom Repository and Tag:

    • Description: Tags an existing Docker image with a custom repository name and tag.
    docker image tag server:latest <myname/name>:<otherName>
    docker image tag d583c3ac45fd <myname/name>:<otherName>
    

Building a Simple Docker Image

Step-by-step guide to creating a basic docker image.

  • Step 1: create directory: /your_path/start-vm-project/
  • Step 2: copy Dockerfile, requirements.txt, scriptToRun.py to directory.
  • Step 3: build the image
docker build -t ime:naziv --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) .

Run Docker Image

  • Step 4 What do i need?:
    • a) virtual mounts: -v ~/home/user/directory:/workingDirectory, /workingDirectory is the directory name you created in the Dockerfile with command WORKDIR,
    • b) GPUs to use for computing --gpus all vs --gpus '"device=0,2"' - select which gpus to use and how many you need,
    • c) what is my working directory -w /set/working/dir/in/container, this command is not necessary if the WORKDIR was specified in the Dockerfile, only if you want to change the working directory but then you can encounter user premissions errors,
    • d) shared memory directory is limited to 64MB, but we increase this size since my application depends on this shared memory to 8GB --shm-size=8g,
    • e) port forwarding between container and "host machine":"virtual machine" -p 8888:8888, meaning that host machine port will be forwarded to the container virtual machine port.
    • f) --group-add users: Add the host's users group to the container's group list. This allows the container to access resources or permissions assigned to the users group on the host.
    • g) ...
  • Step 5: JupyterLab in browser without cuda support:
docker run -it --rm --user $(id -u):$(id -g) --group-add users -p 8888:8888 -v /home/user/WorkDirectory:/remoteWorkDirectory -w /remoteWorkDirectory ime:tag jupyter lab --no-browser --ip=0.0.0.0 --port=8888

Jupyter lab with cuda support for docker images that have cuda installed.

docker run -it --rm --gpus all --user $(id -u):$(id -g) --group-add users --shm-size=8g -p 8888:8888 -v ~/home/user/homeWorkDirectory:/remoteWorkDirectory -w /remoteWorkDirectory ime:tag jupyter lab --no-browser --ip=0.0.0.0 --port=8888

Click on jupyter link to open jupyter lab and develop. ! If jupyter lab is on a server change 127.0.0.1 to <server ip> or server name. Flags at the end are jupyter flags: --no-browser --ip=0.0.0.0 --port=8888 in order: do not open a browser there is no browser on the host machine, use the defalut host ip and the port for jupyter lab is the port 8888 that is forwarded from the host 8888 port to the wirtual machine.

  • Step 5': Run some script that needs all these flags instead of jupyter lab we can use the python command or r depending on your installed environment:
docker run -it --rm --gpus all --user $(id -u):$(id -g) --group-add users --shm-size=8g -p 8888:8888 -v ~/home/user/homeWorkDirectory:/remoteWorkDirectory -w /remoteWorkDirectory ime:tag python -script_based_flags my_script.py

Development in container

Path to dockerfile /developmentInContainer/Dockerfile. How a container environment could be setup for development if you need to use your data in several different environments.

Project
│   README.md
│
├───data
|     |     some_data.txt
|     ├──   ...
│
├───code
|     |     script.py
|     ├──   ...
|     ├──   start-docker
|     │     |     Dockerfile
|     |     ├──   req.txt
|     |     ...

Docker run jupyter lab for code editing:

docker run -it --rm --user $(id -u):$(id -g) --group-add users && \
-p 8888:8888 && \
-v /home/user/CodeDirectory:/workspace/code && \
-v /home/user/DataDirectory:/workspace/data && \
-w /remoteWorkDirectory ime:tag && \
jupyter lab --no-browser --ip=0.0.0.0 --port=8888

Docker Image and Singularity

Introduction to Lab Resources and Additional Guides

Singularity (S) and docker images are compatible to create a Singularity image (.simg) just save your existing docker image and push it to the Singularity server. Singularity available HPC servers access: (small) https://hybridscale.github.io/orthus/access and (BIG) https://wiki.srce.hr/pages/viewpage.action?pageId=8488260 Singularity basic commands and description: https://wiki.srce.hr/display/RKI/Singularity

Docker Image Compatibility with Singularity

Docker to singularity container (1)

How to go about creating docker image and deploy it on the Singularity server.

After you are satisfied with docker image, save docker image to file:

docker save -o pathToFile/py-min.tar fe35d0fd6c24

Sync image to the server with singularity:

rsync -avP <path/to_directory/img-min.tar> <username>@<server>:/home/user/path/to_directory/

Use gzip for large files for transfer between slow connections: gzip img_min.tar, rsync -avP <path/to_directory/py-min.tar.gz> <user>@<server>:/home/user/path/to_directory/, or post your docker image to docker hub as well and create the container form there.

  1. Build the Singularity Container from existing docker image. Replace <img-min.tar> with the desired name for your docker image file. This command does not require sudo to create .simg singularity image:
singularity build singularity_container.simg docker-archive://<img-min.tar>
  1. Use the proposed way of job scheduling when running the scripts in the server environment, https://wiki.srce.hr/display/RKI/Pokretanje+i+upravljanje+poslovima.

  2. Run the Singularity Container. Follow the rules of job scheduling srce or job scheduling orthus both HPCs use SGE (Sons of Grid Engine) and execute some script from the created .simg:

singularity exec --nv sPyCuda.simg python cnn_mnist.py

or

singularity exec --nv /path/to/your_container.simg python helloworld.py

Replace "/path/to/your_container.simg" with the path to your Singularity container file and your_script.py with the name of your Python script.

--nv flag gives singularity premissions to cuda.

Using a Singularity Definition File (e.g., singularityfile.def, similar to Dockerfile only has different syntax), pull the image from dockerhub repository:

Bootstrap: docker
From: name:tag # e.g. rstudio/rstudio-server-pro:1.2.5033-1, or r-base:4.3.3, or pytorch/pytorch:2.2.2-cuda12.1-cudnn8-devel(doesnt work on orthus or srce)

%post
    # Execute your script inside the container
    python your_script.py

Create the .simg:

singularity build sPyCuda.simg singularityfile.def

Using singularityfile.def requires singularity group priveleges (sudo).

Jobs to Son of Grid Engine SGE

Detailed descriptions of job scheduling for SGE in Croatian, how to run jobs with CRO Son of Grid Engine and in English, how to run jobs with ENG Son of Grid Engine

Development in Remote Docker Containers TBD

Remote docker container development using VSCODE on the fly. Coding in interactive containerized environment.

Remote Containers Preinstalation

Step 1. https://code.visualstudio.com/docs/remote/containers-tutorial vscode:extension/ms-vscode-remote.remote-containers

Step 2. https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack Getting started You can launch a new instance of VS Code connected to WSL by opening a WSL terminal, navigating to the folder of your choice, and typing code .: create a folder named .devcontainer in yout development environment.

Windows Working Example SSH

Step 3. SSH In VS Code, run Remote-SSH: Open Configuration File... in the Command Palette (F1), select an SSH config file, and add (or modify) a host entry as follows:

Host server.name.hr
  HostName server.name.hr
  User userName

Create key and transfer to server in cmd administrator privelages: In Powershell administrator privileges to upload: ssh-keygen -t rsa -b 4096

$USER_AT_HOST="username@server.name.hr"
$PUBKEYPATH="$HOME\.ssh\id_rsa.pub"

$pubKey=(Get-Content "$PUBKEYPATH" | Out-String); ssh "$USER_AT_HOST" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '${pubKey}' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Add to config file: In VS Code, run Remote-SSH: Open Configuration File... use F1 button to open.

Host server.name.hr
  HostName server.name.hr
  User userName
  IdentityFile ~/.ssh/id_rsa

Check if SSH is working in your terminal and in VSCODE should connect you after: ssh @server.name.hr without password.

Developing in Remote Docker Environments

Make separate directory "start_project" with files req.txt and Dockerfile and a directory "/.devcontainer" containing file devcontainer.json Examples in the GitHub repository.

Documentation for devcontainer.json: https://containers.dev/implementors/json_reference/ Examples vscode: https://code.visualstudio.com/docs/devcontainers/containers#_open-a-folder-on-a-remote-ssh-host-in-a-container Developing on a remote host: https://code.visualstudio.com/docs/remote/troubleshooting#_configuring-key-based-authentication Working Tourtorial and Examples: https://leimao.github.io/blog/VS-Code-Development-Remote-Host-Docker/

Security

Back to top

About

a) Development with docker for servers.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published