Skip to content
37 changes: 37 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "vortex-image-segmentation-devcontainer",
"image": "vortex-image-segmentation:latest",
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"extensions": [
"ms-azuretools.vscode-docker",
"ms-vscode.cpptools",
"ranch-hand-robotics.rde-pack",
"ms-python.vscode-pylance",
"twxs.cmake",
"ms-vsliveshare.vsliveshare",
"eamodio.gitlens",
"njpwerner.autodocstring",
"cschlosser.doxdocgen",
"xaver.clang-format",
"visualstudioexptteam.vscodeintellicode",
"ms-vscode-remote.remote-ssh",
"gxl.git-graph-3",
"ms-vscode-remote.remote-containers",
"gruntfuggly.todo-tree"
]
}
},
"remoteUser": "devuser",
"workspaceFolder": "/ros2_ws",
"workspaceMount": "source=${localWorkspaceFolder},target=/ros2_ws,type=bind,consistency=cached",
"runArgs": [
"--privileged",
"--network=host",
"--ipc=host",
"--user=1000:1000"
]
}
30 changes: 30 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Ignore build artifacts and large/runtime folders
build/
install/
log/
*.log

# Docker and local config
docker/
.dockerignore

# VCS
.git
.gitignore

# VS Code
.vscode/

# Python
__pycache__/
*.pyc
*.pyo
*.pyd
venv/
.env

# Misc
*.swp
*.swo
node_modules/
bags/
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,10 @@ runs/
*.pt
*jpg

# ROS 2 build artifacts
install/
build/
log/

# data
data/
77 changes: 77 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# ----------------------------------------------------------------------------
# Base Image
# ----------------------------------------------------------------------------
ARG BASE_IMAGE=ros:humble
FROM ${BASE_IMAGE}

# ----------------------------------------------------------------------------
# Install System & ROS Dependencies
# ----------------------------------------------------------------------------
USER root
SHELL ["/bin/bash", "-c"]
ARG DEBIAN_FRONTEND=noninteractive

ENV WORKSPACE=/ros2_ws
WORKDIR ${WORKSPACE}
ARG ROS_DISTRO=humble

RUN apt-get update && apt-get install -y \
git \
python3-rosdep \
python3-vcstool \
python3-pip \
ros-${ROS_DISTRO}-ros-core \
ros-${ROS_DISTRO}-cv-bridge \
ros-${ROS_DISTRO}-vision-msgs \
ros-${ROS_DISTRO}-pcl-conversions \
libopencv-dev \
libpcl-dev \
python3-colcon-common-extensions \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

# ----------------------------------------------------------------------------
# Ensure Cython is installed (for building packages like lapx)
# ----------------------------------------------------------------------------
RUN pip3 install cython


# ----------------------------------------------------------------------------
# Copy requirements.txt and install Python dependencies first for better caching
# ----------------------------------------------------------------------------
COPY requirements.txt ${WORKSPACE}/requirements.txt
RUN pip3 install -r ${WORKSPACE}/requirements.txt

# ----------------------------------------------------------------------------
# Copy Workspace Files
# ----------------------------------------------------------------------------
COPY . ${WORKSPACE}
Copy link

Copilot AI Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workspace is owned by root (COPY is executed as root user) but later switched to a non-root user. This will cause permission issues when the non-root user tries to write to the workspace. Consider changing ownership of the workspace after copying: RUN chown -R ${USER_ID}:${GROUP_ID} ${WORKSPACE}

Copilot uses AI. Check for mistakes.

# ----------------------------------------------------------------------------
# Install ROS dependencies
# ----------------------------------------------------------------------------
RUN rosdep update && rosdep install --from-paths . --ignore-src -r -y

# ----------------------------------------------------------------------------
# Create non-root user
# ----------------------------------------------------------------------------
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=devuser
RUN groupadd --gid ${GROUP_ID} ${USERNAME} || true && \
useradd --uid ${USER_ID} --gid ${GROUP_ID} -m -s /bin/bash ${USERNAME} || true && \
Copy link

Copilot AI Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The groupadd and useradd commands use || true to suppress errors if the user/group already exists, but this silently ignores all errors including genuine failures. Consider using more specific error handling or checking if the user exists first.

Suggested change
RUN groupadd --gid ${GROUP_ID} ${USERNAME} || true && \
useradd --uid ${USER_ID} --gid ${GROUP_ID} -m -s /bin/bash ${USERNAME} || true && \
RUN if ! getent group ${USERNAME} >/dev/null; then groupadd --gid ${GROUP_ID} ${USERNAME}; fi && \
if ! id -u ${USERNAME} >/dev/null 2>&1; then useradd --uid ${USER_ID} --gid ${GROUP_ID} -m -s /bin/bash ${USERNAME}; fi && \

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignoring this. removing "|| true" creates problems for mac users (and possibly windows), as it uses different ids automatically assigned.

apt-get update && apt-get install -y sudo && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \
apt-get clean && rm -rf /var/lib/apt/lists/*

USER ${USERNAME}
WORKDIR /home/${USERNAME}

# ----------------------------------------------------------------------------
# Source user bashrc_extra.sh in bashrc
# ----------------------------------------------------------------------------
RUN echo "if [ -f /ros2_ws/scripts/bashrc_extra.sh ]; then source /ros2_ws/scripts/bashrc_extra.sh; fi" >> ~/.bashrc

# ----------------------------------------------------------------------------
# Default command
# ----------------------------------------------------------------------------
CMD ["bash"]
57 changes: 57 additions & 0 deletions docker/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
set -euo pipefail

# ------------------------------------------------------------------------------
# Environment Variables
# ------------------------------------------------------------------------------
IMAGE="vortex-image-segmentation:latest" # Docker image name/tag
BASE_IMAGE="ros:humble" # Base image for Docker builds

# ------------------------------------------------------------------------------
# Platform Detection
# ------------------------------------------------------------------------------
ARCHITECTURE="$(uname -m)"
if [[ "$ARCHITECTURE" == "arm64" || "$ARCHITECTURE" == "aarch64" ]]; then
PLATFORM="linux/arm64"
elif [[ "$ARCHITECTURE" == "x86_64" ]]; then
PLATFORM="linux/amd64"
else
echo "Unsupported architecture: $ARCHITECTURE" >&2
exit 1
fi

# ------------------------------------------------------------------------------
# Locate Script and Workspace Root
# ------------------------------------------------------------------------------
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
WORKSPACE="$(realpath "$SCRIPT_DIR/..")"

# ------------------------------------------------------------------------------
# Build Start Info
# ------------------------------------------------------------------------------
echo "======================================================================"
echo " Building Docker Image"
echo " • PLATFORM: $PLATFORM"
echo " • BASE_IMAGE: $BASE_IMAGE"
echo " • IMAGE: $IMAGE"
echo " • BUILD CONTEXT: $WORKSPACE"
echo "======================================================================"
echo ""

# ------------------------------------------------------------------------------
# Build Docker Image with Buildx
# ------------------------------------------------------------------------------
docker buildx build \
--platform "$PLATFORM" \
--build-arg BASE_IMAGE="$BASE_IMAGE" \
--build-arg USER_ID="$(id -u)" \
--build-arg GROUP_ID="$(id -g)" \
--tag "$IMAGE" \
--file "$SCRIPT_DIR/Dockerfile" \
--load \
"$WORKSPACE"

echo ""
echo "======================================================================"
echo " Successfully built image '$IMAGE' for platform '$PLATFORM'"
echo "======================================================================"
33 changes: 33 additions & 0 deletions docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail

# ------------------------------------------------------------------------------
# Image Configuration
# ------------------------------------------------------------------------------
IMAGE="vortex-image-segmentation:latest" # Default Docker image name/tag

# ------------------------------------------------------------------------------
# Locate Script Directory and Workspace Root
# ------------------------------------------------------------------------------
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
WORKSPACE="$(realpath "$SCRIPT_DIR/..")"

echo "======================================================================"
echo " Running Container"
echo " • IMAGE: $IMAGE"
echo " • Volume mount: $WORKSPACE -> /ros2_ws"
echo "======================================================================"
echo ""

# ------------------------------------------------------------------------------
# Run Docker Container
# ------------------------------------------------------------------------------
docker run -it --rm \
--user "$(id -u):$(id -g)" \
--privileged \
--network host \
--ipc=host \
-v "$WORKSPACE":/ros2_ws \
-w /ros2_ws \
"$IMAGE" \
/bin/bash
19 changes: 19 additions & 0 deletions scripts/bashrc_extra.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
# /ros2_ws/scripts/bashrc_extra.sh for ROS 2 container

# Print actions for clarity
if [ -f /opt/ros/humble/setup.bash ]; then
echo "[bashrc_extra] Sourcing ROS 2 underlay: /opt/ros/humble/setup.bash"
source /opt/ros/humble/setup.bash
else
echo "[bashrc_extra] ROS 2 underlay not found: /opt/ros/humble/setup.bash"
fi

if [ -f /ros2_ws/install/setup.bash ]; then
echo "[bashrc_extra] Sourcing workspace overlay: /ros2_ws/install/setup.bash"
source /ros2_ws/install/setup.bash
else
echo "[bashrc_extra] Workspace overlay not found: /ros2_ws/install/setup.bash"
fi

# Add your custom shell commands, aliases, or environment variables below
Loading