js8call/docker/Dockerfile.runtime
2025-06-27 19:01:18 -04:00

164 lines
No EOL
7.9 KiB
Text

# Runtime container for JS8Call with X11 and audio support
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
# X11 support
x11-apps \
x11-utils \
libx11-6 \
libxext6 \
libxrender1 \
libxtst6 \
libxi6 \
libxrandr2 \
libxcursor1 \
libxinerama1 \
libxkbcommon-x11-0 \
# Qt6 runtime dependencies
qt6-base-dev \
libqt6core6 \
libqt6gui6 \
libqt6widgets6 \
libqt6multimedia6 \
libqt6serialport6 \
libqt6svg6 \
libqt6opengl6 \
# Audio support (PulseAudio and ALSA)
pulseaudio \
pulseaudio-utils \
alsa-utils \
libasound2t64 \
libpulse0 \
# Other runtime dependencies
libfftw3-single3 \
libusb-1.0-0 \
libudev1 \
libboost-filesystem1.83.0 \
libboost-thread1.83.0 \
libboost-system1.83.0 \
# Utilities
wget \
ca-certificates \
file \
&& rm -rf /var/lib/apt/lists/*
# Create a non-root user for running the application
# Try to use UID 1000 for PulseAudio compatibility, but use next available if taken
RUN if ! id -u 1000 >/dev/null 2>&1; then \
useradd -m -s /bin/bash -u 1000 js8call; \
else \
useradd -m -s /bin/bash js8call; \
fi && \
mkdir -p /home/js8call/.config && \
chown -R js8call:js8call /home/js8call && \
usermod -a -G audio,video js8call
# Create config directory
RUN mkdir -p /home/js8call/.config && \
chown -R js8call:js8call /home/js8call/.config
# Create directory for the extracted application
RUN mkdir -p /opt/js8call && \
chown js8call:js8call /opt/js8call
# Set up environment for Qt and audio
ENV QT_X11_NO_MITSHM=1
ENV ALSA_CARD=0
# Create entrypoint script
RUN echo '#!/bin/bash' > /opt/js8call/entrypoint.sh && \
echo 'set -e' >> /opt/js8call/entrypoint.sh && \
echo '' >> /opt/js8call/entrypoint.sh && \
echo '# Check if AppImage exists' >> /opt/js8call/entrypoint.sh && \
echo 'if [ ! -f /tmp/js8call.AppImage ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Error: JS8Call AppImage not found at /tmp/js8call.AppImage"' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Please mount the AppImage to the container"' >> /opt/js8call/entrypoint.sh && \
echo ' exit 1' >> /opt/js8call/entrypoint.sh && \
echo 'fi' >> /opt/js8call/entrypoint.sh && \
echo '' >> /opt/js8call/entrypoint.sh && \
echo '# Check if we need to extract' >> /opt/js8call/entrypoint.sh && \
echo 'if [ ! -f /opt/js8call/extracted/AppRun ] && [ ! -f /opt/js8call/extracted/js8call ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Extracting AppImage..."' >> /opt/js8call/entrypoint.sh && \
echo ' cd /opt/js8call' >> /opt/js8call/entrypoint.sh && \
echo ' # Make AppImage executable first' >> /opt/js8call/entrypoint.sh && \
echo ' cp /tmp/js8call.AppImage /tmp/js8call-exec.AppImage' >> /opt/js8call/entrypoint.sh && \
echo ' chmod +x /tmp/js8call-exec.AppImage' >> /opt/js8call/entrypoint.sh && \
echo ' # Extract the AppImage' >> /opt/js8call/entrypoint.sh && \
echo ' /tmp/js8call-exec.AppImage --appimage-extract > /dev/null 2>&1 || {' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Standard extraction failed, trying manual extraction..."' >> /opt/js8call/entrypoint.sh && \
echo ' mkdir -p /opt/js8call/extracted' >> /opt/js8call/entrypoint.sh && \
echo ' cd /opt/js8call/extracted' >> /opt/js8call/entrypoint.sh && \
echo ' unsquashfs -f -d . /tmp/js8call-exec.AppImage || {' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Failed to extract AppImage"' >> /opt/js8call/entrypoint.sh && \
echo ' exit 1' >> /opt/js8call/entrypoint.sh && \
echo ' }' >> /opt/js8call/entrypoint.sh && \
echo ' }' >> /opt/js8call/entrypoint.sh && \
echo ' # Move extracted contents if needed' >> /opt/js8call/entrypoint.sh && \
echo ' if [ -d /opt/js8call/squashfs-root ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' mv /opt/js8call/squashfs-root /opt/js8call/extracted' >> /opt/js8call/entrypoint.sh && \
echo ' fi' >> /opt/js8call/entrypoint.sh && \
echo ' rm -f /tmp/js8call-exec.AppImage' >> /opt/js8call/entrypoint.sh && \
echo 'fi' >> /opt/js8call/entrypoint.sh && \
echo '' >> /opt/js8call/entrypoint.sh && \
echo '# Find the executable' >> /opt/js8call/entrypoint.sh && \
echo 'if [ -f /opt/js8call/extracted/AppRun ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' EXEC_PATH="/opt/js8call/extracted/AppRun"' >> /opt/js8call/entrypoint.sh && \
echo 'elif [ -f /opt/js8call/extracted/js8call ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' EXEC_PATH="/opt/js8call/extracted/js8call"' >> /opt/js8call/entrypoint.sh && \
echo 'elif [ -f /opt/js8call/extracted/usr/bin/js8call ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' EXEC_PATH="/opt/js8call/extracted/usr/bin/js8call"' >> /opt/js8call/entrypoint.sh && \
echo 'else' >> /opt/js8call/entrypoint.sh && \
echo ' EXEC_PATH=$(find /opt/js8call/extracted -name "js8call" -type f -executable | head -1)' >> /opt/js8call/entrypoint.sh && \
echo ' if [ -z "$EXEC_PATH" ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Could not find js8call executable in extracted AppImage"' >> /opt/js8call/entrypoint.sh && \
echo ' ls -la /opt/js8call/extracted/' >> /opt/js8call/entrypoint.sh && \
echo ' exit 1' >> /opt/js8call/entrypoint.sh && \
echo ' fi' >> /opt/js8call/entrypoint.sh && \
echo 'fi' >> /opt/js8call/entrypoint.sh && \
echo '' >> /opt/js8call/entrypoint.sh && \
echo '# Copy existing config if mounted' >> /opt/js8call/entrypoint.sh && \
echo 'if [ -d /tmp/js8call-config ] && [ -f /tmp/js8call-config/JS8Call.ini ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Loading existing configuration..."' >> /opt/js8call/entrypoint.sh && \
echo ' mkdir -p /home/js8call/.config' >> /opt/js8call/entrypoint.sh && \
echo ' cp /tmp/js8call-config/JS8Call.ini /home/js8call/.config/JS8Call.ini' >> /opt/js8call/entrypoint.sh && \
echo 'fi' >> /opt/js8call/entrypoint.sh && \
echo '' >> /opt/js8call/entrypoint.sh && \
echo '# Launch JS8Call from extracted directory' >> /opt/js8call/entrypoint.sh && \
echo 'echo "Starting JS8Call from $EXEC_PATH..."' >> /opt/js8call/entrypoint.sh && \
echo 'cd /opt/js8call/extracted' >> /opt/js8call/entrypoint.sh && \
echo '"$EXEC_PATH" "$@"' >> /opt/js8call/entrypoint.sh && \
echo 'EXIT_CODE=$?' >> /opt/js8call/entrypoint.sh && \
echo '' >> /opt/js8call/entrypoint.sh && \
echo '# Copy config file back if mounted' >> /opt/js8call/entrypoint.sh && \
echo 'if [ -d /tmp/js8call-config ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' if [ -f /home/js8call/.config/JS8Call.ini ]; then' >> /opt/js8call/entrypoint.sh && \
echo ' echo "Saving configuration..."' >> /opt/js8call/entrypoint.sh && \
echo ' cp /home/js8call/.config/JS8Call.ini /tmp/js8call-config/JS8Call.ini' >> /opt/js8call/entrypoint.sh && \
echo ' fi' >> /opt/js8call/entrypoint.sh && \
echo 'fi' >> /opt/js8call/entrypoint.sh && \
echo '' >> /opt/js8call/entrypoint.sh && \
echo 'exit $EXIT_CODE' >> /opt/js8call/entrypoint.sh
RUN chmod +x /opt/js8call/entrypoint.sh && \
chown js8call:js8call /opt/js8call/entrypoint.sh
# Install squashfs-tools for extraction
RUN apt-get update && apt-get install -y squashfs-tools && rm -rf /var/lib/apt/lists/*
# Make sure js8call user can access X11
RUN mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix
# Make home directory writable by any user
RUN chmod -R 777 /home/js8call && \
mkdir -p /home/js8call/.local/share && \
chmod -R 777 /home/js8call/.local
# Switch to non-root user
USER js8call
WORKDIR /home/js8call
# Default command
CMD ["/opt/js8call/entrypoint.sh"]