Skip to content
This repository has been archived by the owner on Dec 13, 2024. It is now read-only.

Re-add user Docker overlay example #86

Merged
merged 2 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .ccache/.gitkeep
Empty file.
16 changes: 16 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Defaults for the MoveIt Studio docker compose agent services.

# Robot configuration package to launch
STUDIO_CONFIG_PACKAGE=picknik_ur_mock_hw_config

# MoveIt Studio version tag
# Be careful! Changing this without understanding the consequences may break your installation.
STUDIO_DOCKER_TAG=2.6.0

# Licensing -- enter your MoveIt Studio license below
STUDIO_LICENSE_KEY=

# User name and UID to use when building the container
# Ensure these settings match your host environment for mounted file permissions.
STUDIO_USERNAME=
STUDIO_USER_UID=
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.ccache/
build/
install/
log/
116 changes: 116 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Docker image for extending MoveIt Studio with a custom overlay.
#
# Example build command (with defaults):
#
# docker build -f ./Dockerfile .
#

# Specify the MoveIt Studio release to build on top of.
ARG MOVEIT_STUDIO_BASE_IMAGE
ARG USERNAME=studio-user
ARG USER_UID=1000
ARG USER_GID=1000

#####################################################
# Starting from the specified MoveIt Studio release #
#####################################################
# The image tag is specified in the argument itself.
# hadolint ignore=DL3006
FROM ${MOVEIT_STUDIO_BASE_IMAGE} as base

# hadolint ignore=DL3002
USER root

# Copy source code from the workspace's ROS 2 packages to a workspace inside the container
ARG USER_OVERLAY_WS=/opt/user_overlay_ws
ENV USER_OVERLAY_WS $USER_OVERLAY_WS
RUN mkdir -p ${USER_OVERLAY_WS}/src ${USER_OVERLAY_WS}/build ${USER_OVERLAY_WS}/install ${USER_OVERLAY_WS}/log
COPY ./src ${USER_OVERLAY_WS}/src

# Create a non-root user
ARG USERNAME
ARG USER_UID
ARG USER_GID

# Also mkdir with user permission directories which will be mounted later to avoid docker creating them as root
WORKDIR $USER_OVERLAY_WS
# hadolint ignore=DL3008
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
groupadd --gid $USER_GID ${USERNAME} && \
useradd --uid $USER_UID --gid $USER_GID --shell /bin/bash --create-home ${USERNAME} && \
apt-get update && \
apt-get install -q -y --no-install-recommends sudo && \
echo ${USERNAME} ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME} && \
mkdir -p \
/home/${USERNAME}/.ccache \
/home/${USERNAME}/.config \
/home/${USERNAME}/.ignition \
/home/${USERNAME}/.ros/log && \
chown -R $USER_UID:$USER_GID /home/${USERNAME} ${USER_OVERLAY_WS} /opt/overlay_ws/

# Install additional dependencies
# You can also add any necessary apt-get install, pip install, etc. commands at this point.
# NOTE: The /opt/overlay_ws folder contains MoveIt Studio binary packages and the source file.
# hadolint ignore=SC1091
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
. /opt/overlay_ws/install/setup.sh && \
apt-get update && \
rosdep install -q -y \
--from-paths src \
--ignore-src

# Remove .bashrc from parent image and create a new one
USER ${USERNAME}
RUN rm /home/${USERNAME}/.bashrc && touch /home/${USERNAME}/.bashrc

#########################################
# Target for compiled, deployable image #
#########################################
FROM base as user-overlay

ARG USERNAME
USER ${USERNAME}

# Compile the workspace
# hadolint ignore=SC1091
RUN --mount=type=cache,target=/home/studio-user/.ccache \
. /opt/overlay_ws/install/setup.sh && \
colcon build

# Add the custom entrypoint
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
RUN echo "source /entrypoint.sh && set +e" >> ~/.bashrc
CMD ["/usr/bin/bash"]

###################################################################
# Target for the developer build which does not compile any code. #
###################################################################
FROM base as user-overlay-dev

USER root

# The location of the user's workspace inside the container
ARG USER_OVERLAY_WS=/opt/user_overlay_ws
ENV USER_OVERLAY_WS $USER_OVERLAY_WS

# Install any additional packages for development work
# hadolint ignore=DL3008
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends \
less \
gdb \
nano

# Add the dev entrypoint
ARG USERNAME
USER ${USERNAME}
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
RUN echo "source /entrypoint.sh && set +e" >> ~/.bashrc
CMD ["/usr/bin/bash"]
Empty file added build/.gitkeep
Empty file.
125 changes: 125 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Docker Compose file for user overlays of the MoveIt Studio images.

version: "3.9"

services:
# Sets common properties for other services. Should not be instantiated directly.
base:
# Extend the installed MoveIt Studio docker compose file.
# Change this to match your environment, if MoveIt Studio was installed to a different location.
extends:
file: ${HOME}/moveit_studio/docker-compose.yaml
service: base
image: moveit-studio-overlay
build:
context: .
target: user-overlay
args:
- USER_UID=${STUDIO_USER_UID:-1000}
- USER_GID=${STUDIO_USER_UID:-1000}
- USERNAME=${USERNAME:-studio-user}
- MOVEIT_STUDIO_BASE_IMAGE=picknikciuser/moveit-studio:${STUDIO_DOCKER_TAG:-main}

# Starts the MoveIt Studio Agent
agent:
extends: base
privileged: true
# Allow the user to use the host's network video4linux and usb_device devices.
# "c 81:* rmw": This rule specifies that the container has read, write, and mknod access (rmw) to all character devices (c) with a major number of 81 (video4linux).
# "c 189:* rmw": This rule gives the container read, write, and mknod access (rmw) to all character devices (c) with a major number of 189 (usb_device).
device_cgroup_rules:
- "c 81:* rmw"
- "c 189:* rmw"
depends_on:
rest_api:
condition: service_healthy
volumes:
# Allow the user to run graphical programs from within the docker container.
- /tmp/.X11-unix:/tmp/.X11-unix:ro
# Allow access to host hardware e.g. RealSense cameras
- /dev:/dev
# TODO: replace this tee here and in common_aliases with some integrated logger
command: bash -c "ros2 launch moveit_studio_agent studio_agent.launch.py 2>&1 | tee -a ~/.ros/log/agent_0_0.log"

# Starts the Bridge between the Agent and the Web UI
bridge:
extends: base
depends_on:
agent:
condition: service_started
# TODO: replace this tee here and in common_aliases with some integrated logger
command: bash -c "ros2 launch moveit_studio_bridge studio_bridge.launch.py 2>&1 | tee -a ~/.ros/log/bridge_0_0.log"

# Starts the frontend-agent
frontend_agent:
extends: base
command: /usr/lib/formant/agent/formant-agent

# Starts the REST API for the Web UI
rest_api:
extends: base
healthcheck:
test: "curl -f http://localhost:3200/objectives"
interval: 5s
timeout: 1m
# TODO: replace this tee here and in common_aliases with some integrated logger
command: bash -c "ros2 launch moveit_studio_rest_api rest_api.launch.py 2>&1 | tee -a ~/.ros/log/rest_api_0_0.log"

# Starts the robot drivers
drivers:
extends: base
privileged: true
# Ensures the drivers container has RT priority
ulimits:
rtprio: 99
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0" # Allow access to the gripper.
# TODO: replace this tee here and in common_aliases with some integrated logger
command: bash -c "ros2 launch moveit_studio_agent robot_drivers.launch.py 2>&1 | tee -a ~/.ros/log/robot_0_0.log"

web_ui:
image: picknikciuser/moveit-studio-frontend:${STUDIO_DOCKER_TAG:-main}
ports:
- "80:80"
network_mode: host

# Starts RViz for visualization.
rviz:
extends: base
profiles:
- rviz
command: bash -c "ros2 launch moveit_studio_agent developer_rviz.launch.py"

# Starts MoveIt Setup Assistant for creating MoveIt configurations.
setup_assistant:
extends: base
profiles:
- setup_assistant
command: bash -c "ros2 launch moveit_setup_assistant setup_assistant.launch.py"

# Developer specific configuration
dev:
extends: base
build:
target: user-overlay-dev
image: moveit-studio-overlay-dev
stdin_open: true
tty: true
privileged: true
volumes:
# Mount the source code, colcon generated artifacts, and ccache
- ./src/:/opt/user_overlay_ws/src:rw
- ./build/:/opt/user_overlay_ws/build:rw
- ./install/:/opt/user_overlay_ws/install:rw
- ./log/:/opt/user_overlay_ws/log:rw
- ./.ccache/:/home/${USERNAME:-studio-user}/.ccache:rw
- ${HOME}/.ros/log_moveit_studio:/root/.ros/log:/root/.ros/log
# Allow access to host hardware e.g. RealSense cameras
- /dev:/dev
command: sleep infinity
# Making a separate profile prevents this service from being built when using `docker compose build`
# and launched when using `docker compose up`.
profiles: ["dev"]

volumes:
ignition_resources:
24 changes: 24 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

# Custom entrypoint to start when running an image that overlays MoveIt Studio

set +e

# Source the MoveIt Studio binaries and your workspace
source "/opt/overlay_ws/install/setup.bash"
if [ -f "${USER_OVERLAY_WS}/install/local_setup.bash" ]; then
source "${USER_OVERLAY_WS}/install/local_setup.bash"
fi

# Set the location for custom Behavior package generation
export STUDIO_GENERATE_PACKAGE_OUTPUT_PATH="${USER_OVERLAY_WS}/src"

# Set the permissions for your non-root user at startup.
# shellcheck source=bin/docker/utils/change_permissions.sh
source /moveit_studio_utils/change_permissions.sh

# Set the DDS configuration for ROS 2 inter-process communication.
# shellcheck source=bin/docker/utils/copy_dds_configs.sh
source /moveit_studio_utils/copy_dds_configs.sh

exec "$@"
Empty file added install/.gitkeep
Empty file.
Empty file added log/.gitkeep
Empty file.