{"id":21390759,"url":"https://github.com/interpause/ros2-workspace-template","last_synced_at":"2025-08-03T03:19:09.327Z","repository":{"id":40665650,"uuid":"506984799","full_name":"Interpause/ros2-workspace-template","owner":"Interpause","description":"Template to use ROS2 workspace in Dev Container","archived":false,"fork":false,"pushed_at":"2024-07-04T07:55:06.000Z","size":105,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-07T15:11:08.125Z","etag":null,"topics":["devcontainer","docker","docker-compose","ros2","ros2-humble"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Interpause.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-24T11:26:35.000Z","updated_at":"2023-05-15T22:24:25.000Z","dependencies_parsed_at":"2023-02-10T14:31:08.925Z","dependency_job_id":null,"html_url":"https://github.com/Interpause/ros2-workspace-template","commit_stats":null,"previous_names":[],"tags_count":3,"template":true,"template_full_name":null,"purl":"pkg:github/Interpause/ros2-workspace-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Interpause%2Fros2-workspace-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Interpause%2Fros2-workspace-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Interpause%2Fros2-workspace-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Interpause%2Fros2-workspace-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Interpause","download_url":"https://codeload.github.com/Interpause/ros2-workspace-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Interpause%2Fros2-workspace-template/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263577251,"owners_count":23483130,"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":["devcontainer","docker","docker-compose","ros2","ros2-humble"],"created_at":"2024-11-22T13:19:38.876Z","updated_at":"2025-07-04T16:33:47.021Z","avatar_url":"https://github.com/Interpause.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ros2-workspace-template\n\nTemplate for ROS2 workspace using [VS Code Dev Containers](https://code.visualstudio.com/docs/remote/containers) \u0026 [Docker Compose](https://docs.docker.com/compose/).\n\n- Use `Dev Containers: Clone Repository in Container Volume...` in VS Code's Command Palette to auto-magically setup everything!\n  - To re-open repository, either use `File \u003e Open Recent` or repeat the above with the **exact SAME url**.\n- For customization, do a global find \u0026 replace for `(OPTION)`.\n  - Remember to `Dev Containers: Rebuild Container` afterwards!\n- GUI apps are viewable via [noVNC](https://novnc.com/info.html) (VNC client web app) hosted on \u003chttp://localhost:6080/\u003e.\n  - **The password is `password`!**\n\n## Table of Contents\n\n- [Options](#options)\n  - [Mount Point `/data`](#mount-point-data)\n  - [VNC \u0026 RQT in Production Image](#vnc--rqt-in-production-image)\n- [Other Features](#other-features)\n  - [`requirements.txt` Escape Hatch](#requirementstxt-escape-hatch)\n  - [VS Code Tasks](#vs-code-tasks)\n  - [Docker Image Distribution](#docker-image-distribution)\n  - [VS Code Extension Suggestions](#vs-code-extension-suggestions)\n  - [Code Formatting](#code-formatting)\n  - [Dev Container Lifecycle Hooks](#dev-container-lifecycle-hooks)\n  - [Dev Container using Docker Compose](#dev-container-using-docker-compose)\n- [Tips](#tips)\n  - [`example_module`](#example_module)\n  - [`git` Submodules](#git-submodules)\n  - [Update Package Indexes](#update-package-indexes)\n  - [Minimize Changes to the Dockerfile](#minimize-changes-to-the-dockerfile)\n  - [Change ROS Distro](#change-ros-distro)\n- [Troubleshooting](#troubleshooting)\n\n## Options\n\n`(OPTION)` marks key options to consider before creating the Dev Container. Some of the `(OPTION)`s work together to activate the features listed below:\n\n### Mount Point `/data`\n\n\u003e Note: If using `Dev Containers: Clone Repository in Container Volume...`, the host folder path must be absolute. It is possible to use `$USERPROFILE` (Windows) or `$HOME` (Linux) for absolute paths. Otherwise, the host folder path would be relative to the Docker Compose file location.\n\nMount points are used to mount a folder from the host into the container. An example for mounting a folder to `/data` is included in [`docker-compose.dev.yml`](./docker-compose.dev.yml) as an `(OPTION)`. `/data` can be used to share anything from the host with the container (e.g., config files, models, databases). Also remember to:\n\n- Add mount points to [`.gitignore`](./.gitignore) and [`.dockerignore`](./.dockerignore).\n- Symlink mount points into your workspace folder for convenience in [`postCreate.sh`](./.devcontainer/hooks/postCreate.sh).\n\nWhile one mount point is sufficient, more can be added by following `/data`'s example. See \u003chttps://docs.docker.com/storage/bind-mounts/\u003e for more info.\n\n### VNC \u0026 RQT in Production Image\n\nBy default, noVNC \u0026 RQT are not installed in the production image to save space. It is recommended to use ROS CLI or create a proper API instead to manage ROS systems. However, they can be enabled by following `(OPTION)`s in [`Dockerfile`](./Dockerfile). This can be convenient for early stages of deployment.\n\n## Other Features\n\n### `requirements.txt` Escape Hatch\n\nSome dependencies may be unavailable from the `rosdep` package manager (check [ROS Index](https://index.ros.org)). For Python dependencies, they should be added to a `requirements.txt` created within the ROS package. The ROS package's `requirements.txt` should then be composed into the workspace's [`requirements.txt`](./requirements.txt) (example in [`requirements.txt`](./requirements.txt)). For other dependencies, they should be added to both Dockerfiles. See \u003chttps://github.com/ros/rosdistro/blob/master/CONTRIBUTING.md#rosdep-rules-contributions\u003e with regards to adding new packages to `rosdep`.\n\n### VS Code Tasks\n\nFor developer convenience, some common tasks are present in [`tasks.json`](./.vscode/tasks.json). Use them by opening the Command Palette and typing `task`. The following tasks are available:\n\n- `rosdep install dependencies`: Install all dependencies of the current workspace.\n- `colcon build all`: Build all (detected) ROS packages.\n- `colcon build specific`: Build a specific ROS package.\n- `update package index`: Update Ubuntu and ROS package indexes.\n\n### Docker Image Distribution\n\nSee \u003chttps://docs.docker.com/engine/reference/commandline/docker/\u003e for more info.\n\n#### Building\n\n\u003e Note: If using `Dev Containers: Clone Repository in Container Volume...` on Windows, follow \u003chttps://code.visualstudio.com/docs/containers/choosing-dev-environment#_windows-subsystem-for-linux\u003e to ensure built images are stored on the host computer's image repository.\n\n```sh\ndocker build . -t organization/repo:vx.x.x -t organization/repo:latest\n```\n\nImages can have multiple names tagged to them. Tagging images with the version number and as latest helps when distributing images.\n\n#### Exporting\n\n\u003e Note: Run this command on the host computer rather than in the Dev Container.\n\n```sh\ndocker save organization/repo:vx.x.x organization/repo:latest -o repo-vx.x.x.tar\n```\n\nCompressing the image afterwards using `xzip` is recommended to save space. Docker is able to load compressed images (i.e., `repo-vx.x.x.tar.xz`) without decompressing manually.\n\n#### Importing\n\n```sh\ndocker load -i repo-vx.x.x.tar.xz\n```\n\nImports the image and its names. It will still be tagged as `organization/repo:vx.x.x` and `organization/repo:latest`, conveniently replacing the previous `latest`.\n\n### VS Code Extension Suggestions\n\nBoth [`devcontainer.json`](./.devcontainer/devcontainer.json) and [`extensions.json`](./.vscode/extensions.json) are configured such that VS Code will automatically install some extensions. These are highly recommended for developer experience.\n\n### Code Formatting\n\n[`black`](https://github.com/psf/black) is used to format Python code due to its uncompromising design. Imports are also automatically sorted using compatible rules. See [`settings.json`](./.vscode/settings.json) for the configuration.\n\n### Dev Container Lifecycle Hooks\n\n[`devcontainer.json`](./.devcontainer/devcontainer.json) allows adding lifecycle hooks which can be useful for special cases. See the [`hooks`](./.devcontainer/hooks/) folder for some examples.\n\n### Dev Container using Docker Compose\n\nInstead of using Dev Container with a Dockerfile, this template uses it with Docker Compose instead. This is done for a few reasons:\n\n- Include example of how to configure Docker for ROS to communicate across containers.\n- Docker Compose is closer to real world deployment scenarios.\n  - It is also more flexible and easier to configure than [`devcontainer.json`](./.devcontainer/devcontainer.json).\n\n## Tips\n\n### `example_module`\n\n`example_module`'s [README.md](https://github.com/Interpause/ros-example-node/blob/main/README.md) provides instructions on how to create a `git` submodule and add ROS packages to it. It also contains a simple pub-sub `launch` file that can be used to test bandwidth \u0026 latency. To remove `example_module`:\n\n```sh\ngit rm example_module\n```\n\n### `git` Submodules\n\n\u003e Note: The template will clone missing submodules for you by default.\n\nIt is recommended to add custom ROS packages to the workspace via [`git` Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules). However, when cloning a repository using `git`, it will not clone submodules by default. In order to clone submodules, use:\n\n```sh\ngit clone --recurse-submodules\n```\n\nIf the repository is already cloned and has empty submodules, do:\n\n```sh\ngit submodule update --init --recursive\n```\n\nIf you want `git` to clone submodules by default, try:\n\n```sh\ngit config --global submodule.recurse true\n```\n\nOtherwise, use [Github Desktop](https://desktop.github.com/), which uses `--recurse-submodules` by default.\n\nNonetheless, when submodules are cloned, they will be in a detached state, which prevents committing. Switching submodules to the main branch can either be done through VS Code's Source Control tab, or:\n\n```sh\ngit submodule foreach --recursive git checkout main\n```\n\nThis is done for you automatically if using a named volume to store the repository.\n\n### Update Package Indexes\n\nThe `rosdep` and Ubuntu package managers rely on a local cache of their package index. If the package index is outdated, it may not contain any active package distribution server, leading to package downloads failing. Hence, it is recommended to periodically re-download the package index:\n\n```sh\napt-get update\nrosdep update\n```\n\n### Minimize changes to the Dockerfile\n\nWhen a step in the Dockerfile is changed, subsequent steps are invalidated and need to be rebuilt. Furthermore, ROS workspaces with the same Dockerfile share cache, resulting in less disk usage and shorter rebuilds.\n\nThe current Dockerfiles should work in most cases without needing edits. Nonetheless, if the Dockerfile becomes too complex, re-organizing it is fine. See \u003chttps://docs.docker.com/develop/develop-images/dockerfile_best-practices/\u003e for more info on Docker layer caching and other Docker tips.\n\n### Change ROS Distro\n\nTo change ROS Distro, do a global search for the current distro (`humble`) and replace as necessary with the new distro. Afterwards, rebuild the Dev Container.\n\n## Troubleshooting\n\n### Setup Issues\n\n- On first setup, the Dev Container fails to build and complains about `/r`.\n  - The Dev Container lifecycle hooks were checked out with CRLF instead of LF line endings.\n  - Do `git config --global core.autocrlf input` and re-clone the repository.\n  - See \u003chttps://code.visualstudio.com/docs/remote/troubleshooting#_resolving-git-line-ending-issues-in-wsl-resulting-in-many-modified-files\u003e for more info.\n- When modifying the Dockerfile, earlier cached steps might be stale, causing later steps to fail.\n  - Rebuild the Dev Container without cache.\n\n### Build Issues\n\n- Try deleting the `build` and `install` folders before rebuilding all packages.\n\n### Runtime Issues\n\n- `rosdep` has no version lock, which means there is no protection against breaking changes when packages update.\n  - See: \u003chttps://github.com/ros-infrastructure/rosdep/issues/325\u003e\n  - One solution would be to use your own install script instead of `rosdep`.\n- ROS `launch` files aren't symlinked unlike Python code.\n  - Rebuild the package when `launch` files are modified.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterpause%2Fros2-workspace-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finterpause%2Fros2-workspace-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterpause%2Fros2-workspace-template/lists"}