From 167743efadb6fcf5d426ddbe6cca71c0a26e531b Mon Sep 17 00:00:00 2001 From: wompmacho Date: Tue, 19 May 2026 11:24:39 +0000 Subject: [PATCH] adding slopsmith docker --- docker_compose/slopsmith/docker-compose.yaml | 49 +++++ docker_compose/slopsmith/dockerfile | 182 +++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 docker_compose/slopsmith/docker-compose.yaml create mode 100644 docker_compose/slopsmith/dockerfile diff --git a/docker_compose/slopsmith/docker-compose.yaml b/docker_compose/slopsmith/docker-compose.yaml new file mode 100644 index 0000000..7c73fb7 --- /dev/null +++ b/docker_compose/slopsmith/docker-compose.yaml @@ -0,0 +1,49 @@ +# slopsmith - https://github.com/byrongamatos/slopsmith +services: + slopsmith: + build: + context: . + dockerfile: dockerfile + args: + # Set to 'true' to bake the plugin into the image during build + - PLUGIN_SECTION_MAP=true + - PLUGIN_NOTE_DETECTION=true + - PLUGIN_FIND_MORE_CDLC=true + - PLUGIN_SPLIT_SCREEN=true + - PLUGIN_SLOPPAK_CONVERTER=true + - PLUGIN_INVERT_HIGHWAY=true + - PLUGIN_JUMPING_TAB=true + - PLUGIN_STEP_MODE=true + - PLUGIN_THEMES=true + - PLUGIN_TUNER=true + container_name: slopsmith-web + volumes: + - "Rocksmith_CDLC:/dlc" + - "${CONFIG_DIR_PATH}:/config" + # Only mount this if you want to override the baked-in plugins or add manual ones + # - "./plugins:/app/plugins" + environment: + - DLC_DIR=/dlc + - CONFIG_DIR=/config + ports: + - "${SLOPSMITH_PORT}:8000" + restart: unless-stopped + labels: + # Nginx Proxy Manager Automation + - "npm.proxy.domains=slopsmith" + - "npm.proxy.host=${DOCKER_HOST_IP}" + - "npm.proxy.port=${SLOPSMITH_PORT}" + - "npm.proxy.scheme=https" + - "npm.proxy.ssl_verify=false" + - "npm.proxy.websockets=true" + # Pi-hole Automation (Point to Docker Host/Proxy IP) + - "pihole.custom-record=[[\"slopsmith\", \"${DOCKER_HOST_IP}\"]]" + +volumes: + Rocksmith_CDLC: + name: Rocksmith_CDLC + driver_opts: + type: nfs + o: addr=${NAS_ADDR},nolock,soft,rw + device: :${DLC_DIR_PATH} + diff --git a/docker_compose/slopsmith/dockerfile b/docker_compose/slopsmith/dockerfile new file mode 100644 index 0000000..42e1a85 --- /dev/null +++ b/docker_compose/slopsmith/dockerfile @@ -0,0 +1,182 @@ +# ── Stage 1: Build RsCli ───────────────────────────────────────────────── +FROM python:3.12-slim AS builder +ARG TARGETARCH + +RUN apt-get update && apt-get install -y --no-install-recommends curl git && rm -rf /var/lib/apt/lists/* + +RUN curl -sL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh \ + && chmod +x /tmp/dotnet-install.sh \ + && /tmp/dotnet-install.sh --channel 10.0 --install-dir /usr/share/dotnet \ + && ln -s /usr/share/dotnet/dotnet /usr/local/bin/dotnet + +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 +ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 + +RUN git clone --depth 1 https://github.com/iminashi/Rocksmith2014.NET.git /tmp/rs2014 +RUN git clone --depth 1 https://github.com/byrongamatos/slopsmith.git /tmp/slopsmith + +RUN mkdir -p /tmp/rs2014/tools/RsCli/ \ + && cp /tmp/slopsmith/rscli/RsCli.fsproj /tmp/rs2014/tools/RsCli/ \ + && cp /tmp/slopsmith/rscli/Program.fs /tmp/rs2014/tools/RsCli/ + +RUN sed -i 's||false|' /tmp/rs2014/Directory.Build.props \ + && cd /tmp/rs2014/tools/RsCli \ + && arch="${TARGETARCH:-$(dpkg --print-architecture)}" \ + && case "$arch" in \ + arm64|aarch64) RID=linux-arm64 ;; \ + amd64|x86_64) RID=linux-x64 ;; \ + *) echo "Unsupported build architecture: $arch" >&2; exit 1 ;; \ + esac \ + && dotnet publish -c Release -r "$RID" --self-contained -o /opt/rscli + +# ── Stage 1b: Build native vgmstream-cli for target arch ───────────────────── +FROM python:3.12-slim AS vgmstream-builder +ARG VGMSTREAM_REF=r2083 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + pkg-config \ + yasm \ + libmpg123-dev \ + libvorbis-dev \ + libspeex-dev \ + libavformat-dev \ + libavcodec-dev \ + libavutil-dev \ + libswresample-dev \ + libopus-dev \ + git \ + && rm -rf /var/lib/apt/lists/* + +RUN git clone --depth 1 --branch "${VGMSTREAM_REF}" https://github.com/vgmstream/vgmstream.git /tmp/vgmstream + +RUN cmake -S /tmp/vgmstream -B /tmp/vgmstream/build \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_V123=OFF \ + -DBUILD_AUDACIOUS=OFF \ + -DBUILD_SHARED_LIBS=OFF \ + && cmake --build /tmp/vgmstream/build --config Release --target vgmstream_cli -j"$(nproc)" \ + && mkdir -p /out \ + && cp /tmp/vgmstream/build/cli/vgmstream-cli /out/vgmstream-cli + +# ── Stage 2: Final image ──────────────────────────────────────────────── +FROM python:3.12-slim + +# Accept all plugin toggles +ARG PLUGIN_ULTIMATE_GUITAR=false +ARG PLUGIN_TAB_IMPORT=false +ARG PLUGIN_PRACTICE_JOURNAL=false +ARG PLUGIN_SETLIST_BUILDER=false +ARG PLUGIN_METRONOME=false +ARG PLUGIN_TONE_PLAYER=false +ARG PLUGIN_FRETBOARD=false +ARG PLUGIN_TAB_VIEW=false +ARG PLUGIN_MIDI_AMP_CONTROL=false +ARG PLUGIN_SECTION_MAP=false +ARG PLUGIN_RS1_EXTRACTOR=false +ARG PLUGIN_BASE_GAME_EXTRACTOR=false +ARG PLUGIN_ARRANGEMENT_EDITOR=false +ARG PLUGIN_PROFILE_IMPORT=false +ARG PLUGIN_MIDI_CAPO=false +ARG PLUGIN_NOTE_DETECTION=false +ARG PLUGIN_FIND_MORE_CDLC=false +ARG PLUGIN_PIANO_HIGHWAY=false +ARG PLUGIN_STUDIO=false +ARG PLUGIN_DRUM_HIGHWAY=false +ARG PLUGIN_SPLIT_SCREEN=false +ARG PLUGIN_SLOPPAK_CONVERTER=false +ARG PLUGIN_STEMS_MIXER=false +ARG PLUGIN_INVERT_HIGHWAY=false +ARG PLUGIN_JUMPING_TAB=false +ARG PLUGIN_STEP_MODE=false +ARG PLUGIN_LYRICS_SYNC=false +ARG PLUGIN_NAM_TONE_ENGINE=false +ARG PLUGIN_GUITAR_THEORY_LAB=false +ARG PLUGIN_THEMES=false +ARG PLUGIN_UPDATE_MANAGER=false +ARG PLUGIN_TUNER=false +ARG PLUGIN_SIMPLIFY_CHORDS=false + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ffmpeg \ + fluidsynth \ + fluid-soundfont-gm \ + libsndfile1 \ + curl \ + megatools \ + libmpg123-0 \ + libvorbisfile3 \ + libspeex1 \ + libopus0 \ + git \ + openssl \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=vgmstream-builder /out/vgmstream-cli /usr/local/bin/vgmstream-cli +RUN chmod +x /usr/local/bin/vgmstream-cli + +COPY --from=builder /opt/rscli /opt/rscli + +WORKDIR /app + +RUN git clone --depth 1 https://github.com/byrongamatos/slopsmith.git /tmp/slopsmith \ + && cp -a /tmp/slopsmith/. /app/ \ + && rm -rf /tmp/slopsmith \ + && cd /app/plugins \ + && if [ "$PLUGIN_ULTIMATE_GUITAR" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-ug.git ultimate_guitar; fi \ + && if [ "$PLUGIN_TAB_IMPORT" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-tabimport.git tab_import; fi \ + && if [ "$PLUGIN_PRACTICE_JOURNAL" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-practice.git practice_journal; fi \ + && if [ "$PLUGIN_SETLIST_BUILDER" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-setlist.git setlist; fi \ + && if [ "$PLUGIN_METRONOME" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-metronome.git metronome; fi \ + && if [ "$PLUGIN_TONE_PLAYER" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-tones.git tones; fi \ + && if [ "$PLUGIN_FRETBOARD" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-fretboard.git fretboard; fi \ + && if [ "$PLUGIN_TAB_VIEW" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-tabview.git tab_view; fi \ + && if [ "$PLUGIN_MIDI_AMP_CONTROL" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-midi.git midi_amp; fi \ + && if [ "$PLUGIN_SECTION_MAP" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-sectionmap.git section_map; fi \ + && if [ "$PLUGIN_RS1_EXTRACTOR" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-rs1extract.git rs1_extract; fi \ + && if [ "$PLUGIN_BASE_GAME_EXTRACTOR" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-discextract.git disc_extract; fi \ + && if [ "$PLUGIN_ARRANGEMENT_EDITOR" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-editor.git editor; fi \ + && if [ "$PLUGIN_PROFILE_IMPORT" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-profileimport.git profileimport; fi \ + && if [ "$PLUGIN_MIDI_CAPO" = "true" ]; then git clone --depth 1 https://github.com/masc0t/slopsmith-plugin-midi-capo.git midi_capo; fi \ + && if [ "$PLUGIN_NOTE_DETECTION" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-notedetect.git note_detect; fi \ + && if [ "$PLUGIN_FIND_MORE_CDLC" = "true" ]; then git clone --depth 1 https://github.com/masc0t/slopsmith-plugin-find-more.git find_more; fi \ + && if [ "$PLUGIN_PIANO_HIGHWAY" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-piano.git piano; fi \ + && if [ "$PLUGIN_STUDIO" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-studio.git studio; fi \ + && if [ "$PLUGIN_DRUM_HIGHWAY" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-drums.git drums; fi \ + && if [ "$PLUGIN_SPLIT_SCREEN" = "true" ]; then git clone --depth 1 https://github.com/topkoa/slopsmith-plugin-splitscreen.git splitscreen; fi \ + && if [ "$PLUGIN_SLOPPAK_CONVERTER" = "true" ]; then git clone --depth 1 https://github.com/topkoa/slopsmith-plugin-sloppak-converter.git sloppak_converter; fi \ + && if [ "$PLUGIN_STEMS_MIXER" = "true" ]; then git clone --depth 1 https://github.com/topkoa/slopsmith-plugin-stems.git stems; fi \ + && if [ "$PLUGIN_INVERT_HIGHWAY" = "true" ]; then git clone --depth 1 https://github.com/masc0t/slopsmith-plugin-invert-highway.git invert_highway; fi \ + && if [ "$PLUGIN_JUMPING_TAB" = "true" ]; then git clone --depth 1 https://github.com/renanboni/slopsmith-plugin-jumpingtab.git jumpingtab; fi \ + && if [ "$PLUGIN_STEP_MODE" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-stepmode.git step_mode; fi \ + && if [ "$PLUGIN_LYRICS_SYNC" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-lyrics-sync.git lyrics_sync; fi \ + && if [ "$PLUGIN_NAM_TONE_ENGINE" = "true" ]; then git clone --depth 1 https://github.com/byrongamatos/slopsmith-plugin-nam-tone.git nam_tone; fi \ + && if [ "$PLUGIN_GUITAR_THEORY_LAB" = "true" ]; then git clone --depth 1 https://github.com/topkoa/slopsmith-plugin-guitar-theory.git guitar_theory_lab; fi \ + && if [ "$PLUGIN_THEMES" = "true" ]; then git clone --depth 1 https://github.com/masc0t/slopsmith-plugin-themes.git themes; fi \ + && if [ "$PLUGIN_UPDATE_MANAGER" = "true" ]; then git clone --depth 1 https://github.com/masc0t/slopsmith-update-manager.git update_manager; fi \ + && if [ "$PLUGIN_TUNER" = "true" ]; then git clone --depth 1 https://github.com/OmikronApex/slopsmith-plugin-tuner.git tuner; fi \ + && if [ "$PLUGIN_SIMPLIFY_CHORDS" = "true" ]; then git clone --depth 1 https://github.com/bkranendonk/slopsmith-plugin-simplify-chords.git simplify_chords; fi \ + && find . -name ".git" -type d -exec rm -rf {} + 2>/dev/null || true \ + && cd /app \ + && find plugins -name "requirements.txt" -exec cat {} + >> requirements.txt \ + && pip install --no-cache-dir -r requirements.txt \ + && mkdir -p /app/certs \ + && openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /app/certs/key.pem -out /app/certs/cert.pem -subj "/C=US/ST=State/L=City/O=Slopsmith/CN=slopsmith.local" \ + && sed -i 's/log_config=None,/log_config=None,\n ssl_keyfile="\/app\/certs\/key.pem",\n ssl_certfile="\/app\/certs\/cert.pem",/g' /app/main.py \ + && sed -i 's/ART_CACHE_DIR = CONFIG_DIR \/ "art_cache"/ART_CACHE_DIR = CONFIG_DIR \/ "data" \/ "art_cache"/g' /app/server.py \ + && sed -i 's/AUDIO_CACHE_DIR = CONFIG_DIR \/ "audio_cache"/AUDIO_CACHE_DIR = CONFIG_DIR \/ "data" \/ "audio_cache"/g' /app/server.py \ + && sed -i 's/SLOPPAK_CACHE_DIR = CONFIG_DIR \/ "sloppak_cache"/SLOPPAK_CACHE_DIR = CONFIG_DIR \/ "data" \/ "sloppak_cache"/g' /app/server.py \ + && sed -i 's/self.db_path = str(CONFIG_DIR \/ "web_library.db")/self.db_path = str(CONFIG_DIR \/ "data" \/ "web_library.db")/g' /app/server.py \ + && sed -i 's/CONFIG_DIR.mkdir(parents=True, exist_ok=True)/(CONFIG_DIR \/ "data").mkdir(parents=True, exist_ok=True)/g' /app/server.py \ + && sed -i 's/_PIP_TARGET = Path(os.environ.get("CONFIG_DIR", "\/config")) \/ "pip_packages"/_PIP_TARGET = Path(os.environ.get("CONFIG_DIR", "\/config")) \/ "data" \/ "pip_packages"/g' /app/plugins/__init__.py \ + && sed -i 's/def _install_requirements(plugin_dir: Path, plugin_id: str):/def _install_requirements(plugin_dir: Path, plugin_id: str):\n return True/g' /app/plugins/__init__.py + + +ENV PYTHONPATH=/app/lib:/app +ENV RSCLI_PATH=/opt/rscli/RsCli +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 + +EXPOSE 8000 + +CMD ["python", "main.py"] \ No newline at end of file