Added systemd integration, updated README

This commit is contained in:
emeric
2019-08-10 14:03:17 +02:00
parent 8ea1ed165e
commit 8b1eed504a
7 changed files with 104 additions and 38 deletions
+3
View File
@@ -10,6 +10,9 @@ lms_cssdir=$(lms_docrootdir)/css
lms_jsdir=$(lms_docrootdir)/js lms_jsdir=$(lms_docrootdir)/js
lms_imagesdir=$(lms_approotdir)/images lms_imagesdir=$(lms_approotdir)/images
systemdunit_DATA = \
systemd/lms.service
dist_lms_css_DATA = \ dist_lms_css_DATA = \
docroot/css/lms.css docroot/css/lms.css
+73 -35
View File
@@ -1,6 +1,6 @@
# LMS - Lightweight Music Server # LMS - Lightweight Music Server
LMS is a self-hosted music streaming software: access your music collection from anywhere using a web interface! _LMS_ is a self-hosted music streaming software: access your music collection from anywhere using a web interface!
A [demo](http://lms.demo.poupon.io) instance is available, with the following limitations: A [demo](http://lms.demo.poupon.io) instance is available, with the following limitations:
- Settings cannot be saved - Settings cannot be saved
@@ -8,47 +8,58 @@ A [demo](http://lms.demo.poupon.io) instance is available, with the following li
- No administration panel - No administration panel
## Main features ## Main features
- Low memory requirement (the demo instance runs on a Raspberry Pi3B+, using less than 10% of total memory even when transcoding)
- User management * Low memory requirement (the demo instance runs on a Raspberry Pi3B+, using less than 10% of total memory even when transcoding)
- Recommendation engine * User management
- Audio transcode for maximum interoperability and low bandwith requirements * Recommendation engine
- Persistent play queue across sessions * Audio transcode for maximum interoperability and low bandwith requirements
- Subsonic API * Persistent play queue across sessions
- Album artist * Subsonic API
- Multi-value tags (artists, genres, ...) * Album artist
- Custom tags (ex: "mood", "genre", "albummood", "albumgrouping", ...) * Multi-value tags (artists, genres, ...)
- MusicBrainzID support to handle duplicated artist and release names * Custom tags (ex: _mood_, _genre_, _albummood_, _albumgrouping_, ...)
- Playlists (only using Subsonic API for now) * MusicBrainzID support to handle duplicated artist and release names
- Starred Album/Artist/Tracks (only using Subsonic API for now) * Playlists (only using Subsonic API for now)
* Starred Album/Artist/Tracks (only using Subsonic API for now)
* Systemd integration
## Recommendation engine ## Recommendation engine
LMS provides several ways to help you find the music you like:
- Tag-based filters (ex: "Rock", "Metal" and "Aggressive", "Electronic" and "Relaxed", ...) _LMS_ provides several ways to help you find the music you like:
- Recommendations for similar artists and albums * Tag-based filters (ex: _Rock_, _Metal_ and _Aggressive_, _Electronic_ and _Relaxed_, ...)
- Radio mode * Recommendations for similar artists and albums
- Searches in album, artist and track names * Radio mode
- Most played/Recently added music * Searches in album, artist and track names
* Most played/Recently added music
The recommendation engine makes use of [Self-Organizing Maps](https://en.wikipedia.org/wiki/Self-organizing_map).</br> The recommendation engine makes use of [Self-Organizing Maps](https://en.wikipedia.org/wiki/Self-organizing_map).</br>
Please note this engine: Please note this engine:
- may require some significant computation time on very large collections - may require some significant computation time on large collections (ex: half a hour per 40k tracks)
- makes use of computed data available on [AcousticBrainz](https://acousticbrainz.org/). Therefore your music files must contain the [MusicBrainz Identifier](https://musicbrainz.org/doc/MusicBrainz_Identifier) for the recommendation engine to work properly (otherwise, only tag-based recommendations are provided) - makes use of computed data available on [AcousticBrainz](https://acousticbrainz.org/). Therefore your music files must contain the [MusicBrainz Identifier](https://musicbrainz.org/doc/MusicBrainz_Identifier) for the recommendation engine to work properly (otherwise, only tag-based recommendations are provided)
## Subsonic API ## Subsonic API
The API version implemented is 1.12.0 and has been tested on Android using the official application, Ultrasonic and DSub. The API version implemented is 1.12.0 and has been tested on Android using the official application, _Ultrasonic_ and _DSub_.
Since LMS uses metadata tags to organize data, a compatibility mode is used to navigate through the collection using the directory browsing commands. Since _LMS_ uses metadata tags to organize music, a compatibility mode is used to navigate through the collection using the directory browsing commands.
The Subsonic API is enabled by default. The Subsonic API is enabled by default.
## Installation ## Installation
Here are the required packages to build LMS on Debian Stretch:
This installation process and the default values of the configuration file and the systemd service file have been written for Debian Stretch.
Therefore, you may have to adapt commands and/or paths in order to fit to your distribution.
### Build dependencies
```sh ```sh
apt-get install g++ autoconf automake libboost-filesystem-dev libboost-system-dev libavcodec-dev libavutil-dev libavformat-dev libav-tools libmagick++-dev libpstreams-dev libconfig++-dev libpstreams-dev ffmpeg libtag1-dev apt-get install g++ autoconf automake libboost-filesystem-dev libboost-system-dev libavcodec-dev libavutil-dev libavformat-dev libav-tools libmagick++-dev libpstreams-dev libconfig++-dev libpstreams-dev ffmpeg libtag1-dev
``` ```
You also need wt4, that is not packaged yet on Debian. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html). You may need to build Wt4 in "Release" mode if you want to compile it natively on a Raspberry Pi3B+. You also need wt4, that is not packaged yet on Debian. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html). Due to memory limitations, you may need to build _Wt4_ in _Release_ mode if you want to compile it natively on a Raspberry Pi3B+.
### Build
Get the latest stable release and build it this way:
```sh ```sh
git clone https://github.com/epoupon/lms.git lms git clone https://github.com/epoupon/lms.git lms
cd lms cd lms
@@ -62,23 +73,45 @@ configure will report any missing library.
```sh ```sh
make make
``` ```
Note: you can use `make -jN` to speed up compilation time (N is the number of compilation workers to spawn)
### Deployment
The following commands require root privileges.
```sh ```sh
make install make install
``` ```
This command requires root privileges. In order to customize the installation directories, you have to:
* use the following options of the `configure` script:
** --prefix (default to `/usr/local`)
** --sysconfigdir (/default to `/usr/local/etc`)
** --with-systemdunitdir (default to `/lib/systemd/system`)
* edit the `/etc/lms.conf` file
* edit the `/lib/systemd/system/lms.service` file
## Configuration Create a dedicated lms system user:
LMS uses a configuration file, installed in '/etc/lms.conf'. It is recommended to edit this file and change the relevant settings (working directory, listen port, etc.) ```sh
useradd --system lms
```
Create working directories and give access to the _lms_ user:
```sh
mkdir /var/lms
touch /var/log/lms.log
touch /var/log/lms.access.log
chown lms:lms /var/lms /var/log/lms.log /var/log/lms.access.log
```
### Configuration
_LMS_ uses a configuration file, installed in '/etc/lms.conf'. It is recommended to edit this file and change relevant settings (listen address, listen port, working directory, Subsonic API activation, ...)
All other settings are set using the web interface. All other settings are set using the web interface.
It is highly recommended to run LMS as a non root user. Therefore make sure the user has write permissions on the working directory. ### Reverse proxy settings
_LMS_ is shipped with an embedded web server, but it is recommended to deploy behind a reverse proxy. You have to set the 'behind-reverse-proxy' option to 'true' in the configuration file.
## Reverse proxy settings Here is an example to make _LMS_ properly work on myserver.org using nginx.
You have to set the 'behind-reverse-proxy' option to 'true' in the configuration file.
Here is an example to make LMS properly work on myserver.org using nginx.
``` ```
server { server {
listen 80; listen 80;
@@ -106,11 +139,16 @@ server {
## Running ## Running
```sh ```sh
lms [config_file] service lms start
``` ```
Logs are output in the working directory, in the files 'lms.log' and 'lms.access.log'. Logs are output in `/var/log/lms.log` and `/var/log/lms.access.log`
To connect to LMS, just open your favorite browser and go to http://localhost:5082 To connect to _LMS_, just open your favorite browser and go to http://localhost:5082
To make _LMS_ run automatically during startup:
```sh
service lms enable
```
## Credits ## Credits
- Wt (http://www.webtoolkit.eu/) - Wt (http://www.webtoolkit.eu/)
+2
View File
@@ -3,6 +3,8 @@
# Path to the working directory # Path to the working directory
# Must have write privileges in order to create and modify this directory # Must have write privileges in order to create and modify this directory
working-dir = "/var/lms/"; working-dir = "/var/lms/";
log-file = "/var/log/lms.log";
access-log-file = "/var/log/lms.access.log";
# Listen port/addr of the web server # Listen port/addr of the web server
listen-port = 5082; listen-port = 5082;
+7
View File
@@ -16,6 +16,13 @@ fi
AC_SUBST(MAGICKXX_CFLAGS) AC_SUBST(MAGICKXX_CFLAGS)
AC_SUBST(MAGICKXX_LIBS) AC_SUBST(MAGICKXX_LIBS)
AC_ARG_WITH(systemdunitdir,
AC_HELP_STRING([--with-systemdunitdir=DIR],
[install systemd unit files in dir [[/lib/systemd/system]]]),
systemdunitdir=$withval,systemdunitdir=/lib/systemd/system)
AC_SUBST(systemdunitdir)
AC_CHECK_HEADERS([Wt/WApplication.h pstreams/pstream.h], AC_CHECK_HEADERS([Wt/WApplication.h pstreams/pstream.h],
[], [],
[AC_MSG_ERROR([Header not found or unusable !])]) [AC_MSG_ERROR([Header not found or unusable !])])
+1 -1
View File
@@ -75,7 +75,7 @@ LoginThrottler::onBadClientAttempt(const boost::asio::ip::address& address)
_attemptsInfo[address] = now.addSecs(3); _attemptsInfo[address] = now.addSecs(3);
LMS_LOG(AUTH, INFO) << "Registering bad attempt for '" << clientAddress.to_string() << "'"; LMS_LOG(AUTH, DEBUG) << "Registering bad attempt for '" << clientAddress.to_string() << "'";
} }
void void
+2 -2
View File
@@ -43,8 +43,8 @@ std::vector<std::string> generateWtConfig(std::string execPath)
std::vector<std::string> args; std::vector<std::string> args;
const boost::filesystem::path wtConfigPath {getService<Config>()->getPath("working-dir") / "wt_config.xml"}; const boost::filesystem::path wtConfigPath {getService<Config>()->getPath("working-dir") / "wt_config.xml"};
const boost::filesystem::path wtLogFilePath {getService<Config>()->getPath("working-dir") / "lms.log"}; const boost::filesystem::path wtLogFilePath {getService<Config>()->getPath("log-file")};
const boost::filesystem::path wtAccessLogFilePath {getService<Config>()->getPath("working-dir") / "lms.access.log"}; const boost::filesystem::path wtAccessLogFilePath {getService<Config>()->getPath("access-log-file")};
args.push_back(execPath); args.push_back(execPath);
args.push_back("--config=" + wtConfigPath.string()); args.push_back("--config=" + wtConfigPath.string());
+16
View File
@@ -0,0 +1,16 @@
[Unit]
Description=Lightweight Music Server
After=network.target
[Service]
Type=simple
Restart=on-failure
RestartSec=1
WorkingDirectory=/var/lms
ExecStart=/usr/bin/lms
User=lms
Group=lms
[Install]
WantedBy=multi-user.target