Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docker): add simulator-visualizer container #5411

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
docker
!docker/etc
!docker/scripts
!docker/tools

# Ignore a part of files under src
src/**/.*
Expand Down
31 changes: 30 additions & 1 deletion .github/actions/docker-build-and-push/action.yaml
Copy link
Member

Choose a reason for hiding this comment

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

How about creating a docker-build-and-push-tools action, similar to docker-build-and-push-cuda action, instead of appending to the docker-build-and-push action?
https://github.com/autowarefoundation/autoware/blob/main/.github/actions/docker-build-and-push-cuda/action.yaml

Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,34 @@ runs:
flavor: |
latest=false

- name: Docker meta for autoware:visualizer
id: meta-visualizer
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ inputs.target-image }}
tags: |
type=raw,value=visualizer-${{ inputs.platform }}
type=raw,value=visualizer-${{ steps.date.outputs.date }}-${{ inputs.platform }}
type=ref,event=tag,prefix=visualizer-,suffix=-${{ inputs.platform }}
bake-target: docker-metadata-action-visualizer
flavor: |
latest=false

- name: Docker meta for autoware:simulator
id: meta-simulator
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ inputs.target-image }}
tags: |
type=raw,value=simulator-${{ inputs.platform }}
type=raw,value=simulator-${{ steps.date.outputs.date }}-${{ inputs.platform }}
type=ref,event=tag,prefix=simulator-,suffix=-${{ inputs.platform }}
bake-target: docker-metadata-action-simulator
flavor: |
latest=false

- name: Docker meta for autoware:universe-devel
id: meta-universe-devel
id: meta-devel
Copy link
Member

Choose a reason for hiding this comment

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

I think it should be reverted.

Suggested change
id: meta-devel
id: meta-universe-devel

uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ inputs.target-image }}
Expand Down Expand Up @@ -220,6 +246,7 @@ runs:
push: true
files: |
docker/docker-bake.hcl
docker/docker-bake-tools.hcl
${{ steps.meta-core-devel.outputs.bake-file }}
${{ steps.meta-universe-sensing-perception-devel.outputs.bake-file }}
${{ steps.meta-universe-sensing-perception.outputs.bake-file }}
Expand All @@ -231,6 +258,8 @@ runs:
${{ steps.meta-universe-vehicle-system.outputs.bake-file }}
${{ steps.meta-universe-devel.outputs.bake-file }}
${{ steps.meta-universe.outputs.bake-file }}
${{ steps.meta-simulator.outputs.bake-file }}
${{ steps.meta-visualizer.outputs.bake-file }}
provenance: false
set: |
${{ inputs.build-args }}
22 changes: 22 additions & 0 deletions docker/docker-bake-tools.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
group "default" {
targets = [
"simulator",
"visualizer"
]
}

// For docker/metadata-action
target "docker-metadata-action-simulator" {}
target "docker-metadata-action-visualizer" {}

target "simulator" {
inherits = ["docker-metadata-action-simulator"]
dockerfile = "docker/tools/Dockerfile"
target = "simulator"
}

target "visualizer" {
inherits = ["docker-metadata-action-visualizer"]
dockerfile = "docker/tools/Dockerfile"
target = "visualizer"
}
104 changes: 104 additions & 0 deletions docker/tools/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
ARG ROS_DISTRO

### Builder
FROM ghcr.io/autowarefoundation/autoware:universe-devel AS builder
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ENV CCACHE_DIR="/root/.ccache"
WORKDIR /autoware
COPY src /autoware/src
COPY simulator.repos /autoware/simulator.repos
COPY docker/scripts/resolve_rosdep_keys.sh /autoware/resolve_rosdep_keys.sh
RUN chmod +x /autoware/resolve_rosdep_keys.sh

# Install dependencies and build the simulator
RUN --mount=type=ssh \
--mount=type=cache,target=/var/cache/apt,sharing=locked \
vcs import src < simulator.repos \
&& apt-get update \
&& rosdep update && rosdep install -y --from-paths src --ignore-src --rosdistro $ROS_DISTRO \
&& source /opt/ros/"$ROS_DISTRO"/setup.bash && source /opt/autoware/setup.bash \
&& colcon build --cmake-args \
"-Wno-dev" \
"--no-warn-unused-cli" \
--install-base /opt/autoware \
--merge-install \
--mixin release compile-commands ccache \
--base-paths /autoware/src/simulator \
&& find /opt/autoware/lib -type f -name "*.py" -exec chmod +x {} \; \
&& find /opt/autoware/share -type f -name "*.py" -exec chmod +x {} \; \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* "$HOME"/.cache

# Extract rosdep dependencies for simulator
RUN /autoware/resolve_rosdep_keys.sh /autoware/src/simulator ${ROS_DISTRO} \
> /rosdep-simulator-depend-packages.txt \
&& cat /rosdep-simulator-depend-packages.txt

### Simulator
FROM ghcr.io/autowarefoundation/autoware:universe AS simulator
WORKDIR /autoware
COPY --from=builder /opt/autoware /opt/autoware
COPY --from=builder /rosdep-simulator-depend-packages.txt /tmp/rosdep-simulator-depend-packages.txt

RUN --mount=type=ssh \
--mount=type=cache,target=/var/cache/apt,sharing=locked \
apt-get update && apt-get install -y curl unzip \
&& source /opt/ros/"$ROS_DISTRO"/setup.bash && source /opt/autoware/setup.bash \
&& rosdep update \
# Remove xmlschema and yamale from rosdep packages since we install via pip
&& sed -i '/\(xmlschema\|yamale\)/d' /tmp/rosdep-simulator-depend-packages.txt \
&& pip install yamale xmlschema \
&& cat /tmp/rosdep-simulator-depend-packages.txt | xargs apt-get install -y --no-install-recommends \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* "$HOME"/.cache && \
echo "source /opt/autoware/setup.bash" > /etc/bash.bashrc

COPY docker/tools/etc/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/bin/bash"]

### Visualizer
FROM simulator AS visualizer
WORKDIR /autoware

# Install openbox and VNC requirements

Check warning on line 65 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (openbox)
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
curl unzip openbox tigervnc-standalone-server tigervnc-common \

Check warning on line 67 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (openbox)

Check warning on line 67 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (tigervnc)

Check warning on line 67 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (tigervnc)
novnc websockify python3-numpy python3-xdg \

Check warning on line 68 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (novnc)

Check warning on line 68 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (websockify)
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Set up VNC password
RUN mkdir -p ~/.vnc && \
echo "openadkit" | vncpasswd -f > ~/.vnc/passwd && \

Check warning on line 74 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (vncpasswd)
Copy link
Member

Choose a reason for hiding this comment

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

We don’t want to write the password directly in the Dockerfile. We want to pass it through an environment variable.

chmod 600 ~/.vnc/passwd

# Create SSL certificate for NoVNC
RUN openssl req -x509 -nodes -newkey rsa:2048 \

Check warning on line 78 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (newkey)
-keyout /etc/ssl/private/novnc.key \

Check warning on line 79 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (keyout)

Check warning on line 79 in docker/tools/Dockerfile

View workflow job for this annotation

GitHub Actions / spell-check-differential

Unknown word (novnc)
-out /etc/ssl/certs/novnc.crt \
-days 365 \
-subj "/O=Autoware-OpenADKit/CN=localhost"

# Install ngrok for optional public access if no public ip available
RUN curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
| tee /etc/apt/sources.list.d/ngrok.list && \
apt update && \
apt install ngrok

# Need to expose VNC and NoVNC ports when running the container
EXPOSE 5900 6080

# Add source commands to bash startup
RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> /root/.bashrc && \
echo "source /opt/autoware/setup.bash" >> /root/.bashrc

# Copy startup scripts
COPY docker/tools/etc/xstartup /root/.vnc/xstartup
COPY docker/tools/etc/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh && chmod +x /root/.vnc/xstartup
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/bin/bash"]
82 changes: 82 additions & 0 deletions docker/tools/etc/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env bash

configure_vnc() {
# Create Openbox application configuration
mkdir -p /etc/xdg/openbox
cat >/etc/xdg/openbox/rc.xml <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<openbox_config xmlns="http://openbox.org/3.4/rc"
xmlns:xi="http://www.w3.org/2001/XInclude">
<applications>
<application name="rviz2">
<maximized>yes</maximized>
<position force="yes">
<x>center</x>
<y>center</y>
</position>
<focus>yes</focus>
<desktop>1</desktop>
</application>
</applications>
</openbox_config>
EOF
# Create rviz2 start script
cat >/usr/local/bin/start-rviz2.sh <<'EOF'
#!/bin/bash
source /opt/ros/humble/setup.bash
source /opt/autoware/setup.bash
if [ -n "$RVIZ_CONFIG" ]; then
exec rviz2 -d "$RVIZ_CONFIG"
else
exec rviz2
fi
EOF
chmod +x /usr/local/bin/start-rviz2.sh
echo "echo 'Autostart executed at $(date)' >> /tmp/autostart.log" >>/etc/xdg/openbox/autostart
echo "/usr/local/bin/start-rviz2.sh" >>/etc/xdg/openbox/autostart

# Start VNC server with Openbox
echo "Starting VNC server with Openbox..."
vncserver :99 -geometry 1024x768 -depth 16 -pixelformat rgb565
VNC_RESULT=$?

if [ $VNC_RESULT -ne 0 ]; then
echo "Failed to start VNC server (exit code: $VNC_RESULT)"
exit $VNC_RESULT
fi

# Set the DISPLAY variable to match VNC server
echo "Setting DISPLAY to :99"
echo "export DISPLAY=:99" >>~/.bashrc
sleep 2

# Start NoVNC
echo "Starting NoVNC..."
websockify --daemon --web=/usr/share/novnc/ --cert=/etc/ssl/certs/novnc.crt --key=/etc/ssl/private/novnc.key 6080 localhost:5999

# Configure ngrok if set
if [ -n "$NGROK_AUTHTOKEN" ]; then
ngrok config add-authtoken "$NGROK_AUTHTOKEN"

if [ -n "$NGROK_URL" ]; then
ngrok http --url="$NGROK_URL" 6080 --log=stdout >ngrok.log &
else
ngrok http 6080 --log=stdout >ngrok.log &
sleep 2
NGROK_URL=$(grep -oP 'url=\K[^\s]+' ngrok.log)
fi
fi

# Print info
echo -e "\033[32m-------------------------------------------------------------------------\033[0m"
echo -e "\033[32mBrowser interface available at local address http://$(hostname -I | cut -d' ' -f1):6080/vnc.html?resize=scale&password=openadkit&autoconnect=true\033[0m"
[ -z "$NGROK_AUTHTOKEN" ] && echo -e "\033[32mIf you have a static public ip you can access it on WEB at http://$(curl -s ifconfig.me):6080/vnc.html?resize=scale&password=openadkit&autoconnect=true\033[0m"
[ -n "$NGROK_AUTHTOKEN" ] && echo -e "\033[32mBrowser interface available at WEB address $NGROK_URL/vnc.html?resize=scale&password=openadkit&autoconnect=true\033[0m"
echo -e "\033[32m-------------------------------------------------------------------------\033[0m"
}

# shellcheck disable=SC1090
[ "$VNC_ENABLED" == "true" ] && configure_vnc
source "/opt/ros/$ROS_DISTRO/setup.bash"
source "/opt/autoware/setup.bash"
exec "$@"
15 changes: 15 additions & 0 deletions docker/tools/etc/xstartup
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
export DISPLAY=:99

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r "$HOME/.Xresources" ] && xrdb "$HOME/.Xresources"

# Start Openbox window manager
echo "Starting Openbox window manager..."
openbox-session &

# Keep the session alive
sleep infinity
Loading