diff --git a/artifactcache/handler.go b/artifactcache/handler.go
index 7885a9b..d29a7ce 100644
--- a/artifactcache/handler.go
+++ b/artifactcache/handler.go
@@ -18,7 +18,6 @@ import (
 	"github.com/go-chi/chi/v5"
 	"github.com/go-chi/chi/v5/middleware"
 	"github.com/go-chi/render"
-	"github.com/nektos/act/pkg/common"
 	log "github.com/sirupsen/logrus"
 	_ "modernc.org/sqlite"
 	"xorm.io/builder"
@@ -39,6 +38,8 @@ type Handler struct {
 
 	gc   atomic.Bool
 	gcAt time.Time
+
+	outboundIP string
 }
 
 func NewHandler() (*Handler, error) {
@@ -69,6 +70,12 @@ func NewHandler() (*Handler, error) {
 	}
 	h.storage = storage
 
+	if ip, err := getOutboundIP(); err != nil {
+		return nil, err
+	} else {
+		h.outboundIP = ip.String()
+	}
+
 	router := chi.NewRouter()
 	router.Use(middleware.RequestLogger(&middleware.DefaultLogFormatter{Logger: logger}))
 	router.Use(func(handler http.Handler) http.Handler {
@@ -113,7 +120,7 @@ func NewHandler() (*Handler, error) {
 func (h *Handler) ExternalURL() string {
 	// TODO: make the external url configurable if necessary
 	return fmt.Sprintf("http://%s:%d",
-		common.GetOutboundIP().String(),
+		h.outboundIP,
 		h.listener.Addr().(*net.TCPAddr).Port)
 }
 
diff --git a/artifactcache/util.go b/artifactcache/util.go
index 0f22c05..eca173a 100644
--- a/artifactcache/util.go
+++ b/artifactcache/util.go
@@ -5,6 +5,7 @@ package artifactcache
 
 import (
 	"fmt"
+	"net"
 	"net/http"
 	"strconv"
 	"strings"
@@ -44,8 +45,35 @@ func parseContentRange(s string) (int64, int64, error) {
 	return start, stop, nil
 }
 
+func getOutboundIP() (net.IP, error) {
+	// FIXME: It makes more sense to use the gateway IP address of container network
+	if conn, err := net.Dial("udp", "8.8.8.8:80"); err == nil {
+		defer conn.Close()
+		return conn.LocalAddr().(*net.UDPAddr).IP, nil
+	}
+	if ifaces, err := net.Interfaces(); err == nil {
+		for _, i := range ifaces {
+			if addrs, err := i.Addrs(); err == nil {
+				for _, addr := range addrs {
+					var ip net.IP
+					switch v := addr.(type) {
+					case *net.IPNet:
+						ip = v.IP
+					case *net.IPAddr:
+						ip = v.IP
+					}
+					if ip.IsGlobalUnicast() {
+						return ip, nil
+					}
+				}
+			}
+		}
+	}
+	return nil, fmt.Errorf("no outbound IP address found")
+}
+
 // engine is a wrapper of *xorm.Engine, with a lock.
-// To avoid racing of sqlite, we don't careperformance here.
+// To avoid racing of sqlite, we don't care performance here.
 type engine struct {
 	e *xorm.Engine
 	m sync.Mutex
diff --git a/cmd/daemon.go b/cmd/daemon.go
index e874b79..f24cd6c 100644
--- a/cmd/daemon.go
+++ b/cmd/daemon.go
@@ -52,12 +52,6 @@ func runDaemon(ctx context.Context, envFile string) func(cmd *cobra.Command, arg
 			}
 		}
 
-		handler, err := artifactcache.NewHandler()
-		if err != nil {
-			return err
-		}
-		log.Infof("cache handler listens on: %v", handler.ExternalURL())
-
 		var g errgroup.Group
 
 		cli := client.New(
@@ -75,7 +69,13 @@ func runDaemon(ctx context.Context, envFile string) func(cmd *cobra.Command, arg
 			Environ:       cfg.Runner.Environ,
 			Labels:        cfg.Runner.Labels,
 			Version:       version,
-			CacheHandler:  handler,
+		}
+
+		if handler, err := artifactcache.NewHandler(); err != nil {
+			log.Errorf("cannot init cache server, it will be disabled: %v", err)
+		} else {
+			log.Infof("cache handler listens on: %v", handler.ExternalURL())
+			runner.CacheHandler = handler
 		}
 
 		poller := poller.New(
diff --git a/runtime/runtime.go b/runtime/runtime.go
index 49cc3cf..37cc15b 100644
--- a/runtime/runtime.go
+++ b/runtime/runtime.go
@@ -31,7 +31,9 @@ func (s *Runner) Run(ctx context.Context, task *runnerv1.Task) error {
 	for k, v := range s.Environ {
 		env[k] = v
 	}
-	env["ACTIONS_CACHE_URL"] = s.CacheHandler.ExternalURL() + "/"
+	if s.CacheHandler != nil {
+		env["ACTIONS_CACHE_URL"] = s.CacheHandler.ExternalURL() + "/"
+	}
 	return NewTask(s.ForgeInstance, task.Id, s.Client, env, s.platformPicker).Run(ctx, task, s.Machine, s.Version)
 }