78 lines
4.0 KiB
Docker
78 lines
4.0 KiB
Docker
# syntax=docker/dockerfile:1
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Sanad Package 4 — Custom AI Guide Tour (sanad-guide). SELF-CONTAINED Python
|
|
# orchestrator (vendors the SanadV3 engine + Mask lib; FROM python:3.10-slim; NO
|
|
# ROS2). Bridges to the SEPARATE sanad-nav (web_nav3) stack over HTTP (WEB_NAV3_URL).
|
|
# docker build -t sanad-p4:latest . (Jetson without buildx: DOCKER_BUILDKIT=0)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
ARG BASE_OS_IMAGE=python:3.10-slim-bookworm
|
|
FROM ${BASE_OS_IMAGE}
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=/app
|
|
WORKDIR /app
|
|
|
|
# audio + PortAudio (pyaudio) + BlueZ/D-Bus (mask) + iproute2 (chest-mic `ip`) +
|
|
# libGL/glib (opencv-headless camera for optional recognition).
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates libsndfile1 alsa-utils pulseaudio-utils iproute2 \
|
|
portaudio19-dev libportaudio2 build-essential python3-dev \
|
|
bluez libdbus-1-3 libglib2.0-0 libgl1 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY requirements.txt /tmp/requirements.txt
|
|
RUN python3 -m pip install --no-cache-dir --upgrade pip \
|
|
&& python3 -m pip install --no-cache-dir -r /tmp/requirements.txt
|
|
|
|
# Optional Unitree SDK — chest (builtin) audio over DDS (full CycloneDDS + idlc).
|
|
ARG WITH_UNITREE_SDK=1
|
|
ENV CYCLONEDDS_HOME=/usr/local LD_LIBRARY_PATH=/usr/local/lib
|
|
RUN if [ "$WITH_UNITREE_SDK" = "1" ]; then \
|
|
( set -eux; apt-get update; apt-get install -y --no-install-recommends git cmake build-essential; \
|
|
git clone --depth 1 -b releases/0.10.x https://github.com/eclipse-cyclonedds/cyclonedds /tmp/cyclonedds; \
|
|
cmake -S /tmp/cyclonedds -B /tmp/cyclonedds/build -DCMAKE_INSTALL_PREFIX=/usr/local; \
|
|
cmake --build /tmp/cyclonedds/build --target install -j"$(nproc)"; \
|
|
CYCLONEDDS_HOME=/usr/local CMAKE_PREFIX_PATH=/usr/local python3 -m pip install --no-cache-dir "cyclonedds==0.10.2"; \
|
|
git clone --depth 1 https://github.com/unitreerobotics/unitree_sdk2_python /opt/unitree_sdk2_python; \
|
|
python3 -m pip install --no-cache-dir -e /opt/unitree_sdk2_python; \
|
|
python3 -c "import unitree_sdk2py; print('unitree_sdk2py OK')"; \
|
|
rm -rf /tmp/cyclonedds /var/lib/apt/lists/*; ) \
|
|
|| echo "WARN[P4]: Unitree SDK build failed — chest audio unavailable; use SANAD_AUDIO_PROFILE=plugged"; \
|
|
else echo "WITH_UNITREE_SDK=0 — skipping Unitree SDK"; fi
|
|
|
|
COPY vendor/sanad_pkg /app/sanad_pkg
|
|
RUN mkdir -p /etc/sanad && cp /app/sanad_pkg/pubkey.ed25519 /etc/sanad/pubkey.ed25519
|
|
COPY vendor/mask /app/mask
|
|
COPY vendor/Sanad /app/Sanad
|
|
|
|
# P4 launcher + NEW tour engine + routers + entrypoint + config.
|
|
COPY app_p4.py /app/app_p4.py
|
|
COPY tour_engine.py /app/tour_engine.py
|
|
COPY routes_tour.py /app/routes_tour.py
|
|
COPY routes_p4.py /app/routes_p4.py
|
|
COPY entrypoint.sh /app/entrypoint.sh
|
|
COPY config /app/pkg4_config
|
|
RUN chmod +x /app/entrypoint.sh
|
|
|
|
COPY strip_key.py /tmp/strip_key.py
|
|
RUN python3 /tmp/strip_key.py && rm -f /tmp/strip_key.py
|
|
|
|
RUN python3 - <<'PY'
|
|
import importlib.util as u, sys
|
|
ok = all(u.find_spec(m) for m in ("sanad_pkg.license", "Sanad", "tour_engine",
|
|
"Sanad.navigation.web_nav3_client", "Sanad.navigation.goal_monitor"))
|
|
print("P4 self-contained: modules + nav bridge importable:", ok)
|
|
sys.exit(0 if ok else 1)
|
|
PY
|
|
|
|
ENV SANAD_PACKAGE=P4 \
|
|
SANAD_DASHBOARD_PORT=8014 \
|
|
SANAD_DASHBOARD_HOST=0.0.0.0 \
|
|
SANAD_MASK_DIR=/app/mask \
|
|
SANAD_TOURS_DIR=/app/Sanad/data/tours \
|
|
WEB_NAV3_URL=http://127.0.0.1:8765 \
|
|
SANAD_ROBOT_NAME=sanad \
|
|
SANAD_LICENSE=/etc/sanad/sanad.lic \
|
|
SANAD_PUBKEY=/etc/sanad/pubkey.ed25519
|
|
EXPOSE 8014
|
|
ENTRYPOINT ["/app/entrypoint.sh"]
|