1、Install Docker Engine on Ubuntu
https://docs.docker.com/engine/install/ubuntu/
安装
准备条件
1)安装以前要先卸载以前的,先卸载操作系统默认安装的docker
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
2)安装必要支持
sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
List the available versions:
apt-cache madison docker-ce | awk '{ print $3 }'
5:28.5.1-1~ubuntu.24.04~noble
5:28.5.0-1~ubuntu.24.04~noble
...
VERSION_STRING=5:28.5.1-1~ubuntu.24.04~noble
sudo apt-get install docker-ce=VERSION_STRING docker-ce-cli=VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin
Verify that the installation is successful by running the hello-world
image:
sudo docker run hello-world
Docker 需要用户具有 sudo 权限,为了避免每次命令都输入sudo,可以把用户加入 Docker 用户组:
sudo usermod -aG docker $USER
newgrp docker
其它命令
#查看Docker版本
sudo docker version
#查看Docker运行状态
sudo systemctl status docker
sudo systemctl start docker
查看正在运行的容器
sudo docker ps
停止容器,将 <container_id> 替换为实际容器的 ID 或名称
sudo docker stop <container_id>
再次启动 容器:
sudo docker start <container_id>
Error
1 hello-world 如果遇到拉取镜像失败的情况,则需要换源
sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
sudo vim /etc/docker/daemon.json
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.mirrors.ustc.edu.cn",
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2. 安装ros镜像
ros镜像网址
https://hub.docker.com/r/osrf/ros
https://hub.docker.com/r/osrf/ros/tags
sudo docker pull osrf/ros:noetic-desktop-full
查看镜像
sudo docker images
3、创建ROS容器
配置访问宿主机的 X11 服务器, 可视化界面(vscode rviz gazebo)
宿主机开启xhost,使得docker里面可视化界面(vscode rviz)。注意:每次重启容器,主机都得执行一遍,否则容器内可视化报错。
xhost +
关闭访问控制,允许任何主机访问本地的X服务器;
xhost -
打开访问控制,仅允许授权清单中的主机访问本地的X服务器。
注意:这个命令的效果是临时的.
说明:docker容器中打开gazebo等可视化页面需要访问宿主机的 X11 服务器。而X11服务默认只允许『来自本地的用户』启动的图形程序将图形显示在当前屏幕上。所以需要给docker添加访问权限(否则会报错No protocol specified)
Way1:允许所有本地连接访问 X11 服务器
xhost +local: >> /dev/null
Way2:单独给 docker 访问 X11 服务器的权限
xhost +local:docker
Way3:单独给 docker 中的某个容器访问 X11 服务器的权限
xhost +local:`docker inspect --format='{{ .Config.Hostname }}' containerId\` # containerId替换为容器ID
创建宿主机数据文件夹,作为与容器的数据容器卷
mkdir home/qqq/ros1_noetic_ubuntu20_docker
编写Dockerfile
mkdir docker_file
cd docker_file
gedit Dockerfile
Dockerfile 文件内容:
FROM osrf/ros:melodic-desktop-full
# nvidia-container-runtime
ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
RUN apt-get update && \
apt-get install -y \
build-essential \
libgl1-mesa-dev \
libglew-dev \
libsdl2-dev \
libsdl2-image-dev \
libglm-dev \
libfreetype6-dev \
libglfw3-dev \
libglfw3 \
libglu1-mesa-dev \
freeglut3-dev \
gedit
构建容器
sudo docker build -t noetic .
docker build -t 镜像名称:标签 Dockerfile路径
设置环境变量 NVIDIA_VISIBLE_DEVICES 和 NVIDIA_DRIVER_CAPABILITIES,用于配置 NVIDIA 设备的可见性和驱动程序的能力。
使用 apt-get 更新软件包列表,并安装以下软件包:
build-essential:包含了 gcc 和 make 等基本的构建工具。
libgl1-mesa-dev:Mesa OpenGL 库的开发文件。
libglew-dev:GLEW 库的开发文件。
libsdl2-dev:SDL2 库的开发文件。
libsdl2-image-dev:SDL2_image 库的开发文件。
libglm-dev:GLM 库的开发文件。
libfreetype6-dev:FreeType 库的开发文件。
libglfw3-dev 和 libglfw3:GLFW 库的开发文件和运行时库。
libglu1-mesa-dev:Mesa GLU 库的开发文件。
freeglut3-dev:FreeGLUT 库的开发文件。
gedit:用于在容器内编辑文件的文本编辑器。
创建容器,挂载数据容器卷
--gpus all
sudo docker run -dit \
-e NVIDIA_DRIVER_CAPABILITIES=all \
-v /home/qqq/ros1_noetic_ubuntu20_docker:/data \
-v /dev:/dev \
--group-add video \
--volume=/tmp/.X11-unix:/tmp/.X11-unix \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--net=host \
--name=noetic \
osrf/ros:noetic-desktop-full /bin/bash
sudo docker run -dit \
-e NVIDIA_DRIVER_CAPABILITIES=all \
-v /home/qqq/ros1_noetic_ubuntu20_docker:/data \
-v /dev:/dev \
--group-add video \
--volume=/tmp/.X11-unix:/tmp/.X11-unix \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--net=host \
--name=noetic \
osrf/ros:noetic-desktop-full /bin/bash
demo1
sudo docker run -it \
-v /home/nuc/noetic_container_data_1:/data \
--device=/dev/dri \
--group-add video \
--volume=/tmp/.X11-unix:/tmp/.X11-unix \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--name=noetic_ros_2 osrf/ros:noetic-desktop-full /bin/bash
--env="QT_X11_NO_MITSHM=1"
必须加上,否则docker内部无法可视化(主机必须先执行 xhost + 命令)
-v 主机路径:容器路径 # 挂载卷
-w 工作目录 # 设置工作目录
-p 主机端口:容器端口 # 端口映射
--network host # 使用主机网络
demo2
sudo docker run -dit \
--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all \
--name=<your_name> \
-v /dev:/dev \
-v /home/<your_username>:/home/<your_username> \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=unix$DISPLAY \
-w /home/<your_username> \
osrf/ros:noetic-desktop-full
Tip1:上一行对应自己的镜像名,需要修改,通过sudo docker images查看
Tip2: 后面可以跟一些容器启动后想运行的命令(如果有命令上一行最后别忘了加换行符)
可选参数:
--privileged \
--net=host \
--restart=xxx \
-dit:-d:在后台运行容器、-it: 交互式运行容器,分配一个伪终端。
--gpus all: 将所有可用的 GPU 硬件设备分配给容器
(从Docker19.03开始,--gpus 选项可以直接处理GPU分配,不再需要设置NVIDIA_VISIBLE_DEVICES 环境变量)
-e NVIDIA_DRIVER_CAPABILITIES=all:设置环境变量,允许容器内的所有 NVIDIA 驱动功能。
--name=your_name:为容器指定一个名称
-v /dev:/dev:将宿主机的 /dev 设备目录挂载到容器的 /dev 目录,允许容器访问宿主机的所有设备。(可以解决USB无法挂载问题)(也可以单独选择只挂载某些设备例如:声卡/dev/snd等等)
-v /home/your_username:/home/your_username:将宿主机的用户目录挂载到容器的同名目录,这样容器可以访问宿主机用户的文件。
-v /tmp/.X11-unix:/tmp/.X11-unix:将宿主机的 X11 sockets 目录挂载到容器,允许容器访问宿主机的图形用户界面会话。
-e DISPLAY=unix$DISPLAY:设置环境变量 DISPLAY,使其与宿主机的显示环境变量相同,对于图形应用程序来说是必要的。
-w /home/your_username:设置容器内的工作目录。
osrf/ros:noetic-desktop-full:镜像名称或者ID(改成自己对应的版本)
demo3
sudo docker run -it \
--device=/dev/dri \
--group-add video \
--volume=/tmp/.X11-unix:/tmp/.X11-unix \
--env="DISPLAY=$DISPLAY" \
--name=cwc_docker osrf/ros:noetic-desktop-full /bin/bash
demo4
创建一个Docker的网络,用于指定容器的固定IP
docker network create --subnet=192.168.50.0/24 ros_network
创建容器
映射/tmp/.X11-uni 以便进行图形化工具的访问
映射一个主机路径到容器中,该路径需要手动填写
设置使用固定的IP进行访问
docker run -itd \
-v /dev:/dev \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v your_shared_path:/home/ros/01-RosSpace \
--net ros_network \
--ip 192.168.50.50 \
--name ros-noetic cros
注意:进入ROS容器后先sudo apt-get update
更新一下源,否则可能无法在容器内通过apt install
安装其他包
命令
查看正在运行的容器
sudo docker ps -a
启动容器
sudo docker start 容器id/名称 #(noetic)
进入容器
sudo docker exec -it 容器名称/容器id /bin/bash
退出容器
exit
停止容器
sudo docker stop 容器id/名称
删除容器
docker rm 容器ID或名称
将当前容器打包成镜像备份
以免接下来配环境把当前容器弄脏,记得经常备份镜像!!
docker commit -a "KingO" -m "noetic_loam" 04f380ec1178 noetic_loam:1.0
docker commit -a="用户名" -m="描述" 容器id或名字 打包后的镜像的名字:版本号
**进入容器后,修改镜像,**提交刚才修改的镜像
docker commit d81abcfd2e3b demo:v1.3
4、一键启动【推荐】
- 创建一个文件夹用于存放启动命令,然后cd进入
以 ~/.docker/setup 文件夹为例
cd ~/.docker/setup
2)创建启动文件并编辑内容
这步操作是允许用户只使用容器名对容器进行操作,省去输入docker的原生指令
sudo nano your_name # 名称可以自定义,推荐和容器同名(noetic)
文件中输入以下内容并保存:
xhost +local:docker
echo "请输入指令控制<your_name>容器: 启动(s) 重启(r) 进入(e) 关闭(c):"
read choose
case $choose in
s) docker start <your_name>;;
r) docker restart <your_name>;;
e) docker exec -it <your_name> /bin/bash;;
c) docker stop <your_name>;;
esac
newgrp docker
说明:
其中xhost +local:docker是给docker添加X11访问权限,也可以改为xhost +local: >> /dev/null表示允许所有本地用户连接到 X11
其中 docker xxx 是对应docker启动/重启/进入容器/关命令,可以根据docker的指令添加一些其他的命令,例如删除容器等等
esac是用来结束 case 语句的,别给删了。
newgrp docker表示将当前shell会话的用户组切换到docker组,可以不使用sudo运行docker指令(需要确保你的用户账户已经被添加到docker组,前文中的【Docker用户权限问题】有提到)。
注意: 修改 <your_name> 为你的自定义名称。
- 赋予文件可执行权限
sudo chmod +x 文件名(your_name)
- 在~/.bashrc 中添加该文件所在路径
echo 'export PATH=$PATH:/home/your_username/.docker/setup' >> ~/.bashrc
- 使用
设置好后任意终端中输入容器名(noetic) 即可进入容器,进入容器后先一次性设置一下ROS的source:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
最后退出(输入exit)重新进入容器即可正常使用ros
10、Uninstall the Docker Engine
-
Uninstall the Docker Engine, CLI, containerd, and Docker Compose packages:
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
-
Images, containers, volumes, or custom configuration files on your host aren't automatically removed. To delete all images, containers, and volumes:
sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
-
Remove source list and keyrings
sudo rm /etc/apt/sources.list.d/docker.list sudo rm /etc/apt/keyrings/docker.asc