Files
MusicBot/Dockerfile
T
Miles WardandClaude Fable 5.1 e772eb7c2b
Build and Test / Build and Test (push) Canceled after 1m24s
Gitea copy: $uicide Music Bot — image, Unraid template, CI, publishing
Fork of purnell569/MusicBot 0.7.1 (JMusicBot), kept here as a reliable
copy with a container image built and served from this Gitea.

- README retitled "$uicide Music Bot"; lineage table, Gitea image, Unraid
  and release instructions. Nothing under src/ changes.
- Dockerfile: Maven stage on $BUILDPLATFORM (JAR is arch-neutral, so no
  QEMU for the build), OCI labels point at this repo and record commit and
  version via GIT_SHA/VERSION build args.
- docker/entrypoint.sh: check the data dir is writable up front (the bot's
  own error for that is a misleading "another instance is running"), and
  on a missing config.txt run the bot's generate-config and stop with
  instructions instead of prompting on a console that does not exist.
- deploy/unraid/musicbot.xml: Unraid template, --user 99:100 default.
- .gitea/workflows/build-and-test.yml: mvn verify + docker build on push;
  its presence makes Gitea ignore the GitHub-only workflows in .github/.
- scripts/build-and-publish-unraid.sh + docs/PUBLISHING.md: release
  runbook (keychain-safe registry push, release with zipped JAR).
- docker-compose.example.yml points at the Gitea image.

Upstream's v0.7.1 tag is preserved as upstream/v0.7.1; this repository's
own release tag v0.7.1 is on this commit.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-17 19:19:59 -04:00

107 lines
4.4 KiB
Docker

# syntax=docker/dockerfile:1.12
# Multi-stage build for JMusicBot
# Stage 1: Build the application
# The JAR is architecture-neutral (the natives it bundles are chosen by the pom,
# not by the build host), so this stage runs natively on whatever machine is
# building — no QEMU for Maven when producing linux/amd64 on Apple Silicon.
FROM --platform=$BUILDPLATFORM maven:3.9.12-eclipse-temurin-25-alpine AS builder
ARG BUILD_TIMESTAMP
ENV BUILD_TIMESTAMP=$BUILD_TIMESTAMP
WORKDIR /build
# Copy pom.xml first for better layer caching
COPY --link pom.xml .
# Download dependencies with BuildKit cache mount for Maven repository
# This significantly speeds up builds by persisting dependencies between builds
RUN --mount=type=cache,target=/root/.m2/repository \
mvn dependency:go-offline -B -Pdocker
# Copy source code
COPY --link src ./src
# Build the application with BuildKit cache mount
RUN --mount=type=cache,target=/root/.m2/repository \
if [ -n "$BUILD_TIMESTAMP" ]; then \
mvn clean package -DskipTests -B -Pdocker -Dproject.build.outputTimestamp="$BUILD_TIMESTAMP"; \
else \
mvn clean package -DskipTests -B -Pdocker; \
fi
# Stage 2: Create custom minimal JRE using jlink
# Using noble (Ubuntu 24.04) for glibc 2.39 compatibility with native libraries
FROM eclipse-temurin:25-jdk-noble AS jre-builder
# Create a minimal JRE with only the modules JMusicBot needs
# Modules determined by: jdeps --print-module-deps --ignore-missing-deps <jar>
# Plus runtime-loaded modules that jdeps can't detect:
# java.base - Core Java classes
# java.compiler - Annotation processing (used by some libraries)
# java.desktop - GUI support (Swing/AWT, even for headless mode)
# java.logging - SLF4J/Logback logging
# java.naming - JNDI (required by Logback)
# java.net.http - HTTP client API
# java.scripting - ScriptEngine for EvalCmd (Rhino)
# java.security.jgss - Kerberos/GSS-API security
# java.sql - JDBC (used by some dependencies)
# jdk.crypto.ec - Elliptic curve crypto for TLS/SSL (Discord API) - runtime loaded
# jdk.management - JMX management extensions
# jdk.unsupported - Native library access (jdave, udpqueue)
RUN $JAVA_HOME/bin/jlink \
--add-modules java.base,java.compiler,java.desktop,java.logging,java.naming,java.net.http,java.scripting,java.security.jgss,java.sql,jdk.crypto.ec,jdk.management,jdk.unsupported \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=zip-6 \
--output /javaruntime
# Stage 3: Runtime image
# Using Bitnami minideb:trixie (Debian 13) for minimal size with glibc 2.41
# Required for jdave/udpqueue native libraries which need glibc >= 2.38
FROM bitnami/minideb:trixie
# Provenance: which commit and version this image was built from. Set by
# scripts/build-and-publish-unraid.sh; harmless when left empty.
ARG GIT_SHA=""
ARG VERSION=""
# OCI image labels for better traceability and management
LABEL org.opencontainers.image.title="\$uicide Music Bot" \
org.opencontainers.image.description="A cross-platform Discord music bot with a clean interface (JMusicBot fork)" \
org.opencontainers.image.url="https://gitea.milesward.dev/mward4/MusicBot" \
org.opencontainers.image.source="https://gitea.milesward.dev/mward4/MusicBot" \
org.opencontainers.image.documentation="https://gitea.milesward.dev/mward4/MusicBot/src/branch/main/README.md" \
org.opencontainers.image.revision="$GIT_SHA" \
org.opencontainers.image.version="$VERSION" \
org.opencontainers.image.vendor="Miles Ward" \
org.opencontainers.image.licenses="Apache-2.0"
# Copy custom JRE from jre-builder stage
ENV JAVA_HOME=/opt/java/openjdk
ENV PATH="${JAVA_HOME}/bin:${PATH}"
COPY --from=jre-builder /javaruntime $JAVA_HOME
# Create non-root user and application directories in single layer
RUN groupadd --gid 10001 jmusicbot && \
useradd --uid 10001 --gid 10001 --shell /bin/false jmusicbot && \
mkdir -p /app /musicbot && \
chown -R jmusicbot:jmusicbot /app /musicbot
# Copy the built JAR from builder stage
COPY --from=builder --chown=jmusicbot:jmusicbot /build/target/JMusicBot-*-All.jar /app/app.jar
# Copy and set permissions for entrypoint script
COPY --chown=jmusicbot:jmusicbot --chmod=755 docker/entrypoint.sh /app/entrypoint.sh
WORKDIR /musicbot
# Switch to non-root user for security
USER jmusicbot
ENTRYPOINT ["/app/entrypoint.sh"]