diff --git a/Dockerfile b/Dockerfile index f7478f9..8d77c5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,140 +1,104 @@ -FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04 +# syntax=docker/dockerfile:1.7 +ARG CUDA_VER=12.8.0 +ARG UBUNTU_VER=24.04 -# Core runtime + build deps + GL/GLVND -RUN apt-get update && apt-get install -y \ - # graphics / GL - libglvnd0 \ - libgl1 \ - libgl1-mesa-dev \ - mesa-common-dev \ - libegl1 \ - libgles2 \ - libx11-6 \ - libxext6 \ - xvfb \ - libgtk-3-0 \ - libgtk-3-dev \ - libglib2.0-dev \ - \ - # build tools - build-essential \ - autoconf \ - pkg-config \ - curl \ - wget \ - git \ - git-lfs \ - jq \ - libssl-dev \ - ca-certificates \ - \ - # compression/tools - unzip \ +FROM nvidia/cuda:${CUDA_VER}-devel-ubuntu${UBUNTU_VER} AS builder +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential autoconf pkg-config git git-lfs curl wget jq ca-certificates \ + libpng-dev libfreetype6-dev libfontconfig1-dev libxml2-dev ghostscript webp \ + libgtk-3-dev libglib2.0-dev \ + && rm -rf /var/lib/apt/lists/* + +ARG GO_VERSION=1.24.1 +RUN curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -o /tmp/go.tgz \ + && rm -rf /usr/local/go \ + && tar -C /usr/local -xzf /tmp/go.tgz \ + && rm /tmp/go.tgz +ENV PATH=/usr/local/go/bin:$PATH + +RUN git clone --depth 1 --branch fix-screenshot-slider-ticks \ + https://github.com/Arlind-dev/danser-go.git /src/danser \ + && cd /src/danser \ + && go build -ldflags="-s -w" -o /out/danser-cli . \ + && strip /out/danser-cli || true + +RUN set -eux; \ + mkdir -p /out/ffmpeg; \ + URL="$(curl -s https://api.github.com/repos/BtbN/FFmpeg-Builds/releases/latest \ + | jq -r '.assets[].browser_download_url' \ + | grep -E 'linux64-gpl(\-shared)?\.tar\.xz$' \ + | head -n 1)"; \ + wget -qO /tmp/ffmpeg.tar.xz "$URL"; \ + tar -xf /tmp/ffmpeg.tar.xz -C /tmp; \ + FF_DIR="$(find /tmp -maxdepth 1 -type d -name 'ffmpeg-*' | head -n 1)"; \ + cp "$FF_DIR/bin/ffmpeg" /out/ffmpeg/; \ + cp "$FF_DIR/bin/ffprobe" /out/ffmpeg/ || true; \ + cp "$FF_DIR/bin/ffplay" /out/ffmpeg/ || true; \ + if [ -d "$FF_DIR/lib" ]; then mkdir -p /out/ffmpeg/lib && cp -a "$FF_DIR/lib/." /out/ffmpeg/lib/; fi; \ + rm -rf /tmp/ffmpeg* /tmp/ffmpeg.tar.xz + +RUN set -eux; \ + IMAGICK_URL="$(curl -s https://api.github.com/repos/ImageMagick/ImageMagick/releases/latest | jq -r '.tarball_url')"; \ + mkdir -p /tmp/im; \ + wget -qO- "$IMAGICK_URL" | tar xz -C /tmp; \ + cd /tmp/ImageMagick-*; \ + ./configure --prefix=/usr/local \ + --disable-dependency-tracking \ + --disable-docs \ + --without-perl \ + --with-fontconfig=yes \ + --with-freetype=yes \ + --with-gslib=yes \ + --with-jpeg=yes \ + --with-png=yes \ + --with-tiff=yes \ + --with-xml=yes; \ + make -j"$(nproc)"; \ + make install DESTDIR=/tmp/im; \ + rm -rf /tmp/ImageMagick-* + +FROM nvidia/cuda:${CUDA_VER}-runtime-ubuntu${UBUNTU_VER} AS runtime +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update && apt-get install -y --no-install-recommends \ + git curl ca-certificates \ xz-utils \ - zip \ - \ - # image / media deps - libpng-dev \ - libfreetype6-dev \ - libfontconfig1-dev \ - libxml2 \ - libxml2-dev \ - ghostscript \ - webp \ - \ - # fonts - fonts-urw-base35 \ - fonts-noto-color-emoji \ - fonts-dejavu-core \ - \ - && fc-cache -f -v \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* + libglvnd0 libgl1 libegl1 libgles2 \ + libx11-6 libxext6 \ + xvfb \ + libgtk-3-0 libglib2.0-0 \ + libpng16-16 libfreetype6 libfontconfig1 libxml2 ghostscript webp \ + fonts-urw-base35 fonts-noto-color-emoji fonts-dejavu-core \ + && rm -rf /var/lib/apt/lists/* \ + && fc-cache -f -v -# Vulkan / GL debug tools (optional but handy) -RUN apt-get update && apt-get install -y \ - vulkan-tools \ - mesa-utils \ - && rm -rf /var/lib/apt/lists/* +ARG NODE_VERSION=20.11.1 +RUN curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" -o /tmp/node.tar.xz \ + && tar -C /usr/local --strip-components=1 -xf /tmp/node.tar.xz \ + && rm /tmp/node.tar.xz \ + && node --version \ + && npm --version -# NVIDIA GLVND env (paths used by nvidia-container-runtime) ENV LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:${LD_LIBRARY_PATH} ENV __GLX_VENDOR_LIBRARY_NAME=nvidia -# Go toolchain -RUN curl -fsSL https://go.dev/dl/go1.24.1.linux-amd64.tar.gz -o /tmp/go.tar.gz && \ - rm -rf /usr/local/go && \ - tar -C /usr/local -xzf /tmp/go.tar.gz && \ - ln -s /usr/local/go/bin/go /usr/local/bin/go && \ - rm /tmp/go.tar.gz +RUN groupadd -g 1000 appuser 2>/dev/null || true \ + && id -u 1000 >/dev/null 2>&1 || useradd -u 1000 -g 1000 -m -s /bin/bash appuser \ + && mkdir -p /app/danser/{songs,settings,videos,screenshots,custom-replays,skins/default-skin,ffmpeg} -# danser build -RUN git clone --branch fix-screenshot-slider-ticks --single-branch https://github.com/Arlind-dev/danser-go.git /app/danser && \ - cd /app/danser && \ - go build -o danser-cli . && \ - chmod +x /app/danser/danser-cli +COPY --from=builder /out/danser-cli /app/danser/danser-cli +COPY --from=builder /out/ffmpeg/ /app/danser/ffmpeg/ +COPY --from=builder /tmp/im/usr/local/ /usr/local/ -RUN mkdir -p /app/danser/songs \ - /app/danser/settings \ - /app/danser/videos \ - /app/danser/screenshots +ENV LD_LIBRARY_PATH=/app/danser/ffmpeg/lib:${LD_LIBRARY_PATH} +RUN ldconfig -# FFmpeg (prebuilt bundle) -RUN wget -qO- $(curl -s https://api.github.com/repos/BtbN/FFmpeg-Builds/releases/latest \ - | grep "browser_download_url.*linux64-gpl-shared.tar.xz" \ - | cut -d '"' -f 4) -O /tmp/ffmpeg.tar.xz && \ - tar -xvf /tmp/ffmpeg.tar.xz -C /tmp && \ - mv /tmp/ffmpeg-*/bin/* /usr/local/bin/ && \ - mv /tmp/ffmpeg-*/lib/* /usr/local/lib/ && \ - mv /tmp/ffmpeg-*/include/* /usr/local/include/ && \ - mkdir -p /app/danser/ffmpeg && \ - cp /usr/local/bin/ffmpeg /app/danser/ffmpeg/ && \ - cp /usr/local/bin/ffprobe /app/danser/ffmpeg/ || true && \ - cp /usr/local/bin/ffplay /app/danser/ffmpeg/ || true && \ - ldconfig - -# ImageMagick build -RUN IMAGICK_URL=$(curl -s https://api.github.com/repos/ImageMagick/ImageMagick/releases/latest \ - | jq -r '.tarball_url') && \ - wget -qO- "$IMAGICK_URL" | tar xz && \ - cd ImageMagick-* && \ - ./configure --prefix=/usr/local \ - --with-bzlib=yes \ - --with-fontconfig=yes \ - --with-freetype=yes \ - --with-gslib=yes \ - --with-gvc=yes \ - --with-jpeg=yes \ - --with-jp2=yes \ - --with-png=yes \ - --with-tiff=yes \ - --with-xml=yes \ - --with-gs-font-dir=yes && \ - make -j$(nproc) && \ - make install && \ - ldconfig /usr/local/lib/ && \ - cd / && rm -rf ImageMagick-* - -# NodeJS 20 -RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ - && apt-get install -y nodejs \ - && npm install -g npm@latest \ - && rm -rf /var/lib/apt/lists/* - -# danser dirs + assets -RUN mkdir -p /app/danser/custom-replays/ \ - /app/danser/skins/default-skin/ - -COPY src/maps/* /app/danser/songs/ -COPY src/replays/* /app/danser/custom-replays/ -COPY src/settings/* /app/danser/settings/ -COPY src/default-skin/ /app/danser/skins/default-skin/ - -# non-root user 1000:1000 (safe even if uid/gid already exist) -RUN groupadd -g 1000 appuser 2>/dev/null || true && \ - id -u 1000 >/dev/null 2>&1 || useradd -u 1000 -g 1000 -m -s /bin/bash appuser && \ - chown -R 1000:1000 /app +COPY --chown=1000:1000 src/maps/ /app/danser/songs/ +COPY --chown=1000:1000 src/replays/ /app/danser/custom-replays/ +COPY --chown=1000:1000 src/settings/ /app/danser/settings/ +COPY --chown=1000:1000 src/default-skin/ /app/danser/skins/default-skin/ USER 1000:1000 - WORKDIR /app/danser