管理 Docker 兼容性 | Podman Desktop - Podman 桌面版
比 WSL2 更香的是 Docker for windows_windows装docker好还是wsl好-CSDN博客
Docker + ROS2 开发环境搭建指南 | 小强的博客
在WSL2的Ubuntu中安装和使用Docker/Podman - ChrisZZ - 博客园

配置

第三方源

ghcr.io 中国可用镜像列表 | 高速可靠的 Docker 镜像资源
红帽 Quay - 企业级容器镜像仓库 | Red Hat Quay
gebangfeng/docker-mirror: 整理各大docker,容器镜像仓库的国内镜像源

换源

ocker换源加速(更换镜像源)详细教程(2025.3最新可用镜像,全网最详细) - 知乎

缓存清理

Docker下载到一半失败了的镜像文件在哪里删除? - 知乎
Docker深度清理:一键清除下载缓存,释放宝贵空间,提升运行效率! - 云原生实践
【Docker】清理Docker废弃镜像与缓存_docker 清除缓存-CSDN博客

镜像

Docker创建镜像的三种方法及其优缺点对比:Build、Commit与Pull - 云原生实践
Build可以让自己的镜像自己可控,Commit是镜像构建后的暂存
Pull直接拉取现成镜像,对镜像源有要求
但是拉取后都成为了自己的镜像,在docker images里面静静地躺着

ROS

docker.io/fishros2/ros:noetic-desktop-full - 镜像下载 | docker.io
fishros2/ros - Docker Image | Docker Hub
osrf/docker_images: A repository to hold definitions of docker images maintained by OSRF
osrf/ros - Docker Image | Docker Hub
ros - Official Image | Docker Hub

容器

WSL 上的 Docker 容器入门 | Microsoft Learn
Windows平台下使用vscode + docker + ROS - 知乎
使用VSCode和Docker设置ROS 2 [社区贡献] — ROS 2 Documentation: Humble 文档
Ubuntu通过Docker安装任意版本ROS & 一键启动教程_ros docker-CSDN博客

Note

镜像,文件系统是不可变的,启动配置是不存在的
容器,文件系统是可以变的,启动配置是不可变的

创建并直接运行

Docker run 命令 | 菜鸟教程
Docker之运行容器并通过终端进入容器命令_终端容器器按钮-CSDN博客
Docker命令详解(run篇) - 冰隼 - 博客园
创建容器,要指定自启动命令,且自启动命令一旦创建即不可更改。创建后会自动运行容器,之后可使用start再次运行已有的容器,未来的每次start都会按照第一次的命令执行。可以当成一个服务来理解

无脑看

Docker运行ROS环境 - 知乎

docker run -it --net=host --name ros1 osrf/ros:noetic-desktop-full bash

运行新终端

docker exec -it ros1 bash

.bashrc可用:初始化环境

source /opt/ros/$(rosversion -d)/setup.bash

.bashrc可用:初始化显示地址(如果可以则用host.docker.internal:0.0本,如果不行则本机IP通过ipconfig查看)

export DISPLAY=172.24.0.1:0.0(本机IP)

运行RViz

rviz

当容器的主进程结束,容器便停止。Docker 容器需要前台进程才能保持运行,如果容器启动后没有长期运行的进程(如 roscore 或 bash),它会立即退出。所以下面的命令会“闪退”

docker run -d osrf/ros:noetic-desktop-full
Warning

除非停止、删除容器,再重新按照新的命令创建运行容器
如果想要保留旧容器的数据,可以先docker commit成新镜像

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

交互模式(临时调试):交互式运行容器,进入一个伪终端等待指令

docker run -it osrf/ros:noetic-desktop-full bash

后台模式(无头服务):后台运行容器并返回容器 ID

docker run -d osrf/ros:noetic-desktop-full roscore

后台交互式运行容器(可随时进终端):后台运行,同时提供一个伪终端一直挂着

docker run -dit osrf/ros:noetic-desktop-full

一个容器(随机命名)便基于镜像创建了。

可以指定名字的运行

docker run -d --name ros_container osrf/ros:noetic-desktop-full roscore

只创建不运行

docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

运行和停止

docker start/stop/restart 命令 | 菜鸟教程

docker start [OPTIONS] CONTAINER [CONTAINER...]
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker restart [OPTIONS] CONTAINER [CONTAINER...]
docker kill [OPTIONS] CONTAINER [CONTAINER...]
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker pause CONTAINER [CONTAINER...]
docker unpause CONTAINER [CONTAINER...]

测试网络连接

Networking | Docker Docs

若容器内curl显示Failed to connect to host.podman.internal port 8000: Connection refused

容器内pinghost.docker.internal实际指向ip为10.255.255.254
宿主内ipconfigEthernet adapter vEthernet (WSL (Hyper-V firewall))的ip为172.24.0.1
How to fix WSL X11 Forwarding after Windows Update to 23H2 - Super User
Ubuntu-WSL2一键设置代理操作_10.255.255.254-CSDN博客
(7 封私信) docker compose中的容器如何访问主机服务 - 知乎

host.docker.internal域名解析错误,或数据没有转发。手动改成正确的IP。
Podman container on Windows cannot access host by ip or dns. Linux and Mac OS do not have this issue. · Issue #13966 · containers/podman
🐳 令人头疼的 docker 代理问题,我整理了解决方法和验证方案 | 阿森毛不多
Connection refused on host.docker.internal - Docker Desktop - Docker Community Forums
Connection refused on docker container - Stack Overflow
Unable to connect to host service from inside Docker container - Docker Engine / Compose - Docker Community Forums
docker - Podman containers refuses connections to host.containers.internal - Stack Overflow
macos - Why am I getting "Connection Refused" when using "host.docker.internal" to hit the host's localhost? - Super User

以X11服务为例,把export DISPLAY=172.24.0.1:0.0即可正常转发

X11图形化

一小时实践入门Gazebo - 知乎
针对ros机器人开发同学的docker入门教程 - 哔哩哔哩

自动配置

docker run,要添加DISPLAY环境变量
在Docker for Windows中运行GUI程序 - larva-zhang - 博客园

  • share the Host’s DISPLAY environment variable to the Container --env="DISPLAY"
  • run container with host network driver with --net=host
$ docker run --net=host --env="DISPLAY"

或者用这个句柄(对于非docker引擎,可以用host.containers.internal:0

docker run ... -e DISPLAY=host.docker.internal:0

但是这样存在一个问题!我换成podman后,不知道是不是bug,host.containers.internal指向的是10.255.255.254这样一个WSL的IP句柄,然而这个句柄,经过curl网络测试后得到Connection refused。但是ipconfig得到的真实的宿主机IP不会出现这个错误。

手动配置

如果按如下的方法(docker部署,SSH连接),则只是运行后手动配置环境变量
VScode远程连接Docker容器实现X11转发 - azureology - 博客园
我决定连接docker后,每次手动配置环境变量。

export DISPLAY=host.docker.internal:0.0

开放权限:在linux下的应该还要xhost +,在windows中则是勾选Disable access control

Note

第一次出现下面的错误,不过后面我关闭代理,重启了,打开XLaunch,选择Disable access control,就成功了。估计还是重启的问题。
解决qt.qpa.xcb: could not connect to display问题-CSDN博客
VScode配置X11转发!让你彻底摆脱显示屏!!! - SkyXZ - 博客园
(54 封私信 / 80 条消息) 解决 qt.qpa.xcb: could not connect to display 问题 - 知乎

运行ROS注意到ROS_MASTER_URI=http://docker-desktop:11311/,看来docker-desktop是容器的域名

git

对于Windows下运行Linux的git,存在换行符转换问题。在容器内执行

git config --get core.autocrlf
git config --global core.autocrlf true
git config --get core.autocrlf

管理

列出 Docker 容器,默认只显示运行中的容器

docker ps [OPTIONS]

重命名容器

docker rename my_old_container my_new_container

删除容器

docker rm <容器ID或名称>

备份容器到新镜像

docker commit <容器名或ID> my_new_image

Dockerfile

Docker build 命令 | 菜鸟教程
Docker镜像优化:从1.16GB到22.4MB - 知乎
优化Dockerfile:不建议使用多条RUN命令的原因优化Dockerfile:不建议使用多条RUN命令的原因 RUN - 掘金

docker build -f /path/to/Dockerfile -t myimage:latest .

这会从 /path/to/ 目录读取 Dockerfile 并构建一个名为 myimage:latest 的镜像。

Dev Container(VSCode)

使用现有的容器

VS Code 连接访问本地主机上的Docker容器 - BooTurbo - 博客园
打开VS Code的命令输入行,选择Remote-Containers: Attach to Running Container...(此时要有运行中的容器才能选择)

使用现有的配置文件

在VSCode打开工作空间,以ROS1最后一个版本noetic为例

通过配置文件创建新容器

Create a Dev Container
创建开发容器 - VSCode 编辑器

Note

编辑 .devcontainer 文件夹的内容时,你需要重建才能使更改生效。使用 开发容器:重建容器  Dev Containers: Rebuild Container 命令来更新你的容器。

以下是一个简单的 devcontainer.json 示例,它使用预构建的 TypeScript 和 Node.js VS Code 开发容器 映像

{
  "image": "mcr.microsoft.com/devcontainers/typescript-node:0-18"
}

你可以修改配置以执行以下操作

在此示例中,如果你想在容器中安装 代码拼写检查器扩展 并自动转发端口 3000,你的 devcontainer.json 将如下所示

{
  "image": "mcr.microsoft.com/devcontainers/typescript-node",

  "customizations": {
    "vscode": {
      "extensions": ["streetsidesoftware.code-spell-checker"]
    }
  },
  "forwardPorts": [3000]
}

容器中安装其他软件

运行后安装

一旦 VS Code 连接到容器,你就可以打开 VS Code 终端并在容器内部对操作系统执行任何命令。

运行前安装

你还可以使用 devcontainer.json 中的 "features" 属性从预定义的一组功能甚至你自己的功能中安装工具和语言。例如,你可以使用以下命令安装最新版本的 Azure CLI。有关更多详细信息,请参阅开发容器功能规范

"features": {
    "ghcr.io/devcontainers/features/azure-cli:1": {
        "version": "latest"
    }
  }

通过Dockerfile

Dockerfile 也将存在于 .devcontainer 文件夹中。你可以将 devcontainer.json 中的 image 属性替换为 dockerfile

{
  "build": { "dockerfile": "Dockerfile" },
  "customizations": {
    "vscode": {
      "extensions": ["dbaeumer.vscode-eslint"]
    }
  },
  "forwardPorts": [3000]
}

当你进行更改(例如安装新软件)时,Dockerfile 中所做的更改即使在重建开发容器时也会保留。
在你的 Dockerfile 中,使用 FROM 指定映像,并使用 RUN 指令安装任何软件。你可以使用 && 将多个命令串联起来。

FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get -y install git

图形界面

Run and Access GUI inside VS Code DevContainers
一开始以为是要安装这个feature
devcontainer-features/src/desktop-xserver at main · bascodes/devcontainer-features
但是看了看
devcontainer, how to make X display work (mount graphics inside docker in visual studio code) - Stack Overflow
发现关键还是在

    "containerEnv": {
        "DISPLAY": "unix:0"
    },

(54 封私信 / 80 条消息) Windows平台下使用vscode + docker + ROS - 知乎
这里是这样的

    "remoteEnv": {
        "DISPLAY": "host.docker.internal:0.0"
    },
属性 类型 描述
containerEnv🏷️ 对象 一组名称-值对,用于设置或覆盖容器的环境变量。值中可以引用环境变量和预定义变量。例如:

如果要在设置此变量时引用现有容器变量(例如更新 ),请改用 。
将在 Docker 容器本身上设置变量,因此容器中生成的所有进程都可以访问它。但在容器的生命周期内,它也是静态的 - 您必须重新构建容器才能更新值。
我们建议尽可能多地使用 (over ),因为它允许所有进程查看变量,并且不是特定于客户端的。"containerEnv": { "MY_VARIABLE": "${localEnv:MY_VARIABLE}" }``PATH``remoteEnv``containerEnv``containerEnv``remoteEnv
remoteEnv🏷️ 对象 一组名称-值对,用于设置或覆盖支持服务/工具(或终端等子进程)的环境变量,但不是整个容器。值中可以引用环境变量和预定义变量
如果值不是静态的,则可能需要使用 (over ),因为您可以更新其值而无需重新生成完整容器。devcontainer.json``remoteEnv``containerEnv