2025年7月3日 星期四

ROS Docker 「開機時自動重啟」和「總是運行」

Docker run 命令從 --rm(容器停止時自動移除)改為開機時自動重啟,您需要將 --rm 替換為 Docker 的 重啟策略(restart policy) 參數。

最適合您「開機時自動重啟」和「總是運行」需求的是 --restart=always--restart=unless-stopped


--rm 與重啟策略的差異

  • --rm: 這是個很方便的參數,用於開發和測試。當容器停止後,它會自動刪除容器實例。這意味著您不會有停止的容器佔用磁碟空間,並且每次啟動都是一個全新的容器。但這也表示容器的任何狀態(如日誌、容器內的修改)都會在停止時丟失。它與自動重啟是互斥的。

  • --restart 策略: 這是用於持久運行服務的參數。它指示 Docker 守護進程(daemon)在容器停止時如何處理。


推薦的重啟策略選項:

  1. --restart=always:

    • 行為: 無論容器的退出狀態如何(正常結束或崩潰),Docker 都會總是重啟它。

    • 如果 Docker 守護進程重啟(例如主機重啟),這個容器也會自動啟動。

    • 例外: 如果您手動使用 docker stop <container_name> 命令停止了容器,那麼在 Docker 守護進程重啟之前,它將不會自動重啟。但一旦守護進程重啟,它會再次自動啟動。

    • 適用場景: 確保服務始終運行,即使在主機重啟後。

  2. --restart=unless-stopped:

    • 行為: 類似於 always,但有一個重要區別:只有當容器不是被手動停止時,Docker 才會重啟它。

    • 如果容器因為錯誤或主機重啟而停止,它會自動重啟。

    • 但如果您使用 docker stop 手動停止它,即使 Docker 守護進程重啟,它也不會再次自動啟動,除非您手動啟動它。

    • 適用場景: 這是許多生產環境中的推薦選項,因為它提供了自動重啟的彈性,同時也保留了您手動停止服務的能力。

如何修改您的 docker run 命令

將您的原始命令中的 --rm 替換為您選擇的重啟策略。


範例:使用 --restart=unless-stopped (建議)

Bash
xhost +local:docker # 開放 X11 存取(若尚未執行)
docker run -it -d \ # 添加 -d 以後台模式運行,這樣您可以在容器啟動後退出終端
  --name ros2dev \
  --restart=unless-stopped \ # 將 --rm 替換為此行
  --gpus all \
  --net=host \
  --privileged \
  --env DISPLAY=$DISPLAY \
  --env QT_X11_NO_MITSHM=1 \
  --volume /tmp/.X11-unix:/tmp/.X11-unix:rw \
  --volume $(pwd)/data:/home/ubuntu/data \
  --device /dev/ttyACM0:/dev/ttyACM0 \
  --device /dev/ttyUSB0:/dev/ttyUSB0 \
  ros2-humble-ubuntu bash -c "source /opt/ros/humble/setup.bash && bash" # 添加 bash -c "..." 確保容器保持運行

範例:使用 --restart=always

Bash
xhost +local:docker # 開放 X11 存取(若尚未執行)
docker run -it -d \ # 添加 -d 以後台模式運行
  --name ros2dev \
  --restart=always \ # 將 --rm 替換為此行
  --gpus all \
  --net=host \
  --privileged \
  --env DISPLAY=$DISPLAY \
  --env QT_X11_NO_MITSHM=1 \
  --volume /tmp/.X11-unix:/tmp/.X11-unix:rw \
  --volume $(pwd)/data:/home/ubuntu/data \
  --device /dev/ttyACM0:/dev/ttyACM0 \
  --device /dev/ttyUSB0:/dev/ttyUSB0 \
  ros2-humble-ubuntu bash -c "source /opt/ros/humble/setup.bash && bash" # 添加 bash -c "..."

重要變更和說明:

  1. 移除 --rm: 這是第一步,因為它與重啟策略衝突。

  2. 添加 --restart=<policy>: 根據您的需求選擇 alwaysunless-stopped

  3. 添加 -d (detached mode): 當您設置了重啟策略後,容器通常是作為後台服務運行的。添加 -d 參數會讓容器在後台運行,並在啟動後立即將控制權返回給您的終端。如果沒有 -d,當您關閉終端時,容器可能會停止。

  4. 修改容器啟動命令: 由於 -d 模式下,如果容器的主進程結束,容器也會停止,您需要確保容器內有一個長時間運行的進程。

    • ros2-humble-ubuntu 後面的指令從原先的空置狀態,改為 bash -c "source /opt/ros/humble/setup.bash && bash"

    • 這會讓容器啟動時,先 source ROS 環境,然後再啟動一個 bash shell,這個 shell 會持續運行,直到您手動停止容器。這樣即使您從主機斷開連接,容器也會繼續運行。


透過這些修改,您的 Docker 容器將在開機時自動啟動,並在非手動停止的情況下保持運行。



沒有留言:

張貼留言