Skip to content
36 changes: 36 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "vortex-image-segmentation-devcontainer",
"image": "vortex-image-segmentation:latest",
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "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"
]
}
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/
75 changes: 75 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# ----------------------------------------------------------------------------
# Base Image
# ----------------------------------------------------------------------------
ARG BASE_IMAGE=ros:humble
FROM ${BASE_IMAGE}

# ----------------------------------------------------------------------------
# Setup Arguments & Environment
# ----------------------------------------------------------------------------
USER root
SHELL ["/bin/bash", "-c"]
ARG DEBIAN_FRONTEND=noninteractive
ARG ROS_DISTRO=humble

# Define User Args
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=devuser

ENV WORKSPACE=/ros2_ws
WORKDIR ${WORKSPACE}

# ----------------------------------------------------------------------------
# Create non-root user
# ----------------------------------------------------------------------------
RUN groupadd --gid ${GROUP_ID} ${USERNAME} || true && \
useradd --uid ${USER_ID} --gid ${GROUP_ID} -m -s /bin/bash ${USERNAME} || true && \
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/*

# ----------------------------------------------------------------------------
# Install System Dependencies
# ----------------------------------------------------------------------------
RUN apt-get update && apt-get install -y \
git \
python3-vcstool \
python3-pip \
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/*

RUN pip3 install cython

# ----------------------------------------------------------------------------
# Copy & Install Requirements
# ----------------------------------------------------------------------------
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.
RUN chown -R ${USER_ID}:${GROUP_ID} ${WORKSPACE}

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

# ----------------------------------------------------------------------------
# User Configuration
# ----------------------------------------------------------------------------
RUN echo "if [ -f /ros2_ws/scripts/bashrc_extra.sh ]; then source /ros2_ws/scripts/bashrc_extra.sh; fi" >> /home/${USERNAME}/.bashrc

# Switch to the user
USER ${USERNAME}
WORKDIR /home/${USERNAME}

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 "======================================================================"
32 changes: 32 additions & 0 deletions docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/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 \
--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