# Docker Tutorial
[TOC]
## Reference
[基本操作](https://ithelp.ithome.com.tw/articles/10186431)
## Install Docker
1. Update package list
```bash
sudo apt-get update
```
2. Install docker
```bash
sudo apt-get install docker.io
```
3. Add user to the docker group
```bash
sudo usermod -aG docker ${USER}
```
4. Logout and log back to take effect
## Build Image
The below example will take Ubuntu20.04 install ROS for example
1. Create Dockerfile
```bash
touch Dockerfile
```
2. Open Dockerfile and write
```dockerfile
# We want to use ubuntu:20.04 for base image
FROM ubuntu:20.04
# install prequsites package
RUN apt-get update && \
apt-get install -y curl gnupg2 lsb-release && \
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add - && \
echo "deb http://packages.ros.org/ros2/ubuntu focal main" > /etc/apt/sources.list.d/ros2-latest.list && \
apt-get update && \
apt-get install -y ros-foxy-desktop
# we can also use RUN + command we want to use
RUN git clone https://github.com/ika-rwth-aachen/mqtt_client.git
# Change directory
WORKDIR /root/catkin_ws/src/mqtt_client
RUN rosdep install -r -y --ignore-src --from-paths .
WORKDIR /root/catkin_ws
# Add additional user if you want
## create a non-root user
ARG USER_ID=1000
RUN useradd -m --no-log-init --system --uid ${USER_ID} ncrl -g sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER ncrl
WORKDIR /home/ncrl
```
3. Build your docker image
```bash
docker build -t my-ros-image .
```
## Run Container
1. use a bash script to run your docker container with serveral option
```bash
#!/usr/bin/env bash
xhost +local:
# allow display GUI
docker run \
# run docker
-it \
# enable TTY terminal
--env="DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ # allow GUI
-p 2233:22 \
--rm \
# Automatically remove container when it is stopped
--name ncrl_mqtt \
# Docker name is "ncrl_mqtt".
--user root \
# Runs the container as the root user.
--network host \
# Access network services running on the host system.
-e GRANT_SUDO=yes \
-v ~/ncrl_mqtt:/root/catkin_ws \
#This option mounts the directory ~/ncrl_mqtt
#on the host system to the directory
#/root/catkin_ws inside the Docker container.
#This allows the user to share files between
#the host system and the Docker container.
leeandy90833/ncrl:ncrl_mqtt \
# This specifies the Docker image to use,
# leeandy90833/ncrl:ncrl_mqtt.
bash
```
## Publish Image
[reference](https://docs.docker.com/engine/reference/commandline/push/)
1. Tag the image with a name that includes the registry URL and the image name:
```bash
#docker tag IMAGE_NAME REGISTRY_URL/IMAGE_NAME:TAG
docker tag my-image docker.io/my-username/my-image:latest
```
2. Login to Docker registry
```bash
docker login REGISTRY_URL
```
3. Push the image