-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathDockerfile.arm
More file actions
127 lines (107 loc) · 4.21 KB
/
Copy pathDockerfile.arm
File metadata and controls
127 lines (107 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# OpenCastor — SO-ARM101 / LeRobot arm image
# Targets: Raspberry Pi 5 (arm64), alex.local (x86_64 or arm64)
#
# Includes:
# - OpenCastor runtime + castor arm commands
# - LeRobot + feetech-servo-sdk (lerobot[feetech])
# - FFmpeg / media build deps (required by LeRobot)
# - USB serial access (dialout group)
#
# Build:
# docker build -f Dockerfile.arm -t opencastor-arm:latest .
#
# Run (quick test):
# docker run --rm --device /dev/ttyACM0 opencastor-arm castor arm status
# ── Stage 1: Builder ──────────────────────────────────────────────────────────
FROM python:3.12-slim-bookworm AS builder
# System deps: build tools + FFmpeg libs (LeRobot requirement)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
pkg-config \
python3-dev \
# FFmpeg (LeRobot video/episode recording)
libavformat-dev \
libavcodec-dev \
libavdevice-dev \
libavutil-dev \
libswscale-dev \
libswresample-dev \
libavfilter-dev \
ffmpeg \
# OpenCV + display
libgl1-mesa-glx \
libglib2.0-0 \
libsm6 \
libxext6 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
# Install OpenCastor deps
COPY pyproject.toml requirements.txt ./
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# Install OpenCastor + arm extras (feetech + lerobot sdk)
COPY . .
RUN pip install --no-cache-dir --prefix=/install ".[lerobot]"
# Install LeRobot from HuggingFace (full package for lerobot-* CLI tools)
RUN pip install --no-cache-dir --prefix=/install \
"lerobot[feetech] @ git+https://github.com/huggingface/lerobot.git"
# ── Stage 2: Runtime ─────────────────────────────────────────────────────────
FROM python:3.12-slim-bookworm
LABEL org.opencontainers.image.title="OpenCastor ARM"
LABEL org.opencontainers.image.description="OpenCastor + SO-ARM101 + LeRobot"
LABEL org.opencontainers.image.source="https://github.com/craigm26/OpenCastor"
LABEL org.opencontainers.image.licenses="Apache-2.0"
# Runtime system deps
RUN apt-get update && apt-get install -y --no-install-recommends \
# FFmpeg runtime
ffmpeg \
# USB serial (lsusb, /dev/ttyACM*)
usbutils \
# OpenCV headless runtime
libgl1-mesa-glx \
libglib2.0-0 \
libsm6 \
libxext6 \
# Serial port device access
cu \
&& rm -rf /var/lib/apt/lists/*
# Non-root user — member of dialout for USB serial access
RUN groupadd --system castor 2>/dev/null || true && \
useradd --system --gid castor \
--create-home --home-dir /home/castor --shell /bin/bash castor 2>/dev/null || true && \
usermod -aG dialout castor 2>/dev/null || true
WORKDIR /app
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV HOME=/home/castor
ENV OPENCASTOR_DIR=/home/castor/.opencastor
ENV CASTOR_CONFIG=/app/config/arm.rcan.yaml
# Make lerobot-* CLI tools findable
ENV PATH="/usr/local/bin:${PATH}"
# Copy installed packages from builder
COPY --from=builder /install /usr/local
# Copy source
COPY --from=builder /build/castor ./castor
COPY --from=builder /build/pyproject.toml ./
# Config + data mount points
RUN mkdir -p /app/config /app/episodes \
/home/castor/.cache/huggingface/lerobot/calibration/robots/so_follower \
/home/castor/.cache/huggingface/lerobot/calibration/robots/so_leader \
/home/castor/.opencastor && \
chown -R castor:castor /app /home/castor && \
chmod -R 755 /home/castor
# Entrypoint (reuse base one — handles missing config gracefully)
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Arm-specific entrypoint wrapper
COPY docker/arm-entrypoint.sh /arm-entrypoint.sh
RUN chmod +x /arm-entrypoint.sh
USER castor
# Expose web wizard + API
EXPOSE 8000 8765
# Health: just check castor is importable (no gateway needed for arm setup mode)
HEALTHCHECK --interval=60s --timeout=10s --start-period=15s --retries=3 \
CMD python -c "import castor; print('ok')" || exit 1
ENTRYPOINT ["/arm-entrypoint.sh"]
CMD ["castor", "run", "--config", "/app/config/arm.rcan.yaml"]