diff --git a/node/icecast.go b/node/icecast.go
index 8fe19d8a929c0dd3ffaa26f2cf515e058f9e7d61..af875705a4b2f450a3f758a19962843dac663a2e 100644
--- a/node/icecast.go
+++ b/node/icecast.go
@@ -3,6 +3,7 @@ package node
 import (
 	"encoding/xml"
 	"errors"
+	"flag"
 	"fmt"
 	"io"
 	"log"
@@ -18,21 +19,63 @@ import (
 	"git.autistici.org/ale/autoradio/util"
 )
 
+// Managing the local Icecast instance is a less simple task than it
+// might look, as the details tend to be distribution-specific. We'd
+// like to avoid implementing yet another service manager within
+// radiod, so we are just going to assume that the Icecast daemon is
+// managed using the local distribution-specific tools, and is running
+// independently of radiod. Furthermore, we're going to make the
+// following assumptions:
+//
+// - We have permissions to modify the Icecast config file;
+//
+// - We have installed our status XSLT page;
+//
+// - We can reload the Icecast service (send the icecast2 process a
+// SIGHUP). Ideally we'd like to use the distribution-specific method,
+// but with systemd we need to use "sudo". The code tries to
+// autodetect a supported mechanism.
+//
+// The above is usually accomplished by running radiod as the same
+// user that is running the Icecast daemon.
+//
 var (
-	statusPage        = "/status-autoradio.xsl"
-	icecastConfigFile = "/etc/icecast2/icecast.xml"
-	icecastReloadCmd  = "/usr/sbin/service icecast2 reload || /usr/sbin/service icecast2 start"
+	icecastConfigFile      = flag.String("icecast-config", "/etc/icecast2/icecast.xml", "Icecast configuration file")
+	icecastCustomReloadCmd = flag.String("icecast-reload-command", "", "Command to reload / restart the icecast2 daemon")
 
-	icecastOk = instrumentation.NewGauge("icecast.ok")
+	icecastStatusPage = "/status-autoradio.xsl"
+	icecastOk         = instrumentation.NewGauge("icecast.ok")
 )
 
+const (
+	systemCtlReloadCmd = "sudo systemctl reload icecast2.service || sudo systemctl restart icecast2.service"
+	debianReloadCmd    = "/usr/sbin/service icecast2 reload || /usr/sbin/service icecast2 restart"
+	genericReloadCmd   = "pkill -HUP icecast2"
+)
+
+func getIcecastReloadCmd() string {
+	if *icecastCustomReloadCmd != "" {
+		return *icecastCustomReloadCmd
+	}
+	if _, err := os.Stat("/bin/systemctl"); err == nil {
+		log.Printf("using /bin/systemctl to reload icecast2")
+		return systemCtlReloadCmd
+	}
+	if _, err := os.Stat("/usr/sbin/service"); err == nil {
+		log.Printf("using /usr/sbin/service to reload icecast2")
+		return debianReloadCmd
+	}
+	log.Printf("using pkill to reload icecast2")
+	return genericReloadCmd
+}
+
 // Icecast returns empty fields in our status handler, which we'll
 // need to turn into integers (the xml unmarshaler will return an
 // error in this specific case), so we use a separate type for
 // decoding the status page output. This would be much simpler if I
 // knew how to get the XSLT to put a default value in the output
 // instead of an empty field...
-type icecastMountStatusUnparsed struct {
+type icecastMountStatusRaw struct {
 	Name         string `xml:"name,attr"`
 	Listeners    string `xml:"listeners"`
 	BitRate      string `xml:"bitrate"`
@@ -42,9 +85,9 @@ type icecastMountStatusUnparsed struct {
 	FrameRate    string `xml:"frame-rate"`
 }
 
-type icecastStatusUnparsed struct {
-	XMLName xml.Name                     `xml:"status"`
-	Mounts  []icecastMountStatusUnparsed `xml:"mount"`
+type icecastStatusRaw struct {
+	XMLName xml.Name                `xml:"status"`
+	Mounts  []icecastMountStatusRaw `xml:"mount"`
 }
 
 type icecastStatus struct {
@@ -53,15 +96,17 @@ type icecastStatus struct {
 }
 
 type icecastController struct {
-	config *icecastConfig
-	status *icecastStatus
-	stop   chan bool
+	config    *icecastConfig
+	status    *icecastStatus
+	reloadCmd string
+	stop      chan bool
 }
 
 func newIcecastController(publicIP string, maxClients int) *icecastController {
 	return &icecastController{
-		config: newIcecastConfig(publicIP, maxClients),
-		status: &icecastStatus{},
+		config:    newIcecastConfig(publicIP, maxClients),
+		status:    &icecastStatus{},
+		reloadCmd: getIcecastReloadCmd(),
 	}
 }
 
@@ -69,7 +114,8 @@ func newIcecastController(publicIP string, maxClients int) *icecastController {
 // for debugging purposes.
 func (ic *icecastController) reload() error {
 	log.Printf("reloading icecast")
-	cmd := exec.Command("/bin/sh", "-c", icecastReloadCmd)
+	cmd := exec.Command("/bin/sh", "-c", ic.reloadCmd)
+	cmd.Dir = "/"
 	cmd.Stdout = os.Stderr
 	cmd.Stderr = os.Stderr
 	return cmd.Run()
@@ -113,7 +159,7 @@ func (ic *icecastController) Update(conf *clusterConfig, isMaster bool, masterAd
 		return err
 	}
 
-	changed, err := util.WriteFileIfChanged(icecastConfigFile, data)
+	changed, err := util.WriteFileIfChanged(*icecastConfigFile, data)
 	if err != nil {
 		return err
 	}
@@ -163,7 +209,7 @@ func (ic *icecastController) Run(stop chan bool) {
 }
 
 func (ic *icecastController) fetchStatus() (*icecastStatus, error) {
-	resp, err := http.Get(fmt.Sprintf("http://localhost:%d%s", autoradio.IcecastPort, statusPage))
+	resp, err := http.Get(fmt.Sprintf("http://localhost:%d%s", autoradio.IcecastPort, icecastStatusPage))
 	if err != nil {
 		return nil, err
 	}
@@ -172,7 +218,7 @@ func (ic *icecastController) fetchStatus() (*icecastStatus, error) {
 }
 
 func (ic *icecastController) parseStatusPage(input io.Reader) (*icecastStatus, error) {
-	var ustatus icecastStatusUnparsed
+	var ustatus icecastStatusRaw
 	if err := xml.NewDecoder(input).Decode(&ustatus); err != nil {
 		return nil, err
 	}