Docker note

Masaru Nakanotani
CSPAR, UAH, Huntsville, AL 35805, USA
Dec/02/2021 (Date created)
May/05/2023 (Last modified)


In this post, I take a note how to use Docker.
You can install Docker for several OS (Linux, Windows, and Mac), and the installation document is here https://docs.docker.com/get-docker/.
The following argument is valid for Linux, Windows with WSL, and Mac.

Once you have completed installing, you can check the version in the terminal. If it does not work, you may need to run Docker Desktop (if you installed it).

user@pc:~$ docker --version
Docker version 20.10.10, build b485636
user@pc:~$

Next you can check the hello-world test as follows,

user@pc:~$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world

Digest: sha256:cc15c5b292d8525effc0f89cb299f1804f3a725c8d05e158653a563f15e4f685
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

user@pc:~$

If you want to enter a container with an Ubuntu OS and work something there, you can run with the '-it' option.

user@pc:~$ docker run -it ubuntu bash
root@cb577cb9b9a4:/#

If you are seeing the above message (root@...), you are now in a container as the root user. You can exit from the container by just typing exit.

user@pc:~$ docker run -it ubuntu bash
root@cb577cb9b9a4:/# exit
exit
user@pc:~$

If you want to build an environment in a container for your work, it is convenient to make a Dockerfile. For example, you can write the following script in a Dockerfile,

user@pc:~$ vim Dockerfile
FROM ubuntu:18.04
RUN upt-get update && upt-get install -y vim
RUN echo "hello world" > sample.txt

Once you create a Dockerfile, you need to build to run as follows and would see,

user@pc:~$ docker image build -t myimage .
[+] Building 1.6s (7/7) FINISHED                                                                           
 => [internal] load build definition from Dockerfile                                                 0.0s
 => => transferring dockerfile: 140B                                                                 0.0s
 => [internal] load .dockerignore                                                                    0.0s
 => => transferring context: 2B                                                                      0.0s
 => [internal] load metadata for docker.io/library/ubuntu:18.04                                      1.0s
 => [1/3] FROM docker.io/library/ubuntu:18.04@sha256:0fedbd5bd9fb72089c7bbca476949e10593cebed9b1fb9e 0.0s
 => CACHED [2/3] RUN apt-get update && apt-get install -y vim                                        0.0s
 => [3/3] RUN echo "hello world" >sample.txt                                                         0.3s
 => exporting to image                                                                               0.1s
 => => exporting layers                                                                              0.1s
 => => writing image sha256:a941244a269e63d6e8f221ff709ed9b1b29c9a3c7684fc8bf048999530148aa5         0.0s
 => => naming to docker.io/library/myimage 
user@pc:~$

By using the option "-t myimage", you can name a image as "myimage".

Finally you can run the image "myimage",

user@pc:~$ docker run -it myimage
root@0a37a361de6f:/# ls
bin   dev  home  lib64  mnt  proc  run         sbin  sys  usr
boot  etc  lib   media  opt  root  sample.txt  srv   tmp  var
root@0a37a361de6f:/# cat sample.txt 
hello world
root@0a37a361de6f:/# exit
exit
user@pc:~$

You can check images you built,

user@pc:~$ docker images
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
myimage       latest    4238f49152a1   43 minutes ago   162MB
ubuntu        latest    ba6acccedd29   6 weeks ago      72.8MB
hello-world   latest    feb5d9fea6a5   2 months ago     13.3kB

Here, I keep a Dockerfile which I created so that you can read NASA cdf files from CDAWEB on Jupyter notebook.

### based on anaconda3 ###
FROM continuumio/anaconda3

### install CDF ###
ARG HOME=/home/workdir
WORKDIR $HOME
RUN mkdir $HOME/cdf
RUN apt update -y &&\
    apt install -y wget build-essential gcc gfortran libncurses5-dev make
RUN wget -r -l1 -np -nd -nc https://cdaweb.gsfc.nasa.gov/pub/software/cdf/dist/cdf38_1/linux/ -A cdf38_1-dist-all.tar.gz &&\
    gunzip cdf38_1-dist-all.tar.gz &&\
    tar -xvf cdf38_1-dist-all.tar -C ./ &&\
    cd cdf38_1-dist &&\
    make OS=linux ENV=gnu CURSES=yes FORTRAN=no UCOPTIONS=-O2 SHARED=yes -j4 all &&\
    make INSTALLDIR=$HOME/cdf install &&\
    . $HOME/cdf/bin/definitions.B
#   sed -i -e '68d' $HOME/cdf/bin/definitions.B && \
#   sed -i -e '67a export LD_LIBRARY_PATH=/home/workdir/cdf/lib:$LD_LIBRARY_PATH' $HOME/cdf/bin/definitions.B 
VOLUME $HOME/cdf

### install spacepy ###
RUN pip install --upgrade pip &&\
    pip install git+https://github.com/spacepy/spacepy.git

### define user ID and name ###
ARG USER_ID
ARG GROUP_ID
ARG USER_NAME=guest
#RUN addgroup --gid $GROUP_ID $USER_NAME  #comment out this line for a Mac user
RUN adduser  --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID $USER_NAME
USER $USER_NAME

### start jupyter notebook when running ###
EXPOSE 8888
ENTRYPOINT ["jupyter", "notebook", "--port=8888", "--no-browser", "--ip=0.0.0.0", "--allow-root"]
CMD ["--notebook-dir=/home/workdir"]

Then you can build and run as follows,

user@pc:~$ docker image build -t myimage --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) .
[+] Building 152.6s (11/11) FINISHED                                                                       
 => [internal] load build definition from Dockerfile                                                 0.0s
 => => transferring dockerfile: 1.49kB                                                               0.0s
 => [internal] load .dockerignore                                                                    0.0s
 => => transferring context: 2B                                                                      0.0s
 => [internal] load metadata for docker.io/continuumio/anaconda3:latest                              1.3s
 => [1/7] FROM docker.io/continuumio/anaconda3@sha256:70915870bb4c3b1963252c674a49babc9334b693985855 0.0s
 => => resolve docker.io/continuumio/anaconda3@sha256:70915870bb4c3b1963252c674a49babc9334b693985855 0.0s
 => CACHED [2/7] WORKDIR /home/workdir                                                               0.0s
 => CACHED [3/7] RUN mkdir /home/workdir/cdf                                                         0.0s
 => CACHED [4/7] RUN apt update  -y &&     apt install -y  wget build-essential gcc gfortran libncur 0.0s
 => [5/7] RUN wget -r -l1 -np -nd -nc https://cdaweb.gsfc.nasa.gov/pub/software/cdf/dist/cdf36_4/li 35.0s
 => [6/7] RUN pip install --upgrade pip &&     pip install git+https://github.com/spacepy/spacepy. 113.8s
 => [7/7] RUN adduser --disabled-password --gecos '' --uid 501 --gid 20 guest                        0.9s 
 => exporting to image                                                                               1.5s 
 => => exporting layers                                                                              1.5s 
 => => writing image sha256:82fb43696fa967d6396dbece6b55b7407f1267d65e176dd012e2ed5b2c00f2f9         0.0s 
 => => naming to docker.io/library/myimage  
user@pc:~$ docker run -p 8888:8888 -it --rm -v $PWD:/home/workdir -w /home/workdir myimage

The point here is that you will be no longer root in the container.

In a jupyter notebook in the container, you may need to import spacepy as follows,

import os
os.environ["CDF_LIB"] = 'cdf/lib/'
from spacepy import pycdf