diff --git a/cmd/web.go b/cmd/web.go
index 22a7f9082..e45e52be3 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -60,7 +60,7 @@ func runHTTPRedirector() {
 		http.Redirect(w, r, target, http.StatusTemporaryRedirect)
 	})
 
-	var err = runHTTP(source, context2.ClearHandler(handler))
+	var err = runHTTP("tcp", source, context2.ClearHandler(handler))
 
 	if err != nil {
 		log.Fatal("Failed to start port redirection: %v", err)
@@ -77,12 +77,12 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
 	go func() {
 		log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
 		// all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here)
-		var err = runHTTP(setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)))
+		var err = runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, certManager.HTTPHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)))
 		if err != nil {
 			log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err)
 		}
 	}()
-	return runHTTPSWithTLSConfig(listenAddr, certManager.TLSConfig(), context2.ClearHandler(m))
+	return runHTTPSWithTLSConfig("tcp", listenAddr, certManager.TLSConfig(), context2.ClearHandler(m))
 }
 
 func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
@@ -171,7 +171,7 @@ func runWeb(ctx *cli.Context) error {
 	switch setting.Protocol {
 	case setting.HTTP:
 		NoHTTPRedirector()
-		err = runHTTP(listenAddr, context2.ClearHandler(m))
+		err = runHTTP("tcp", listenAddr, context2.ClearHandler(m))
 	case setting.HTTPS:
 		if setting.EnableLetsEncrypt {
 			err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m))
@@ -182,7 +182,7 @@ func runWeb(ctx *cli.Context) error {
 		} else {
 			NoHTTPRedirector()
 		}
-		err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
+		err = runHTTPS("tcp", listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
 	case setting.FCGI:
 		NoHTTPRedirector()
 		// FCGI listeners are provided as stdin - this is orthogonal to the LISTEN_FDS approach
@@ -200,25 +200,8 @@ func runWeb(ctx *cli.Context) error {
 		}()
 		err = fcgi.Serve(listener, context2.ClearHandler(m))
 	case setting.UnixSocket:
-		// This could potentially be inherited using LISTEN_FDS but currently
-		// these cannot be inherited
 		NoHTTPRedirector()
-		NoMainListener()
-		if err := os.Remove(listenAddr); err != nil && !os.IsNotExist(err) {
-			log.Fatal("Failed to remove unix socket directory %s: %v", listenAddr, err)
-		}
-		var listener *net.UnixListener
-		listener, err = net.ListenUnix("unix", &net.UnixAddr{Name: listenAddr, Net: "unix"})
-		if err != nil {
-			break // Handle error after switch
-		}
-
-		// FIXME: add proper implementation of signal capture on all protocols
-		// execute this on SIGTERM or SIGINT: listener.Close()
-		if err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission)); err != nil {
-			log.Fatal("Failed to set permission of unix socket: %v", err)
-		}
-		err = http.Serve(listener, context2.ClearHandler(m))
+		err = runHTTP("unix", listenAddr, context2.ClearHandler(m))
 	default:
 		log.Fatal("Invalid protocol: %s", setting.Protocol)
 	}
diff --git a/cmd/web_graceful.go b/cmd/web_graceful.go
index a37f669d0..3907e843a 100644
--- a/cmd/web_graceful.go
+++ b/cmd/web_graceful.go
@@ -11,16 +11,16 @@ import (
 	"code.gitea.io/gitea/modules/graceful"
 )
 
-func runHTTP(listenAddr string, m http.Handler) error {
-	return graceful.HTTPListenAndServe("tcp", listenAddr, m)
+func runHTTP(network, listenAddr string, m http.Handler) error {
+	return graceful.HTTPListenAndServe(network, listenAddr, m)
 }
 
-func runHTTPS(listenAddr, certFile, keyFile string, m http.Handler) error {
-	return graceful.HTTPListenAndServeTLS("tcp", listenAddr, certFile, keyFile, m)
+func runHTTPS(network, listenAddr, certFile, keyFile string, m http.Handler) error {
+	return graceful.HTTPListenAndServeTLS(network, listenAddr, certFile, keyFile, m)
 }
 
-func runHTTPSWithTLSConfig(listenAddr string, tlsConfig *tls.Config, m http.Handler) error {
-	return graceful.HTTPListenAndServeTLSConfig("tcp", listenAddr, tlsConfig, m)
+func runHTTPSWithTLSConfig(network, listenAddr string, tlsConfig *tls.Config, m http.Handler) error {
+	return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, tlsConfig, m)
 }
 
 // NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go
index 2b8efe035..5550c09f4 100644
--- a/modules/graceful/net_unix.go
+++ b/modules/graceful/net_unix.go
@@ -16,6 +16,7 @@ import (
 	"sync"
 
 	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/setting"
 )
 
 const (
@@ -165,15 +166,27 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
 		if isSameAddr(l.Addr(), address) {
 			providedListeners = append(providedListeners[:i], providedListeners[i+1:]...)
 			activeListeners = append(activeListeners, l)
-			return l.(*net.UnixListener), nil
+			unixListener := l.(*net.UnixListener)
+			unixListener.SetUnlinkOnClose(true)
+			return unixListener, nil
 		}
 	}
 
 	// make a fresh listener
+	if err := os.Remove(address.Name); err != nil && !os.IsNotExist(err) {
+		return nil, fmt.Errorf("Failed to remove unix socket %s: %v", address.Name, err)
+	}
+
 	l, err := net.ListenUnix(network, address)
 	if err != nil {
 		return nil, err
 	}
+
+	fileMode := os.FileMode(setting.UnixSocketPermission)
+	if err = os.Chmod(address.Name, fileMode); err != nil {
+		return nil, fmt.Errorf("Failed to set permission of unix socket to %s: %v", fileMode.String(), err)
+	}
+
 	activeListeners = append(activeListeners, l)
 	return l, nil
 }
diff --git a/modules/graceful/restart_unix.go b/modules/graceful/restart_unix.go
index 8c68965f5..3fc4f0511 100644
--- a/modules/graceful/restart_unix.go
+++ b/modules/graceful/restart_unix.go
@@ -9,6 +9,7 @@ package graceful
 
 import (
 	"fmt"
+	"net"
 	"os"
 	"os/exec"
 	"strings"
@@ -48,6 +49,10 @@ func RestartProcess() (int, error) {
 		if err != nil {
 			return 0, err
 		}
+
+		if unixListener, ok := l.(*net.UnixListener); ok {
+			unixListener.SetUnlinkOnClose(false)
+		}
 		// Remember to close these at the end.
 		defer files[i].Close()
 	}