Subsonic in a SmartOS zone


Subsonic is an opensource web-based media server, written in Java that runs on every platform. It supports a bunch of media formats such like OGG, MP3, WMA, FLAC, … with Flash and HTML5 players.

Optionally it has a Premium subscription for $1 a month for those interested in extended features (Smartphone Apps, no Ads, Chromecast and Sonos streaming, etc).

subsonic 1

For its setup the following parts are covered in this guide:

  • Zone creation and setup.
  • Subsonic standalone installation and startup.
  • Webserver which proxies connections to internal IP and port.

Zone setup

The following steps are to be run in the GZ (Global Zone).

Directory structure

Since all the media might be shared among several zones (NAS, subsonic, …) I have chosen to name the parent dataset exported, thus:

[root@3c-4a-92-79-bf-d6 ~]# zfs create -p zones/exported/media
[root@3c-4a-92-79-bf-d6 ~]# zfs list -r zones/exported
NAME                    USED  AVAIL  REFER  MOUNTPOINT
zones/exported          115K   854G  57.5K  /zones/exported
zones/exported/media    115K   854G  57.5K  /zones/exported/media

Zone creation

See below the json code for the VM itself, feel free to tweak settings as you like but take in account the points below:

brand refers to the type of virtualisation used, in this case OS Zone.

image_uuid is the UUID for the image, see images. In this case it’s base-64-lts.

quota refers to the amount of space available for the "/" filesystem.

resolvers, nics are for the network configuration. More info here.

Now the most important part to note is filesystems where the dataset we created in the point above is used. For more information about lofs mounts see here.

{
	"brand": "joyent",
	"image_uuid": "b67492c2-055c-11e5-85d8-8b039ac981ec",
	"alias": "subsonic",
	"hostname": "subsonic.mydomain.com",
	"max_physical_memory": 1024,
	"max_swap": 1024,
	"quota": 20,
	"resolvers": ["192.168.1.1", "8.8.8.8"],
	"nics": [
	{
		"nic_tag": "internal",
		"ip": "192.168.1.100",
		"netmask": "255.255.255.0",
		"gateway": "192.168.1.1"
	}
	],
	"filesystems": [
	{
		"source": "/zones/exported/media",
		"target": "/opt/media",
		"type": "lofs"
	}
	]
}

And create the Zone:

[root@3c-4a-92-79-bf-d6 /opt/custom/etc]# vmadm create -f subsonic.json
Successfully created VM 014e59d6-970f-4827-8510-fcfcbd15cba6

Subsonic installation

Getting Subsonic Standalone

Get to: http://www.subsonic.org/pages/download.jsp to see what’s the latest version and pick up the download URL from there. As of the moment of this writing, latest version is Subsonic 5.3.

[root@3c-4a-92-79-bf-d6 /opt/custom/etc]# zlogin 014e59d6-970f-4827-8510-fcfcbd15cba6
[Connected to zone '014e59d6-970f-4827-8510-fcfcbd15cba6' pts/3]
Last login: Wed Jan 27 11:54:53 on pts/3
   __        .                   .
 _|  |_      | .-. .  . .-. :--. |-
|_    _|     ;|   ||  |(.-' |  | |
  |__|   `--'  `-' `;-| `-' '  ' `-'
                   /  ; Instance (base-64-lts 14.4.2)
                   `-'  https://docs.joyent.com/images/smartos/base

[root@subsonic ~]# wget http://subsonic.org/download/subsonic-5.3-standalone.tar.gz -O /tmp/subsonic-5.3-standalone.tar.gz

[...]

2016-01-27 12:15:52 (970 KB/s) - '/tmp/subsonic-5.3-standalone.tar.gz' saved [43714286/43714286]

Installation

First create the user and group to run Subsonic:

[root@subsonic ~]# groupadd -g 1001 subsonic
[root@subsoni2 ~]# useradd -u 1001 -g subsonic -d /var/subsonic -m -s /bin/sh subsonic
144 blocks

Upgrade packages in the recently created system and install transcoding programs:

root@subsonic ~]# pkgin update && pkgin -y fug
processing remote summary (http://pkgsrc.joyent.com/packages/SmartOS/2014Q4/x86_64/All)...
[...]
pkg_install warnings: 0, errors: 0
reading local summary...
processing local summary...
updating database: 100%

[root@subsonic ~]# pkgin -y install flac ffmpeg2 lame
calculating dependencies... done.

nothing to upgrade.
25 packages to be installed (50M to download, 179M to install):

perl-5.20.1 libxcb-1.11 libXdmcp-1.1.1 libXau-1.0.8 expat-2.1.0 png-1.6.16 glib2-2.42.1 harfbuzz-0.9.36 fribidi-0.19.6 freetype2-2.5.4 fontconfig-2.11.1nb1 enca-1.15 libX11-1.6.2nb1 libogg-1.3.2 xvidcore-1.3.3 x264-devel-20141023 opencore-amr-0.1.3 libvpx-1.3.0nb3 libvorbis-1.3.4 libvdpau-0.5 libtheora-1.1.1nb2 libass-0.11.2 lame-3.99.5nb1 flac-1.3.1 ffmpeg2-2.5.4
[...]
pkg_install warnings: 0, errors: 0
reading local summary...
processing local summary...
marking flac-1.3.1 as non auto-removable
marking ffmpeg2-2.5.4 as non auto-removable
marking lame-3.99.5nb1 as non auto-removable

It is very important that you symlink your transcoding programs into the transcode Subsonic directory since the standalone version doesn’t come with them.

subsonic@subsonic:~$ mkdir /var/subsonic/transcode
subsonic@subsonic:~$ ln -s /opt/local/bin/ffmpeg /var/subsonic/transcode/ffmpeg
subsonic@subsonic:~$ ln -s /opt/local/bin/lame /var/subsonic/transcode/lame
subsonic@subsonic:~$ ln -s /opt/local/bin/flac /var/subsonic/transcode/flac
subsonic@subsonic:~$ ls -l /var/subsonic/transcode/
total 2
lrwxrwxrwx 1 subsonic subsonic 21 Jan 28 00:09 ffmpeg -> /opt/local/bin/ffmpeg
lrwxrwxrwx 1 subsonic subsonic 19 Jan 28 00:09 flac -> /opt/local/bin/flac
lrwxrwxrwx 1 subsonic subsonic 19 Jan 28 00:09 lame -> /opt/local/bin/lame

Get JRE for Solaris x64 from Oracle site and extract it into /opt:

**NOTE: You might want to use openjdk but I’ve had problems with it so decided to go on with JRE from Oracle. Downside is that you need to keep updating it manually **

[root@subsonic /tmp]# wget --no-check-certificate --no-cookies \
     --header "Cookie: oraclelicense=accept-securebackup-cookie"     \
     http://download.oracle.com/otn-pub/java/jdk/8u71-b15/jre-8u71-solaris-x64.tar.gz \
     -O /tmp/jre-8u71-solaris-x64.tar.gz

2016-01-27 12:45:34 (1.00 MB/s) - '/tmp/jre-8u71-solaris-x64.tar.gz' saved [52076954/52076954]

[root@subsonic ~]# mkdir -p /opt/java && tar xzf /tmp/jre-8u71-solaris-x64.tar.gz -C /opt/java
[root@subsonic ~]# /opt/java/jre1.8.0_71/bin/java -version
java version "1.8.0_71"
Java(TM) SE Runtime Environment (build 1.8.0_71-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.71-b15, mixed mode)

And now extract Subsonic:

[root@subsonic ~]# su - subsonic
   __        .                   .
 _|  |_      | .-. .  . .-. :--. |-
|_    _|     ;|   ||  |(.-' |  | |
  |__|   `--'  `-' `;-| `-' '  ' `-'
                   /  ; Instance (base-64-lts 14.4.2)
                   `-'  https://docs.joyent.com/images/smartos/base
					    
subsonic@subsonic:~$ cd /var/subsonic
subsonic@subsonic:/opt/subsonic$ tar -xzf /tmp/subsonic\-5.3\-standalone.tar.gz
subsonic@subsonic:/opt/subsonic$ rm Getting\ Started.html LICENSE.TXT README.TXT subsonic.bat subsonic.sh

Startup via SMF

Fetch the manifest file and the startup script as well as the config file.

subsonic@subsonic:~$ wget https://raw.githubusercontent.com/tuxillo/tools/master/unix/smartos/subsonic.xml
[...]
subsonic@subsonic:~$ wget https://raw.githubusercontent.com/tuxillo/tools/master/unix/smartos/subsonic
[...]
subsonic@subsonic:~$ wget https://raw.githubusercontent.com/tuxillo/tools/master/unix/smartos/subsonic.conf

Edit /var/subsonic/subsonic.conf so it meets your needs. At least a minimun change would be necessary, in our case. Make sure JAVA_HOME points to the correct path without the bin path component.

JAVA_HOME=/opt/java/jre1.8.0_71
[...]
SUBSONIC_DEFAULT_MUSIC_FOLDER=/opt/media/music

As root, register the service. It should autostart:

[root@subsonic ~]# svccfg validate /var/subsonic/subsonic.xml
[root@subsonic ~]# svccfg import /var/subsonic/subsonic.xml
[root@subsonic ~]# svcs subsonic
STATE          STIME    FMRI
online          0:04:05 svc:/application/subsonic:default

Apache configuration

There are enough Apache configuration documents on teh Internet so I’m going to skip any details and post my config as it is. In my particular case I am using Subsonic under my domain and not in a subdomain so the first thing to do is to change the prefix parameter in the configuration file:

SUBSONIC_CONTEXT_PATH=/subsonic

Then I simply using Apache’s mod_proxy to do the rest:

 #
 # Subsonic specific setup
 #
 ProxyRequests off
 ProxyPreserveHost Off
 ProxyPass /subsonic http://192.168.1.100:4040/subsonic ttl=300 retry=300
 ProxyPassReverse /subsonic http://192.168.1.100:4040/subsonic

Let me know if you have questions/suggestions :-)