Skip to content

Instantly share code, notes, and snippets.

@entropie
Last active April 14, 2025 18:20
Show Gist options
  • Save entropie/b4fe305a8537b9453d0fb71fdc99dbcd to your computer and use it in GitHub Desktop.
Save entropie/b4fe305a8537b9453d0fb71fdc99dbcd to your computer and use it in GitHub Desktop.
{ config, lib, pkgs, ... }:
# Headless Mopidy + Icecast Streaming Setup on NixOS
#
# Minimal and robust audio streaming setup using Mopidy and Icecast.
# Streams MP3 audio from Mopidy to Icecast (/mpd.mp3) using a clean GStreamer pipeline.
# No local audio output — pure network streaming.
#
# For example: use this setup to run a local home audio "radio" stream
# that you can cast to Chromecast devices or play on any networked media player.
#
# The best: its mpd compatible
let
mopidyUser = "mopidy";
mopidyGroup = "mopidy";
mpdGroup = "mpd";
icecastUser = "icecast";
icecastGroup = "icecast";
musicBaseDir = "/srv/mopidy/music";
mopidyDataDir = "/srv/mopidy";
mopidyConfPath = "${mopidyDataDir}/mopidy.conf";
icecastIp = "192.168.1.3";
icecastPort = 13337;
icecastPassword = "hackme";
mopidyOutput = ''
audioresample ! audioconvert ! audio/x-raw,rate=44100,channels=2 ! lamemp3enc quality=0 bitrate=192 cbr=true ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=2097152 ! shout2send async=true mount=/mpd.mp3 ip=${icecastIp} port=${toString icecastPort} password=${icecastPassword}
'';
in
{
fileSystems."${musicBaseDir}/audiobooks" = {
device = "/home/media/audiobooks";
options = [ "bind" ];
};
fileSystems."${musicBaseDir}/music" = {
device = "/home/media/music";
options = [ "bind" ];
};
users.users.${mopidyUser} = {
isSystemUser = true;
group = mopidyGroup;
createHome = true;
extraGroups = [ "audio" "users" mpdGroup ];
};
users.groups.${mpdGroup} = {};
services.mopidy = {
enable = true;
extraConfigFiles = [ mopidyConfPath ];
dataDir = mopidyDataDir;
extensionPackages = with pkgs; [
mopidy-mpd
# mopidy-local
# mopidy-spotify
];
configuration = "\n\n"; # Wird durch activationScript überschrieben
};
system.activationScripts.mopidyConf = {
text = ''
install -Dm775 ${pkgs.writeText "mopidy.conf" ''
[audio]
output = ${mopidyOutput}
[mpd]
enabled = true
hostname = 0.0.0.0
port = 6600
[file]
media_dirs = ${musicBaseDir}
''} ${mopidyConfPath}
chmod 0777 ${mopidyDataDir}
chown ${mopidyUser}:${mpdGroup} ${mopidyConfPath}
'';
};
systemd.tmpfiles.rules = [
"d ${mopidyDataDir} 0775 ${mopidyUser} ${mpdGroup} -"
"f ${mopidyConfPath} 0775 ${mopidyUser} ${mpdGroup} -"
];
users.users.${icecastUser} = {
isSystemUser = true;
group = icecastGroup;
};
users.groups.${icecastGroup} = {};
services.icecast = {
enable = true;
hostname = icecastIp;
admin = {
user = "admin";
password = icecastPassword;
};
user = icecastUser;
group = icecastGroup;
logDir = "/var/log/icecast";
listen = {
address = "0.0.0.0";
port = icecastPort;
};
extraConf = ''
<limits>
<clients>100</clients>
<sources>2</sources>
</limits>
<mount>
<mount-name>/mpd.mp3</mount-name>
<password>${icecastPassword}</password>
</mount>
'';
};
environment.systemPackages = with pkgs; [
mpc
ncmpcpp
lame
mopidy
icecast
];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment