├── .gitignore ├── .gitattributes ├── examples ├── subsonic.logrotate ├── stop-subsonic.sh └── start-subsonic.sh ├── README.md ├── Dockerfile └── startup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .#* 2 | *~ 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.sh eof=lf -------------------------------------------------------------------------------- /examples/subsonic.logrotate: -------------------------------------------------------------------------------- 1 | /var/local/subsonic/*.log { 2 | weekly 3 | missingok 4 | rotate 7 5 | compress 6 | notifempty 7 | copytruncate 8 | create 600 9 | } 10 | 11 | -------------------------------------------------------------------------------- /examples/stop-subsonic.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | image="mschuerig/debian-subsonic" 4 | music="/data/music" 5 | data="/var/local/subsonic" 6 | http_subsonicport=4040 7 | http_hostport=4040 8 | https_subsonicport=4443 9 | https_hostport=4443 10 | 11 | container_exposing_port() { 12 | docker ps --no-trunc \ 13 | | awk "/->${1}\\/tcp/ { print \$1; exit }" 14 | } 15 | 16 | running=$( container_exposing_port "$http_subsonicport" ) 17 | if [ -n "$running" ]; then 18 | echo "Stopping Subsonic container..." >&2 19 | docker stop "$running" 20 | else 21 | echo "Subsonic container is not running" >&2 22 | fi 23 | 24 | exit 0 25 | 26 | -------------------------------------------------------------------------------- /examples/start-subsonic.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | image="mschuerig/debian-subsonic" 4 | music="/data/music" 5 | data="/var/local/subsonic" 6 | http_subsonicport=4040 7 | http_hostport=4040 8 | https_subsonicport=4443 9 | https_hostport=4443 10 | 11 | container_exposing_port() { 12 | docker ps --no-trunc \ 13 | | awk "/->${1}\\/tcp/ { print \$1; exit }" 14 | } 15 | 16 | container_for_image() { 17 | docker ps -a --no-trunc \ 18 | | awk "\$2 == \"${1}\" || \$2 == \"${1}:latest\" { print \$1; exit }" 19 | } 20 | 21 | 22 | running=$( container_exposing_port "$http_subsonicport" ) 23 | if [ -n "$running" ]; then 24 | echo "Subsonic container is already running" >&2 25 | else 26 | container=$( container_for_image "$image" ) 27 | if [ -n "$container" ]; then 28 | echo "Re-starting Subsonic container" >&2 29 | docker start "$container" 30 | else 31 | echo "Freshly starting Subsonic container" >&2 32 | docker run \ 33 | --name subsonic \ 34 | --detach \ 35 | --publish ${http_hostport}:${http_subsonicport} \ 36 | --publish ${https_hostport}:${https_subsonicport} \ 37 | --volume "${music}:/var/music:ro" \ 38 | --volume "${data}:/var/subsonic" \ 39 | --restart=always \ 40 | "${image}" \ 41 | --https-port=$https_subsonicport 42 | fi 43 | fi 44 | 45 | exit 0 46 | 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | **This project is dormant and dreams of the fjords. 3 | See [anarcat/debian-airsonic](https://github.com/anarcat/debian-airsonic) 4 | for a substitute.** 5 | 6 | 7 | This repository contains configuration files for building a 8 | Docker (http://docker.io) image for the Subsonic media streamer. 9 | 10 | ## Noteworthy 11 | 12 | * Subsonic 6 (http://www.subsonic.org) 13 | * Debian (https://debian.org/ - latest stable) 14 | * Runs as user subsonic (UID 10000) 15 | 16 | ## Build your own image 17 | 18 | ```shell 19 | $ docker build -t /debian-subsonic debian-subsonic 20 | ``` 21 | 22 | ## Get a pre-built image 23 | 24 | A current image is available as a trusted build from the Docker index: 25 | 26 | ```shell 27 | $ docker pull mschuerig/debian-subsonic 28 | ``` 29 | 30 | The repository page is at 31 | https://hub.docker.com/r/mschuerig/subsonic-docker-image/ 32 | 33 | 34 | ## Run a container with this image 35 | 36 | ```shell 37 | $ docker run \ 38 | --detach \ 39 | --publish 4040:4040 \ 40 | --volume "/wherever/your/music/is:/var/music:ro" \ 41 | /debian-subsonic 42 | 43 | ``` 44 | 45 | ## Pitfalls 46 | 47 | The host music directory mounted into the container at /var/music must be 48 | readable by user subsonic (UID 10000). 49 | 50 | If you use a volume for the container's /var/subsonic, the host directory 51 | mounted there must have read-write-execute permissions for user 52 | subsonic (UID 10000). 53 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stretch 2 | 3 | MAINTAINER michael@schuerig.de 4 | 5 | ENV DEBIAN_FRONTEND noninteractive 6 | 7 | # Create a new user account with UID/GID at least 10000. 8 | # This makes it easier to keep host and docker accounts apart. 9 | RUN useradd --home /var/subsonic -M subsonic -K UID_MIN=10000 -K GID_MIN=10000 && \ 10 | mkdir -p /var/subsonic && chown subsonic /var/subsonic && chmod 0770 /var/subsonic 11 | 12 | RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ 13 | apt-get update && \ 14 | apt-get dist-upgrade --yes --no-install-recommends --no-install-suggests && \ 15 | apt-get install --yes --no-install-recommends --no-install-suggests openjdk-8-jre-headless locales && \ 16 | apt-get clean 17 | 18 | ENV SUBSONIC_VERSION 6.1.1 19 | 20 | ADD https://s3-eu-west-1.amazonaws.com/subsonic-public/download/subsonic-$SUBSONIC_VERSION.deb /tmp/subsonic-$SUBSONIC_VERSION.deb 21 | RUN dpkg -i /tmp/subsonic-$SUBSONIC_VERSION.deb && rm -f /tmp/*.deb 22 | 23 | # Create hardlinks to the transcoding binaries. 24 | # This way we can mount a volume over /var/subsonic. 25 | # Apparently, Subsonic does not accept paths in the Transcoding settings. 26 | # If you mount a volume over /var/subsonic, create symlinks 27 | # /var/subsonic/transcode/ffmpeg -> /usr/local/bin/ffmpeg 28 | # /var/subsonic/transcode/lame -> /usr/local/bin/lame 29 | RUN ln /var/subsonic/transcode/ffmpeg /var/subsonic/transcode/lame /usr/local/bin 30 | 31 | VOLUME /var/subsonic 32 | 33 | COPY startup.sh /startup.sh 34 | 35 | EXPOSE 4040 36 | 37 | USER subsonic 38 | 39 | CMD [] 40 | ENTRYPOINT ["/startup.sh"] 41 | -------------------------------------------------------------------------------- /startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | ################################################################################### 4 | # Shell script for starting Subsonic. See http://subsonic.org. 5 | # 6 | # Author: Sindre Mehus 7 | # 8 | # Adapted for docker use by Michael Schuerig 9 | # 10 | ################################################################################### 11 | 12 | SUBSONIC_HOME=/var/subsonic 13 | SUBSONIC_HOST=0.0.0.0 14 | SUBSONIC_PORT=4040 15 | SUBSONIC_HTTPS_PORT=0 16 | SUBSONIC_CONTEXT_PATH=/ 17 | SUBSONIC_MAX_MEMORY=200 18 | SUBSONIC_PIDFILE= 19 | SUBSONIC_DEFAULT_MUSIC_FOLDER=/var/music 20 | SUBSONIC_DEFAULT_PODCAST_FOLDER=${SUBSONIC_HOME}/podcasts 21 | SUBSONIC_DEFAULT_PLAYLIST_FOLDER=${SUBSONIC_HOME}/playlists 22 | 23 | SUBSONIC_USER=subsonic 24 | 25 | export LANG=POSIX 26 | export LC_ALL=en_US.UTF-8 27 | 28 | quiet=0 29 | 30 | usage() { 31 | echo "Usage: subsonic.sh [options]" 32 | echo " --help This small usage guide." 33 | echo " --home=DIR The directory where Subsonic will create files." 34 | echo " Make sure it is writable. Default: /var/subsonic" 35 | echo " --host=HOST The host name or IP address on which to bind Subsonic." 36 | echo " Only relevant if you have multiple network interfaces and want" 37 | echo " to make Subsonic available on only one of them. The default value" 38 | echo " will bind Subsonic to all available network interfaces. Default: 0.0.0.0" 39 | echo " --port=PORT The port on which Subsonic will listen for" 40 | echo " incoming HTTP traffic. Default: 4040" 41 | echo " --https-port=PORT The port on which Subsonic will listen for" 42 | echo " incoming HTTPS traffic. Default: 0 (disabled)" 43 | echo " --context-path=PATH The context path, i.e., the last part of the Subsonic" 44 | echo " URL. Typically '/' or '/subsonic'. Default '/'" 45 | echo " --max-memory=MB The memory limit (max Java heap size) in megabytes." 46 | echo " Default: 100" 47 | echo " --pidfile=PIDFILE Write PID to this file. Default not created." 48 | echo " --quiet Don't print anything to standard out. Default false." 49 | echo " --default-music-folder=DIR Configure Subsonic to use this folder for music. This option " 50 | echo " only has effect the first time Subsonic is started. Default '/var/music'" 51 | echo " --default-podcast-folder=DIR Configure Subsonic to use this folder for Podcasts. This option " 52 | echo " only has effect the first time Subsonic is started. Default '/var/music/Podcast'" 53 | echo " --default-playlist-folder=DIR Configure Subsonic to use this folder for playlists. This option " 54 | echo " only has effect the first time Subsonic is started. Default '/var/playlists'" 55 | exit 1 56 | } 57 | 58 | 59 | # Parse arguments. 60 | while [ $# -ge 1 ]; do 61 | case $1 in 62 | debug) 63 | exec /bin/bash 64 | ;; 65 | --help) 66 | usage 67 | ;; 68 | --home=?*) 69 | SUBSONIC_HOME=${1#--home=} 70 | ;; 71 | --host=?*) 72 | SUBSONIC_HOST=${1#--host=} 73 | ;; 74 | --port=?*) 75 | SUBSONIC_PORT=${1#--port=} 76 | ;; 77 | --https-port=?*) 78 | SUBSONIC_HTTPS_PORT=${1#--https-port=} 79 | ;; 80 | --context-path=?*) 81 | SUBSONIC_CONTEXT_PATH=${1#--context-path=} 82 | ;; 83 | --max-memory=?*) 84 | SUBSONIC_MAX_MEMORY=${1#--max-memory=} 85 | ;; 86 | --pidfile=?*) 87 | SUBSONIC_PIDFILE=${1#--pidfile=} 88 | ;; 89 | --quiet) 90 | quiet=1 91 | ;; 92 | --default-music-folder=?*) 93 | SUBSONIC_DEFAULT_MUSIC_FOLDER=${1#--default-music-folder=} 94 | ;; 95 | --default-podcast-folder=?*) 96 | SUBSONIC_DEFAULT_PODCAST_FOLDER=${1#--default-podcast-folder=} 97 | ;; 98 | --default-playlist-folder=?*) 99 | SUBSONIC_DEFAULT_PLAYLIST_FOLDER=${1#--default-playlist-folder=} 100 | ;; 101 | *) 102 | usage 103 | ;; 104 | esac 105 | shift 106 | done 107 | 108 | # Create Subsonic home directory. 109 | mkdir -p \ 110 | ${SUBSONIC_HOME} \ 111 | ${SUBSONIC_DEFAULT_PODCAST_FOLDER} \ 112 | ${SUBSONIC_DEFAULT_PLAYLIST_FOLDER} \ 113 | /tmp/subsonic 114 | 115 | LOG=${SUBSONIC_HOME}/subsonic_sh.log 116 | truncate -s0 ${LOG} 117 | 118 | for tc in ffmpeg lame flac; do 119 | type -P $tc && ln -srf "$(type -P $tc)" ${SUBSONIC_HOME}/transcode/ 120 | done 121 | 122 | cd /usr/share/subsonic 123 | 124 | exec /usr/bin/java -Xmx${SUBSONIC_MAX_MEMORY}m \ 125 | -Dsubsonic.home=${SUBSONIC_HOME} \ 126 | -Dsubsonic.host=${SUBSONIC_HOST} \ 127 | -Dsubsonic.port=${SUBSONIC_PORT} \ 128 | -Dsubsonic.httpsPort=${SUBSONIC_HTTPS_PORT} \ 129 | -Dsubsonic.contextPath=${SUBSONIC_CONTEXT_PATH} \ 130 | -Dsubsonic.defaultMusicFolder=${SUBSONIC_DEFAULT_MUSIC_FOLDER} \ 131 | -Dsubsonic.defaultPodcastFolder=${SUBSONIC_DEFAULT_PODCAST_FOLDER} \ 132 | -Dsubsonic.defaultPlaylistFolder=${SUBSONIC_DEFAULT_PLAYLIST_FOLDER} \ 133 | -Djava.awt.headless=true \ 134 | -verbose:gc \ 135 | -jar subsonic-booter-jar-with-dependencies.jar >> ${LOG} 2>&1 136 | --------------------------------------------------------------------------------