Docker
Follow the installation instruction from Docker website in your system. Once docker service has started, you can check:
docker info
# or
docker version
List images:
docker images
Run an image:
docker run -ti ubuntu:latest bash
docker run <image-id>
-ti
stands for terminal interactive. If the image is not present locally, it
will pull from the docker hub. Alternatively, you can use docker pull
to
download locally an image prior to running.
List docker process:
# running containers
docker ps
# all containers
docker ps -a
# last exited container
docker ps -l
Create images from container:
docker commit <container-id>
Give a name to the image:
docker tag <SHA-256-image-id> <my-image-name>
We can assign name at the same time with commit:
docker commit <container-id> <image-name>
This will save the state of the container in the latest image.
Start a detached container:
docker run -d -ti ubuntu:latest bash
Attach running detached container:
docker attach <container-name-or-id>
Exit from the docker container without killing the process: [control] + [P], [control] + [Q]
Sharing volumes (shared folder with the host):
docker run -v /home/host/docs:/home -ti centos bash
docker run -v ${PWD}:/home -ti ubuntu bash
Check docker storage usage:
docker system df
Remove build cache:
docker builder prune
Delete container:
docker rm <id-or-name>
Delete all idle containers:
docker container prune
Delete images:
docker rmi <image-name>
Reclaim space immediately (otherwise it may take several minutes to reflect storage space after a cleanup operation):
docker run --privileged --pid=host --rm docker/desktop-reclaim-space
Delete all the stopped containers and images:
docker system prune -a
Run and remove when docker instance exits:
docker run --rm <image-name>
Use host network:
docker run -it --net=host centos bash
Port forwarding:
docker run -ti -p 8888:8888 -v ${PWD}:/home jupyter bash
Set MAC address:
docker run -it --mac-address 02:42:ac:11:0d:11 ubuntu bash
You can also pass environment variables with -e
flag, e.g.,-e LANG=C.UTF-8
,
-e TZ=Asia/Singapore
. You can pass multiple -e
flags to pass multiple such
variables.
Running GUI apps on docker
First we need to install a X-window system. On linux, we can choose X11. On macOS X-Quartz, on Windows xming. On macOS, allow connections from network clients:
After launching XQuartz (you may launch for terminal by open -a XQuartz
),
issue xhost +
. More about X-window system here.
# macOS
docker run --rm -tid -e DISPLAY=docker.for.mac.host.internal:0 ubuntu firefox
# linux
docker run --rm -tid --net=host -e DISPLAY=:0 ubuntu firefox
# Windows
docker run --rm -tid -e DISPLAY=host.docker.internal:0 ubuntu firefox
I assumed you have the X version of firefox is installed in the ubuntu image.
Running apache on docker
Here we will install centos docker image:
docker pull centos
Run docker:
docker run -ti centos bash
Once inside centos update the os:
dnf up
Install apache:
sudo dnf install httpd
exit
docker commit <container-id> centos
docker run --net=host centos httpd -D FOREGROUND &
Now if you browse your host IP address you should be able to view the default website. We can stop the httpd, by killing the container.
docker ps
docker kill <container-id>
Stop all running containers:
docker stop $(docker ps -a -q)
Dockerfile
Write the Dockerfile
:
# Start from Ubuntu 22.04 LTS
FROM ubuntu:jammy
# Update OS
RUN apt update \
&& apt upgrade -y
# Install software packages
RUN apt install -y python3 \
&& apt install -y python3-pip \
&& apt install -y git \
&& apt install -y fonts-open-sans
# Install pip packages
RUN pip3 install jupyterlab numpy scipy matplotlib
# bashrc settings
RUN echo 'alias jupyter-notebook="jupyter-notebook --allow-root --no-browser"' \
>> $HOME/.bashrc
# clone code from git repository
WORKDIR /root
RUN git clone https://github.com/pranabdas/arpespythontools.git
# leave in `/home` which we can map with the host
WORKDIR /home
Build docker image (the file is named Dockerfile):
docker build -t arptools .
If the file is named other than Dockerfile:
docker build -t arptools -f arptools.dockerfile .
Launch:
docker run -ti --net=host -v /host/path:/home arptools bash
Add non-root user and group:
RUN groupadd -r noroot && useradd -r -g noroot noroot
# make owner of certain directory / executables
RUN chown -R noroot:noroot build_dir
# set user
USER noroot
More details on adduser
(also check useradd --help
):
ENV NON_ROOT_USER="noroot"
ARG NON_ROOT_USER_PASSWORD="gf3r-trf5-6etd"
ENV NON_ROOT_USER_GROUP="noroot"
RUN groupadd -r $NON_ROOT_USER_GROUP -g 1000 \
&& useradd \
--uid 1000 \
--system \
--gid $NON_ROOT_USER_GROUP \
--create-home \
--home-dir /home/$NON_ROOT_USER/ \
--shell /bin/bash \
--comment "non-root user" \
$NON_ROOT_USER \
&& chmod 755 /home/$NON_ROOT_USER/ \
&& echo "$NON_ROOT_USER:$NON_ROOT_USER_PASSWORD" | chpasswd
Running chown
on a large directory may increase the image size significantly.
In such case build the directory using another instance, and copy it to new
image using:
COPY --chown=noroot:noroot /home/build_dir /noroot/build_dir
Docker hub
Login:
sudo docker login docker.io
Tag a local image:
sudo docker tag localimage:latest username/localimage:latest
Push a local image:
sudo docker push username/localimage:latest
Transferring image offline
docker pull ubuntu
docker save -o ubuntu_image.docker ubuntu
docker load -i ubuntu_image.docker
Docker compose
Docker compose can help create, run, and manage the lifecycle of the containers. For example below docker run command
docker run -d --name apache -p 8080:80 -v ${PWD}/build:/usr/local/apache2/htdocs/ httpd:latest
would translate to following docker compose specification:
services:
apache:
image: httpd:latest
container_name: apache
ports:
- '8080:80'
volumes:
- ./build:/usr/local/apache2/htdocs
Now go to the directory where compose.yaml
is saved and issue:
docker compose up
Now we can access our website at localhost:8080
using a web browser.
We can run a service in the background with -d
(detached) flag.
docker compose up -d
Once we are done, we can stop
or down
(down
stops the container and
removes the container).
docker compose stop
docker compose down
Explore more docker compose commands with
docker compose --help
How can we access the shell of a container running a service? List running containers:
docker ps
Then access the shell:
docker exec -it <container-id> bash
Use systemctl in docker
See this project: docker-systemctl-replacement.