Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
39d0b03
Add Dockerfile and GitHub Actions workflow for building AOC Docker im…
marc-hanheide Feb 16, 2026
6400cd7
Add GitHub Actions workflow for building AOC Docker images with multi…
marc-hanheide Feb 16, 2026
b3e9a40
Update Docker build workflow to enable sequential builds and dynamic …
marc-hanheide Feb 16, 2026
7f2808b
Add CUDA Dockerfile and update build workflow for CUDA support
marc-hanheide Feb 16, 2026
6e0c408
Refactor Docker build configuration to use ROS_DISTRO variable for ta…
marc-hanheide Feb 16, 2026
a1fe98d
Add ROS installation and setup commands to CUDA Dockerfile
marc-hanheide Feb 16, 2026
a16011a
Add ROS_DISTRO argument and environment variables to CUDA Dockerfile
marc-hanheide Feb 16, 2026
71f257b
Add ARG declarations for BASE_IMAGE and ROS_DISTRO in Dockerfiles
marc-hanheide Feb 16, 2026
3f967cb
Add CUDA Dockerfile stages for base and desktop images with ROS support
marc-hanheide Feb 16, 2026
14e9331
Comment out cache-from and cache-to lines in Docker build configuration
marc-hanheide Feb 16, 2026
728dad1
Move python3-rosdep installation to the correct stage in Dockerfile
marc-hanheide Feb 16, 2026
3749deb
Add target specification for Docker build stage in workflow
marc-hanheide Feb 16, 2026
0d530ee
Add additional CUDA Dockerfile stages for base and desktop images wit…
marc-hanheide Feb 16, 2026
c55cbf2
Uncomment cache-from and cache-to lines in Docker build configuration
marc-hanheide Feb 16, 2026
ac535ef
Initialize rosdep before updating in Dockerfile
marc-hanheide Feb 16, 2026
1a5d2bf
Add support for ROS Jazzy in Docker build configuration
marc-hanheide Feb 16, 2026
37b628f
Refactor Docker build configuration by removing unused desktop stage …
marc-hanheide Feb 16, 2026
2e8ba15
Add reusable Docker image build workflow and CUDA desktop Dockerfile
marc-hanheide Feb 16, 2026
6a10ecd
Add outputs section for image digest in Docker build workflow
marc-hanheide Feb 16, 2026
8d66679
Reorder Docker build steps to ensure proper setup of buildx before bu…
marc-hanheide Feb 16, 2026
0591fb5
Fix Dockerfile syntax for ros installation
marc-hanheide Feb 16, 2026
7665cde
feat: add seperate display container
cooperj Feb 16, 2026
e9e2e9a
Merge branch 'main' into display
marc-hanheide Feb 16, 2026
940098f
ci: rename the container from `display` to `vnc` add CI building
cooperj Feb 17, 2026
2f6514f
ci: disable requirement for ros distro, allowing for non ros builds
cooperj Feb 17, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/_build-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
required: true
type: string
ros_distro:
required: true
required: false
type: string
dockerfile:
required: true
Expand Down Expand Up @@ -79,4 +79,4 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BASE_IMAGE=${{ inputs.base_image }}
ROS_DISTRO=${{ inputs.ros_distro }}
ROS_DISTRO=${{ inputs.ros_distro }}
10 changes: 10 additions & 0 deletions .github/workflows/docker-build-and-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ on:

jobs:

# ── VNC Container Building ──────────────────────-────────────────────────
vnc:
uses: ./.github/workflows/_build-image.yaml
with:
base_image: debian:trixie-slim
push_image: vnc
dockerfile: vnc.dockerfile
architectures: linux/amd64,linux/arm64
secrets: inherit

# ── Level 0: no dependencies ──────────────────────────────────────────────

ros-humble:
Expand Down
78 changes: 78 additions & 0 deletions docker/vnc-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/bash

echo
echo "****************************************************************************************************************************************"
echo "AOC VNC container starting..."
echo "****************************************************************************************************************************************"


echo "starting turbovnc"
sudo rm -rf /tmp/.X1-lock /tmp/.X11-unix/X1 > /dev/null 2>&1
screen -dmS turbovnc bash -c 'VGL_DISPLAY=egl VGL_FPS=30 /opt/TurboVNC/bin/vncserver :1 -depth 24 -noxstartup -securitytypes TLSNone,X509None,None 2>&1 | tee /tmp/vnc.log; read -p "Press any key to continue..."'
# wait for VNC to be running

echo "waiting for display to be up"
while ! xdpyinfo -display :1 2> /dev/null > /dev/null; do
sleep .1
done
echo "display is up"

echo "starting xfce4"
screen -dmS xfce4 bash -c 'DISPLAY=:1 /usr/bin/xfce4-session 2>&1 | tee /tmp/xfce4.log'
while [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; do
if pgrep xfce4-session > /dev/null; then
XFCE_PID=$(pgrep xfce4-session)
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$XFCE_PID/environ|cut -d= -f2-|tr -d '\0')
fi
sleep .1
done
echo "xfce4 up"

echo "starting novnc ${NOVNC_VERSION}"
screen -dmS novnc bash -c '/usr/local/novnc/noVNC-${NOVNC_VERSION}/utils/novnc_proxy --vnc localhost:5901 --listen 5801 2>&1 | tee /tmp/novnc.log'

DISPLAY=:1 xhost +local: 2>/dev/null
echo "xhost +local: applied to :1"

# ensure wallpaper/panels are applied; start xfdesktop if missing
(
sleep 8
export DISPLAY=:1
export DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS"

# start xfdesktop if not running so it can apply the wallpaper
if ! pgrep -u "$USER" xfdesktop > /dev/null 2>&1; then
xfdesktop --daemon > /dev/null 2>&1 || true
fi

WALLPAPER="/usr/share/backgrounds/xfce/aoc_wallpaper.jpg"

# apply wallpaper for monitor0 (add others if needed)
xfconf-query -c xfce4-desktop -np /backdrop/screen0/monitor0/image-path -t string -s "$WALLPAPER" > /dev/null 2>&1
xfconf-query -c xfce4-desktop -np /backdrop/screen0/monitor0/last-image -t string -s "$WALLPAPER" > /dev/null 2>&1
xfconf-query -c xfce4-desktop -np /backdrop/screen0/monitor0/workspace0/last-image -t string -s "$WALLPAPER" > /dev/null 2>&1
xfconf-query -c xfce4-desktop -np /backdrop/screen0/monitor0/image-show -t bool -s true > /dev/null 2>&1

# remove secondary panel if present
xfconf-query -c xfce4-panel -p /panels/panel-2 -r > /dev/null 2>&1 || true
xfce4-panel --reload > /dev/null 2>&1 || true

xfdesktop --reload > /dev/null 2>&1 || true
) &

echo
echo "****************************************************************************************************************************************"
echo "VNC Desktop ready. Open your browser at http://localhost:5801/vnc.html?autoconnect=true or another hostname and port you may have forwarded."
echo "****************************************************************************************************************************************"
echo

echo >&2

# This script can either be a wrapper around arbitrary command lines,
# or it will simply exec bash if no arguments were given
if [[ $# -eq 0 ]]; then
exec "/bin/bash"
else
exec "$@"
fi

154 changes: 154 additions & 0 deletions vnc.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
ARG BASE_IMAGE=debian:trixie-slim
FROM ${BASE_IMAGE} AS base

ARG BASE_IMAGE
ARG username=aoc
ENV BASE_IMAGE=${BASE_IMAGE}

ENV DEBIAN_FRONTEND=noninteractive \
DISPLAY=:1 \
VNC_PORT=5900 \
NOVNC_PORT=5801 \
RESOLUTION=1366x768x24

# Install timezone
RUN ln -fs /usr/share/zoneinfo/UTC /etc/localtime \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends tzdata \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*

# Install packages
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
gnupg2 \
lsb-release \
nano \
sudo \
python3-setuptools \
wget \
libglvnd0 \
libgl1 \
libglx0 \
libegl1 \
libxext6 \
libx11-6 \
x11-utils \
python3-minimal \
python3-pip \
python3-numpy \
python3-venv \
less \
tmux \
screen \
unzip \
x11-apps \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN useradd -m -s /bin/bash -G video,sudo ${username} && \
echo "${username} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# Fix /tmp/.X11-unix permissions
RUN mkdir -p /tmp/.X11-unix && \
chmod 1777 /tmp/.X11-unix

# Install VirtualGL
ARG TARGETARCH
ENV DEBIAN_FRONTEND=noninteractive
RUN curl -L -O https://github.com/VirtualGL/virtualgl/releases/download/3.1.1/virtualgl_3.1.1_${TARGETARCH}.deb && \
apt-get update && \
apt-get -y install ./virtualgl_3.1.1_${TARGETARCH}.deb && \
rm virtualgl_3.1.1_${TARGETARCH}.deb && rm -rf /var/lib/apt/lists/*
RUN curl -L -O https://github.com/TurboVNC/turbovnc/releases/download/3.1.1/turbovnc_3.1.1_${TARGETARCH}.deb && \
apt-get update && \
apt-get -y install ./turbovnc_3.1.1_${TARGETARCH}.deb && \
rm turbovnc_3.1.1_${TARGETARCH}.deb && rm -rf /var/lib/apt/lists/*
RUN addgroup --system vglusers && adduser ${username} vglusers


# Install noVNC
ENV NOVNC_VERSION=1.4.0
ENV WEBSOCKETIFY_VERSION=0.10.0

RUN mkdir -p /usr/local/novnc && \
curl -sSL https://github.com/novnc/noVNC/archive/v${NOVNC_VERSION}.zip -o /tmp/novnc-install.zip && \
unzip /tmp/novnc-install.zip -d /usr/local/novnc && \
cp /usr/local/novnc/noVNC-${NOVNC_VERSION}/vnc.html /usr/local/novnc/noVNC-${NOVNC_VERSION}/index.html && \
curl -sSL https://github.com/novnc/websockify/archive/v${WEBSOCKETIFY_VERSION}.zip -o /tmp/websockify-install.zip && \
unzip /tmp/websockify-install.zip -d /usr/local/novnc && \
ln -s /usr/local/novnc/websockify-${WEBSOCKETIFY_VERSION} /usr/local/novnc/noVNC-${NOVNC_VERSION}/utils/websockify && \
rm -f /tmp/websockify-install.zip /tmp/novnc-install.zip && \
sed -i -E 's/^python /python3 /' /usr/local/novnc/websockify-${WEBSOCKETIFY_VERSION}/run

RUN cat <<EOF > /usr/share/glvnd/egl_vendor.d/10_nvidia.json
{
"file_format_version" : "1.0.0",
"ICD" : {
"library_path" : "libEGL_nvidia.so.0"
}
}
EOF

FROM base AS xfce

# Install XFCE4
RUN apt-get update && \
apt-get -y install \
xfce4-session \
xfce4-panel \
xfdesktop4 \
konsole \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get purge -y xfce4-screensaver

# thunar

COPY docker/vnc-entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]

# Set default XFCE wallpaper -- doesnt work
# COPY aoc_wallpaper.jpg /usr/share/backgrounds/xfce/aoc_wallpaper.jpg
# RUN mkdir -p /home/${username}/.config/xfce4/xfconf/xfce-perchannel-xml && \
# cat > /home/${username}/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml <<'EOF'
# <?xml version="1.0" encoding="UTF-8"?>
# <channel name="xfce4-desktop" version="1.0">
# <property name="backdrop" type="empty">
# <property name="screen0" type="empty">
# <property name="monitor0" type="empty">
# <property name="image-path" type="string" value="/usr/share/backgrounds/xfce/aoc_wallpaper.jpg"/>
# <property name="last-image" type="string" value="/usr/share/backgrounds/xfce/aoc_wallpaper.jpg"/>
# <property name="image-show" type="bool" value="true"/>
# <property name="workspace0" type="empty">
# <property name="last-image" type="string" value="/usr/share/backgrounds/xfce/aoc_wallpaper.jpg"/>
# </property>
# </property>
# </property>
# </property>
# </channel>
# EOF
RUN chown -R ${username}:${username} /home/${username}/.config

# Allow other containers to share windows into this display
RUN echo 'xhost +local: 2>/dev/null' >> ~/.bashrc

EXPOSE 5801

USER ${username}
ENV HOME=/home/${username}
WORKDIR ${HOME}
RUN mkdir -p ${HOME}/.local/bin

ENV DISPLAY=:1
ENV TVNC_VGL=1
ENV VGL_ISACTIVE=1
ENV VGL_FPS=25
ENV VGL_COMPRESS=0
ENV VGL_DISPLAY=egl
ENV VGL_WM=1
ENV VGL_PROBEGLX=0
ENV LD_PRELOAD=/usr/lib/libdlfaker.so:/usr/lib/libvglfaker.so
ENV SHELL=/bin/bash
Loading