{"id":17692985,"url":"https://github.com/themousepotato/rosappsdeployment","last_synced_at":"2025-05-13T02:48:28.534Z","repository":{"id":105120427,"uuid":"125385477","full_name":"themousepotato/ROSAppsDeployment","owner":"themousepotato","description":"Deploying ROS apps using Docker","archived":false,"fork":false,"pushed_at":"2018-06-25T10:37:17.000Z","size":2334,"stargazers_count":15,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-01T06:02:42.114Z","etag":null,"topics":["deployment","docker","robotics","ros"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/themousepotato.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-15T15:11:35.000Z","updated_at":"2024-03-21T04:54:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"1e2fbdd0-49fd-47bc-ad92-1734ce8dc7e1","html_url":"https://github.com/themousepotato/ROSAppsDeployment","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themousepotato%2FROSAppsDeployment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themousepotato%2FROSAppsDeployment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themousepotato%2FROSAppsDeployment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themousepotato%2FROSAppsDeployment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/themousepotato","download_url":"https://codeload.github.com/themousepotato/ROSAppsDeployment/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253862735,"owners_count":21975583,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deployment","docker","robotics","ros"],"created_at":"2024-10-24T13:07:50.455Z","updated_at":"2025-05-13T02:48:28.512Z","avatar_url":"https://github.com/themousepotato.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deploying ROS apps using Docker\n\n## What is Docker ?\nDocker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package. By doing so, thanks to the container, the developer can rest assured that the application will run on any other Linux machine regardless of any customized settings that machine might have that could differ from the machine used for writing and testing the code.\n\nUnlike a virtual machine, rather than creating a whole virtual operating system, Docker allows applications to use the same Linux kernel as the system that they're running on and only requires applications be shipped with things not already running on the host computer. This gives a significant performance boost and reduces the size of the application.\n\n## Why deploy ROS apps?\nApps developed using the Robotic Operating System can be made repeatable and reproducible. Why don't we make them deployable? Let's go through some hardware drivers which want to use ROS tools. They includes cameras, depth cameras, laser cameras, robots, audio, inertial units, GPS, joysticks. Sounds cool :stuck_out_tongue_winking_eye: !\n\nThere are variety of ROS ecosystems also. Have a look at them.\n\n![ROS ecosystems](https://raw.githubusercontent.com/TheMousePotato/ROSAppsDeployment/master/images/ecosyss.png)\n\nLet's try to combine our areas of interest. First have a look at a normal software development environment matrix.\n\n![Software development matrix](https://github.com/TheMousePotato/ROSAppsDeployment/raw/master/images/matrix1.png)\n\nNow, see how the robotics development progress in a matrix:\n\n![Robotics development matrix](https://github.com/TheMousePotato/ROSAppsDeployment/raw/master/images/matrix2.png)\n\nYuck! Too complex? Time has come to re-invent the convensional approach. The cool thing about docker is that a container has no need to account for the changes in another container. Let's try to make it simpler to understand. I'm maintaining a container for running apps required for joystick(say). My friend does that for camera. Then, my friend don't need to bother about dependencies for running my joystick apps. In the same way, I don't have to keep track of his development. So, I only need to install the libraries for my peripheral and so as my friend. If we are not deploying it using containers, then we have to work on a single space with all the packages installed. The worst thing about this non-deployable robotics is we have to commit each and every update for the libraries unnecessarily. We need to look after the libraries which we have no point of interest. Through containers, things get more simplification. Now the interesting thing comes to action. Our peripherals can still communicate. How? Each container has got an IP address and Docker act as a pathway and provides several network topologies to connect our nodes. Wow! Let's see it in action.\n\n## How to use Docker to ship ROS apps?\nAs we have learnt to make things easier so far, let's try to implement it step by step. Links to installation and proxy setup for Docker are given in the end of this documentation. After that, let's start.\n\n### Volumes\nBy default Docker uses `/root/.ros/` directory to keep track of the logs and debugging info. If you want to change it to your home directory(say 'ubuntu'), perform :\n\n\u003e $ docker run -v \"/home/ubuntu/.ros/:/root/.ros/\" ros\n\n### Devices\nSome application may require device access for acquiring images from connected cameras, control input from human interface device, or GPUS for hardware acceleration. This can be done using the --device run argument to mount the device inside the container, providing processes inside hardware access.\n\n### Networks\nAlthough one process per container is recommended, Docker networks can also be extended to use several running ROS apps. See documentation on [NetworkSetup](http://wiki.ros.org/ROS/NetworkSetup).\n\n## Start by an example\nFor the communication between our ROS nodes, there should be a virtual network. In this short example, we’ll create a virtual network, spin up a new container running roscore advertised as the master service on the new network, then spawn a message publisher and subscriber process as services on the same network.\n\n### Build image\n\n\u003e    Build a ROS image that includes ROS tutorials using this `Dockerfile`:\n\n```\nFROM ros:indigo-ros-base\n# install ros tutorials packages\nRUN apt-get update \u0026\u0026 apt-get install -y \\\n    ros-indigo-ros-tutorials \\\n    ros-indigo-common-tutorials \\\n    \u0026\u0026 rm -rf /var/lib/apt/lists/\n```\n\n\u003e    Then to build the image from within the same directory:\n\n```\ndocker build --tag ros:ros-tutorials .\n```\n\n### Create network\n\n\u003e    To create a new network foo, we use the network command:\n\n```\ndocker network create foo\n```\n\n\u003e    Now that we have a network, we can create services. Services advertise there location on the network, making it easy to resolve the location/address of the service specific container. We’ll use this make sure our ROS nodes can find and connect to our ROS master.\n\n### Run services\n\n\u003e    To create a container for the ROS master and advertise it’s service:\n\n```\n docker run -it --rm \\\n    --net foo \\\n    --name master \\\n    ros:ros-tutorials \\\n    roscore\n```\n\n \u003e   Now you can see that master is running and is ready manage our other ROS nodes. To add our talker node, we’ll need to point the relevant environment variable to the master service:\n\n```\n  docker run -it --rm \\\n    --net foo \\\n    --name talker \\\n    --env ROS_HOSTNAME=talker \\\n    --env ROS_MASTER_URI=http://master:11311 \\\n    ros:ros-tutorials \\\n    rosrun roscpp_tutorials talker\n```\n\n\u003e    Then in another terminal, run the listener node similarly:\n\n```\n  docker run -it --rm \\\n    --net foo \\\n    --name listener \\\n    --env ROS_HOSTNAME=listener \\\n    --env ROS_MASTER_URI=http://master:11311 \\\n    ros:ros-tutorials \\\n    rosrun roscpp_tutorials listener\n```\n\n\u003e    Alright! You should see listener is now echoing each message the talker broadcasting. You can then list the containers and see something like this:\n\n```\n  docker service ls\nSERVICE ID          NAME                NETWORK             CONTAINER\n67ce73355e67        listener            foo                 a62019123321\n917ee622d295        master              foo                 f6ab9155fdbe\n7f5a4748fb8d        talker              foo                 e0da2ee7570a\n```\n\n\u003e    And for the services:\n\n```\n docker ps\nCONTAINER ID        IMAGE               COMMAND                CREATED              STATUS              PORTS               NAMES\na62019123321        ros:ros-tutorials   \"/ros_entrypoint.sh    About a minute ago   Up About a minute   11311/tcp           listener\ne0da2ee7570a        ros:ros-tutorials   \"/ros_entrypoint.sh    About a minute ago   Up About a minute   11311/tcp           talker\nf6ab9155fdbe        ros:ros-tutorials   \"/ros_entrypoint.sh    About a minute ago   Up About a minute   11311/tcp           master\n```\n\n### Introspection\n\n \u003e   Ok, now that we see the two nodes are communicating, let get inside one of the containers and do some introspection what exactly the topics are:\n\n```\n  docker exec -it master bash\n  source /ros_entrypoint.sh\n```\n\n\u003e    If we then use rostopic to list published message topics, we should see something like this:\n\n```\n  rostopic list\n/chatter\n/rosout\n/rosout_agg\n```\n\n### Tear down\n\n\u003e    To tear down the structure we’ve made, we just need to stop the containers and the services. We can stop and remove the containers using Ctrl^C where we launched the containers or using the stop command with the names we gave them:\n\n```\n  docker stop master talker listener\n  docker rm master talker listener\n```\n\n### Compose\n\n\u003e Now that you have an appreciation for bootstrapping a distributed ROS example manually, lets try and automate it using docker-compose.\n\n\u003e    Start by making a folder named rostutorials and moving the Dockerfile we used earlier inside this directory. Then create a yaml file named docker-compose.yml in the same directory and paste the following inside:\n\n```\nversion: '2'\nservices:\n  master:\n    build: .\n    container_name: master\n    command:\n      - roscore\n  \n  talker:\n    build: .\n    container_name: talker\n    environment:\n      - \"ROS_HOSTNAME=talker\"\n      - \"ROS_MASTER_URI=http://master:11311\"\n    command: rosrun roscpp_tutorials talker\n  \n  listener:\n    build: .\n    container_name: listener\n    environment:\n      - \"ROS_HOSTNAME=listener\"\n      - \"ROS_MASTER_URI=http://master:11311\"\n    command: rosrun roscpp_tutorials listener\n```\n\u003e    Now from inside the same folder, use docker-copose to launch our ROS nodes and specify that they coexist on their own network:\n\n```\n  docker-compose up -d\n```\n\n\u003e    Notice that a new network named rostutorials_default has now been created, you can inspect it further with:\n\n```\n  docker network inspect rostutorials_default\n```\n\n\u003e    We can monitor the logged output of each service, such as the listener node like so:\n\n```\n  docker-compose logs listener\n```\n\n\u003e    Finally, we can stop and remove all the relevant containers using docker-copose from the same directory:\n\n```\n  docker-compose stop\n  docker-compose rm\n```\n\n\u003e    Note: the auto-generated network, rostutorials_default, will persist over the life of the docker engine or until you explicitly remove it using docker network rm.\n\n\n## Conclusion\nLet's have a look at a funny cartoon on convensional approach on robotics.\n\n![Cartoon making fun of convensional robotics](https://github.com/TheMousePotato/ROSAppsDeployment/raw/master/images/cartoon2.jpg)\n\nNow, see how it has changed.\n\n![Image of deployable robotics](https://github.com/TheMousePotato/ROSAppsDeployment/raw/master/images/simplify.png)\n\n## Some ROS apps shipped using Docker\n* [Caffe](https://github.com/ruffsl/ros_caffe/tree/master/docker)\n* [Gazemo demos](https://github.com/ruffsl/gazebo_docker_demos)\n\n## Reference and further reading\n* [Docker for beginners - tutorial by DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-16-04)\n* [Docker for beginners - workshop material](https://docker-curriculum.com/)\n* [Docker cheatsheet](https://github.com/wsargent/docker-cheat-sheet)\n* [Awesome Docker resources](https://github.com/veggiemonk/awesome-docker)\n* [Configuring network proxy for using Docker](https://stackoverflow.com/questions/23111631/cannot-download-docker-images-behind-a-proxy)\n* [Official Docker library for ROS](https://registry.hub.docker.com/_/ros/)\n* [Official documentation from Docker on ROS](https://docs.docker.com/samples/library/ros/)\n* [Official documentation from ROS on Docker](http://wiki.ros.org/docker)\n* [Official website of Open Robotics](https://www.osrfoundation.org/)\n* [Docker on ROS slack channel](https://rosorg.slack.com/messages/docker/)\n* [FAQ on Docker at ROS website](http://answers.ros.org/questions/scope:all/sort:activity-desc/tags:Docker/page:1/)\n\n## Contributions\nHey! If you've found something missing in this article, do suggest changes by sending PRs.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthemousepotato%2Frosappsdeployment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthemousepotato%2Frosappsdeployment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthemousepotato%2Frosappsdeployment/lists"}