Repository: supabase/cli
Pull request #2364 (2024-06-04 02:15:29)

Prod deploy
- **fix: declare password flag for viper bind (#2360)**
- **fix: escape health check cmd for podman (#2359)**



Patch:
diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml
index 32a2089d..bc2601c0 100644
--- a/.github/workflows/release-beta.yml
+++ b/.github/workflows/release-beta.yml
@@ -41,10 +41,10 @@ jobs:
           go-version-file: go.mod
           cache: true
 
-      - uses: goreleaser/goreleaser-action@v5
+      - uses: goreleaser/goreleaser-action@v6
         with:
           distribution: goreleaser
-          version: ~> 1
+          version: ~> v2
           args: release --clean
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 06d6c5f6..b1174fd6 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -1,3 +1,4 @@
+version: 2
 project_name: supabase
 builds:
   - id: supabase
diff --git a/cmd/bootstrap.go b/cmd/bootstrap.go
index 64fb1af2..da5d96e4 100644
--- a/cmd/bootstrap.go
+++ b/cmd/bootstrap.go
@@ -65,7 +65,7 @@ var (
 
 func init() {
 	bootstrapFlags := bootstrapCmd.Flags()
-	bootstrapFlags.StringP("password", "p", "", "Password to your remote Postgres database.")
+	bootstrapFlags.StringVarP(&dbPassword, "password", "p", "", "Password to your remote Postgres database.")
 	cobra.CheckErr(viper.BindPFlag("DB_PASSWORD", bootstrapFlags.Lookup("password")))
 	rootCmd.AddCommand(bootstrapCmd)
 }
diff --git a/cmd/functions.go b/cmd/functions.go
index 5db0d395..6555bae9 100644
--- a/cmd/functions.go
+++ b/cmd/functions.go
@@ -82,7 +82,7 @@ var (
 	}
 
 	envFilePath string
-	inspectRun  bool
+	inspectBrk  bool
 	inspectMode = utils.EnumFlag{
 		Allowed: []string{
 			string(serve.InspectModeRun),
@@ -107,8 +107,8 @@ var (
 
 			if len(inspectMode.Value) > 0 {
 				runtimeOption.InspectMode = utils.Ptr(serve.InspectMode(inspectMode.Value))
-			} else if inspectRun {
-				runtimeOption.InspectMode = utils.Ptr(serve.InspectModeRun)
+			} else if inspectBrk {
+				runtimeOption.InspectMode = utils.Ptr(serve.InspectModeBrk)
 			}
 			if runtimeOption.InspectMode == nil && runtimeOption.InspectMain {
 				return fmt.Errorf("--inspect-main must be used together with one of these flags: [inspect inspect-mode]")
@@ -130,7 +130,7 @@ func init() {
 	functionsServeCmd.Flags().BoolVar(noVerifyJWT, "no-verify-jwt", false, "Disable JWT verification for the Function.")
 	functionsServeCmd.Flags().StringVar(&envFilePath, "env-file", "", "Path to an env file to be populated to the Function environment.")
 	functionsServeCmd.Flags().StringVar(&importMapPath, "import-map", "", "Path to import map file.")
-	functionsServeCmd.Flags().BoolVar(&inspectRun, "inspect", false, "Alias of --inspect-mode run.")
+	functionsServeCmd.Flags().BoolVar(&inspectBrk, "inspect", false, "Alias of --inspect-mode brk.")
 	functionsServeCmd.Flags().Var(&inspectMode, "inspect-mode", "Activate inspector capability for debugging.")
 	functionsServeCmd.Flags().BoolVar(&runtimeOption.InspectMain, "inspect-main", false, "Allow inspecting the main worker.")
 	functionsServeCmd.MarkFlagsMutuallyExclusive("inspect", "inspect-mode")
diff --git a/cmd/link.go b/cmd/link.go
index facaa532..780b667e 100644
--- a/cmd/link.go
+++ b/cmd/link.go
@@ -45,7 +45,8 @@ var (
 func init() {
 	linkFlags := linkCmd.Flags()
 	linkFlags.StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.")
-	linkFlags.StringP("password", "p", "", "Password to your remote Postgres database.")
+	linkFlags.StringVarP(&dbPassword, "password", "p", "", "Password to your remote Postgres database.")
+	// For some reason, BindPFlag only works for StringVarP instead of StringP
 	cobra.CheckErr(viper.BindPFlag("DB_PASSWORD", linkFlags.Lookup("password")))
 	rootCmd.AddCommand(linkCmd)
 }
diff --git a/cmd/root.go b/cmd/root.go
index 138fbf45..b0f9d50a 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -241,6 +241,7 @@ func init() {
 	flags.Bool("debug", false, "output debug logs to stderr")
 	flags.String("workdir", "", "path to a Supabase project directory")
 	flags.Bool("experimental", false, "enable experimental features")
+	flags.String("network-id", "", "use the specified docker network instead of a generated one")
 	flags.Var(&utils.DNSResolver, "dns-resolver", "lookup domain names using the specified resolver")
 	flags.BoolVar(&createTicket, "create-ticket", false, "create a support ticket for any CLI error")
 	cobra.CheckErr(viper.BindPFlags(flags))
diff --git a/cmd/secrets.go b/cmd/secrets.go
index a6f123b6..df4084e4 100644
--- a/cmd/secrets.go
+++ b/cmd/secrets.go
@@ -26,20 +26,16 @@ var (
 	}
 
 	secretsSetCmd = &cobra.Command{
-		Use:   "set [flags] <NAME=VALUE> ...",
+		Use:   "set <NAME=VALUE> ...",
 		Short: "Set a secret(s) on Supabase",
 		Long:  "Set a secret(s) to the linked Supabase project.",
 		RunE: func(cmd *cobra.Command, args []string) error {
-			envFilePath, err := cmd.Flags().GetString("env-file")
-			if err != nil {
-				return err
-			}
 			return set.Run(cmd.Context(), flags.ProjectRef, envFilePath, args, afero.NewOsFs())
 		},
 	}
 
 	secretsUnsetCmd = &cobra.Command{
-		Use:   "unset <NAME> ...",
+		Use:   "unset [NAME] ...",
 		Short: "Unset a secret(s) on Supabase",
 		Long:  "Unset a secret(s) from the linked Supabase project.",
 		RunE: func(cmd *cobra.Command, args []string) error {
@@ -50,7 +46,7 @@ var (
 
 func init() {
 	secretsCmd.PersistentFlags().StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.")
-	secretsSetCmd.Flags().String("env-file", "", "Read secrets from a .env file.")
+	secretsSetCmd.Flags().StringVar(&envFilePath, "env-file", "", "Read secrets from a .env file.")
 	secretsCmd.AddCommand(secretsListCmd)
 	secretsCmd.AddCommand(secretsSetCmd)
 	secretsCmd.AddCommand(secretsUnsetCmd)
diff --git a/docs/supabase/functions/serve.md b/docs/supabase/functions/serve.md
index ac11ad6a..1ce46321 100644
--- a/docs/supabase/functions/serve.md
+++ b/docs/supabase/functions/serve.md
@@ -5,7 +5,7 @@ Serve all Functions locally.
 `supabase functions serve` command includes additional flags to assist developers in debugging using tools like `DevTools`.
 
 1. `--inspect`
-   * Alias of `--inspect-mode run`.
+   * Alias of `--inspect-mode brk`.
 
 2. `--inspect-mode [ run | brk | wait ]`
    * Activates the inspector capability.
diff --git a/go.mod b/go.mod
index 5b0ac7e4..4bf04417 100644
--- a/go.mod
+++ b/go.mod
@@ -11,10 +11,10 @@ require (
 	github.com/charmbracelet/bubbletea v0.26.4
 	github.com/charmbracelet/glamour v0.7.0
 	github.com/charmbracelet/lipgloss v0.11.0
-	github.com/containers/common v0.59.0
-	github.com/deepmap/oapi-codegen/v2 v2.1.0
+	github.com/containers/common v0.59.1
+	github.com/deepmap/oapi-codegen/v2 v2.2.0
 	github.com/docker/cli v26.1.2+incompatible
-	github.com/docker/docker v26.1.3+incompatible
+	github.com/docker/docker v26.1.4+incompatible
 	github.com/docker/go-connections v0.5.0
 	github.com/docker/go-units v0.5.0
 	github.com/getsentry/sentry-go v0.28.0
@@ -23,7 +23,7 @@ require (
 	github.com/go-git/go-git/v5 v5.12.0
 	github.com/go-xmlfmt/xmlfmt v1.1.2
 	github.com/golang-jwt/jwt/v5 v5.2.1
-	github.com/golangci/golangci-lint v1.59.0
+	github.com/golangci/golangci-lint v1.59.1
 	github.com/google/go-github/v62 v62.0.0
 	github.com/google/go-querystring v1.1.0
 	github.com/google/uuid v1.6.0
@@ -43,14 +43,14 @@ require (
 	github.com/spf13/afero v1.11.0
 	github.com/spf13/cobra v1.8.0
 	github.com/spf13/pflag v1.0.5
-	github.com/spf13/viper v1.18.2
+	github.com/spf13/viper v1.19.0
 	github.com/stretchr/testify v1.9.0
 	github.com/stripe/pg-schema-diff v0.7.0
 	github.com/withfig/autocomplete-tools/packages/cobra v1.2.0
-	github.com/zalando/go-keyring v0.2.4
-	golang.org/x/mod v0.17.0
-	golang.org/x/oauth2 v0.20.0
-	golang.org/x/term v0.20.0
+	github.com/zalando/go-keyring v0.2.5
+	golang.org/x/mod v0.18.0
+	golang.org/x/oauth2 v0.21.0
+	golang.org/x/term v0.21.0
 	google.golang.org/grpc v1.64.0
 	gopkg.in/yaml.v3 v3.0.1
 	gotest.tools/gotestsum v1.12.0
@@ -64,7 +64,7 @@ require (
 	github.com/Abirdcfly/dupword v0.0.14 // indirect
 	github.com/Antonboom/errname v0.1.13 // indirect
 	github.com/Antonboom/nilnil v0.1.9 // indirect
-	github.com/Antonboom/testifylint v1.3.0 // indirect
+	github.com/Antonboom/testifylint v1.3.1 // indirect
 	github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
 	github.com/Crocmagnon/fatcontext v0.2.2 // indirect
 	github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
@@ -136,7 +136,7 @@ require (
 	github.com/fvbommel/sortorder v1.1.0 // indirect
 	github.com/fzipp/gocyclo v0.6.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
-	github.com/getkin/kin-openapi v0.122.0 // indirect
+	github.com/getkin/kin-openapi v0.124.0 // indirect
 	github.com/ghostiam/protogetter v0.3.6 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
 	github.com/go-critic/go-critic v0.11.4 // indirect
@@ -156,7 +156,7 @@ require (
 	github.com/go-toolsmith/astp v1.1.0 // indirect
 	github.com/go-toolsmith/strparse v1.1.0 // indirect
 	github.com/go-toolsmith/typep v1.1.0 // indirect
-	github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
+	github.com/go-viper/mapstructure/v2 v2.0.0 // indirect
 	github.com/gobwas/glob v0.2.3 // indirect
 	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/godbus/dbus/v5 v5.1.0 // indirect
@@ -166,7 +166,7 @@ require (
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
 	github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect
-	github.com/golangci/misspell v0.5.1 // indirect
+	github.com/golangci/misspell v0.6.0 // indirect
 	github.com/golangci/modinfo v0.3.4 // indirect
 	github.com/golangci/plugin-module-register v0.1.1 // indirect
 	github.com/golangci/revgrep v0.5.3 // indirect
@@ -257,7 +257,7 @@ require (
 	github.com/pjbgf/sha1cd v0.3.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
-	github.com/polyfloyd/go-errorlint v1.5.1 // indirect
+	github.com/polyfloyd/go-errorlint v1.5.2 // indirect
 	github.com/prometheus/client_golang v1.12.1 // indirect
 	github.com/prometheus/client_model v0.2.0 // indirect
 	github.com/prometheus/common v0.32.1 // indirect
@@ -277,7 +277,7 @@ require (
 	github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
 	github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
 	github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
-	github.com/sashamelentyev/usestdlibvars v1.25.0 // indirect
+	github.com/sashamelentyev/usestdlibvars v1.26.0 // indirect
 	github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 // indirect
 	github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
 	github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
@@ -319,7 +319,7 @@ require (
 	github.com/yuin/goldmark-emoji v1.0.2 // indirect
 	gitlab.com/bosi/decorder v0.4.2 // indirect
 	go-simpler.org/musttag v0.12.2 // indirect
-	go-simpler.org/sloglint v0.7.0 // indirect
+	go-simpler.org/sloglint v0.7.1 // indirect
 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
 	go.opentelemetry.io/otel v1.27.0 // indirect
 	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 // indirect
@@ -336,14 +336,14 @@ require (
 	go.uber.org/multierr v1.9.0 // indirect
 	go.uber.org/zap v1.24.0 // indirect
 	golang.org/x/arch v0.8.0 // indirect
-	golang.org/x/crypto v0.23.0 // indirect
+	golang.org/x/crypto v0.24.0 // indirect
 	golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
 	golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
-	golang.org/x/net v0.25.0 // indirect
+	golang.org/x/net v0.26.0 // indirect
 	golang.org/x/sync v0.7.0 // indirect
-	golang.org/x/sys v0.20.0 // indirect
-	golang.org/x/text v0.15.0 // indirect
-	golang.org/x/tools v0.21.0 // indirect
+	golang.org/x/sys v0.21.0 // indirect
+	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/tools v0.22.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect
 	google.golang.org/protobuf v1.34.1 // indirect
@@ -352,5 +352,5 @@ require (
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	honnef.co/go/tools v0.4.7 // indirect
 	mvdan.cc/gofumpt v0.6.0 // indirect
-	mvdan.cc/unparam v0.0.0-20240427195214-063aff900ca1 // indirect
+	mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect
 )
diff --git a/go.sum b/go.sum
index 14623da3..d87dd228 100644
--- a/go.sum
+++ b/go.sum
@@ -45,8 +45,8 @@ github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHO
 github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns=
 github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ=
 github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ=
-github.com/Antonboom/testifylint v1.3.0 h1:UiqrddKs1W3YK8R0TUuWwrVKlVAnS07DTUVWWs9c+y4=
-github.com/Antonboom/testifylint v1.3.0/go.mod h1:NV0hTlteCkViPW9mSR4wEMfwp+Hs1T3dY60bkvSfhpM=
+github.com/Antonboom/testifylint v1.3.1 h1:Uam4q1Q+2b6H7gvk9RQFw6jyVDdpzIirFOOrbs14eG4=
+github.com/Antonboom/testifylint v1.3.1/go.mod h1:NV0hTlteCkViPW9mSR4wEMfwp+Hs1T3dY60bkvSfhpM=
 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -204,8 +204,8 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I
 github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
 github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
 github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
-github.com/containers/common v0.59.0 h1:fy9Jz0B7Qs1C030bm73YJtVddaiFSZD3558EV1tgN2g=
-github.com/containers/common v0.59.0/go.mod h1:53VicJCZ2AD0O+Br7VVoyrS7viXF4YmwlTIocWUT8XE=
+github.com/containers/common v0.59.1 h1:7VkmJN3YvD0jLFwaUjLHSRJ98JLffydiyOJjYr0dUTo=
+github.com/containers/common v0.59.1/go.mod h1:53VicJCZ2AD0O+Br7VVoyrS7viXF4YmwlTIocWUT8XE=
 github.com/containers/storage v1.54.0 h1:xwYAlf6n9OnIlURQLLg3FYHbO74fQ/2W2N6EtQEUM4I=
 github.com/containers/storage v1.54.0/go.mod h1:PlMOoinRrBSnhYODLxt4EXl0nmJt+X0kjG0Xdt9fMTw=
 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -227,8 +227,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/deepmap/oapi-codegen/v2 v2.1.0 h1:I/NMVhJCtuvL9x+S2QzZKpSjGi33oDZwPRdemvOZWyQ=
-github.com/deepmap/oapi-codegen/v2 v2.1.0/go.mod h1:R1wL226vc5VmCNJUvMyYr3hJMm5reyv25j952zAVXZ8=
+github.com/deepmap/oapi-codegen/v2 v2.2.0 h1:FW4f7C0Xb6EaezBSB3GYw2QGwHD5ChDflG+3xSZBdvY=
+github.com/deepmap/oapi-codegen/v2 v2.2.0/go.mod h1:L4zUv7ULYDtYSb/aYk/xO3OYcQU6BoU/0viULkbi2DE=
 github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8=
 github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=
 github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
@@ -243,8 +243,8 @@ github.com/docker/cli v26.1.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvM
 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
 github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo=
-github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU=
+github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
 github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
 github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
@@ -294,8 +294,8 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
 github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
 github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
 github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
-github.com/getkin/kin-openapi v0.122.0 h1:WB9Jbl0Hp/T79/JF9xlSW5Kl9uYdk/AWD0yAd9HOM10=
-github.com/getkin/kin-openapi v0.122.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw=
+github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M=
+github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
 github.com/getsentry/sentry-go v0.28.0 h1:7Rqx9M3ythTKy2J6uZLHmc8Sz9OGgIlseuO1iBX/s0M=
 github.com/getsentry/sentry-go v0.28.0/go.mod h1:1fQZ+7l7eeJ3wYi82q5Hg8GqAPgefRq+FP/QhafYVgg=
 github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk=
@@ -372,8 +372,8 @@ github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQi
 github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
 github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=
 github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
-github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c=
-github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc=
+github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
 github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=
 github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
 github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
@@ -428,10 +428,10 @@ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9
 github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
 github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e h1:ULcKCDV1LOZPFxGZaA6TlQbiM3J2GCPnkx/bGF6sX/g=
 github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM=
-github.com/golangci/golangci-lint v1.59.0 h1:st69YDnAH/v2QXDcgUaZ0seQajHScPALBVkyitYLXEk=
-github.com/golangci/golangci-lint v1.59.0/go.mod h1:QNA32UWdUdHXnu+Ap5/ZU4WVwyp2tL94UxEXrSErjg0=
-github.com/golangci/misspell v0.5.1 h1:/SjR1clj5uDjNLwYzCahHwIOPmQgoH04AyQIiWGbhCM=
-github.com/golangci/misspell v0.5.1/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
+github.com/golangci/golangci-lint v1.59.1 h1:CRRLu1JbhK5avLABFJ/OHVSQ0Ie5c4ulsOId1h3TTks=
+github.com/golangci/golangci-lint v1.59.1/go.mod h1:jX5Oif4C7P0j9++YB2MMJmoNrb01NJ8ITqKWNLewThg=
+github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
+github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
 github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA=
 github.com/golangci/modinfo v0.3.4/go.mod h1:wytF1M5xl9u0ij8YSvhkEVPP3M5Mc7XLl1pxH3B2aUM=
 github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c=
@@ -806,8 +806,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/polyfloyd/go-errorlint v1.5.1 h1:5gHxDjLyyWij7fhfrjYNNlHsUNQeyx0LFQKUelO3RBo=
-github.com/polyfloyd/go-errorlint v1.5.1/go.mod h1:sH1QC1pxxi0fFecsVIzBmxtrgd9IF/SkJpA6wqyKAJs=
+github.com/polyfloyd/go-errorlint v1.5.2 h1:SJhVik3Umsjh7mte1vE0fVZ5T1gznasQG3PV7U5xFdA=
+github.com/polyfloyd/go-errorlint v1.5.2/go.mod h1:sH1QC1pxxi0fFecsVIzBmxtrgd9IF/SkJpA6wqyKAJs=
 github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
 github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -878,8 +878,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng
 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
 github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw=
 github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
-github.com/sashamelentyev/usestdlibvars v1.25.0 h1:IK8SI2QyFzy/2OD2PYnhy84dpfNo9qADrRt6LH8vSzU=
-github.com/sashamelentyev/usestdlibvars v1.25.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8=
+github.com/sashamelentyev/usestdlibvars v1.26.0 h1:LONR2hNVKxRmzIrZR0PhSF3mhCAzvnr+DcUiHgREfXE=
+github.com/sashamelentyev/usestdlibvars v1.26.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 h1:rnO6Zp1YMQwv8AyxzuwsVohljJgp4L0ZqiCgtACsPsc=
 github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9/go.mod h1:dg7lPlu/xK/Ut9SedURCoZbVCR4yC7fM65DtH9/CDHs=
@@ -927,8 +927,8 @@ github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
-github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
-github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
+github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
+github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
 github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
 github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=
 github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
@@ -1018,8 +1018,8 @@ github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
 github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s=
 github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY=
-github.com/zalando/go-keyring v0.2.4 h1:wi2xxTqdiwMKbM6TWwi+uJCG/Tum2UV0jqaQhCa9/68=
-github.com/zalando/go-keyring v0.2.4/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk=
+github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8=
+github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk=
 github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
 gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo=
 gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8=
@@ -1027,8 +1027,8 @@ go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ=
 go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28=
 go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs=
 go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM=
-go-simpler.org/sloglint v0.7.0 h1:rMZRxD9MbaGoRFobIOicMxZzum7AXNFDlez6xxJs5V4=
-go-simpler.org/sloglint v0.7.0/go.mod h1:g9SXiSWY0JJh4LS39/Q0GxzP/QX2cVcbTOYhDpXrJEs=
+go-simpler.org/sloglint v0.7.1 h1:qlGLiqHbN5islOxjeLXoPtUdZXb669RW+BDQ+xOSNoU=
+go-simpler.org/sloglint v0.7.1/go.mod h1:OlaVDRh/FKKd4X4sIMbsz8st97vomydceL146Fthh/c=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -1104,8 +1104,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
 golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
-golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
-golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
+golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1134,8 +1134,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -1156,8 +1154,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
+golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1205,16 +1203,16 @@ golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
 golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
-golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
-golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
+golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
-golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
+golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1302,8 +1300,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
-golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1318,8 +1316,8 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
 golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
 golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
-golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
-golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
+golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1336,8 +1334,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
-golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1414,8 +1412,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
 golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
-golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
-golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
+golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1555,8 +1553,8 @@ honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs=
 honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0=
 mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo=
 mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA=
-mvdan.cc/unparam v0.0.0-20240427195214-063aff900ca1 h1:Nykk7fggxChwLK4rUPYESzeIwqsuxXXlFEAh5YhaMRo=
-mvdan.cc/unparam v0.0.0-20240427195214-063aff900ca1/go.mod h1:ZzZjEpJDOmx8TdVU6umamY3Xy0UAQUI2DHbf05USVbI=
+mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U=
+mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ=
 nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go
index b7cfd94d..10d8667c 100644
--- a/internal/bootstrap/bootstrap.go
+++ b/internal/bootstrap/bootstrap.go
@@ -368,7 +368,7 @@ type Downloader struct {
 
 func NewDownloader(concurrency uint, fsys afero.Fs) *Downloader {
 	return &Downloader{
-		api:   fetcher.NewFetcher(""),
+		api:   fetcher.NewFetcher("", fetcher.WithExpectedStatus(http.StatusOK)),
 		queue: utils.NewJobQueue(concurrency),
 		fsys:  fsys,
 	}
diff --git a/internal/db/diff/diff.go b/internal/db/diff/diff.go
index 3f15c5fc..474b02b7 100644
--- a/internal/db/diff/diff.go
+++ b/internal/db/diff/diff.go
@@ -43,8 +43,8 @@ func Run(ctx context.Context, schema []string, file string, config pgconn.Config
 			return err
 		} else if len(container) > 0 {
 			defer utils.DockerRemove(container)
-			if !start.WaitForHealthyService(ctx, container, start.HealthTimeout) {
-				return errors.New(start.ErrDatabase)
+			if err := start.WaitForHealthyService(ctx, start.HealthTimeout, container); err != nil {
+				return err
 			}
 			if err := migrateBaseDatabase(ctx, container, fsys, options...); err != nil {
 				return err
@@ -206,8 +206,8 @@ func DiffDatabase(ctx context.Context, schema []string, config pgconn.Config, w
 		return "", err
 	}
 	defer utils.DockerRemove(shadow)
-	if !start.WaitForHealthyService(ctx, shadow, start.HealthTimeout) {
-		return "", errors.New(start.ErrDatabase)
+	if err := start.WaitForHealthyService(ctx, start.HealthTimeout, shadow); err != nil {
+		return "", err
 	}
 	if err := MigrateShadowDatabase(ctx, shadow, fsys, options...); err != nil {
 		return "", err
diff --git a/internal/db/diff/migra.go b/internal/db/diff/migra.go
index 01ee2f5a..6b7dbd16 100644
--- a/internal/db/diff/migra.go
+++ b/internal/db/diff/migra.go
@@ -30,7 +30,7 @@ func DiffSchemaMigra(ctx context.Context, source, target string, schema []string
 			Cmd:   cmd,
 		},
 		container.HostConfig{
-			NetworkMode: container.NetworkMode("host"),
+			NetworkMode: network.NetworkHost,
 		},
 		network.NetworkingConfig{},
 		"",
diff --git a/internal/db/diff/pgadmin.go b/internal/db/diff/pgadmin.go
index 248a38a8..f1b63ee0 100644
--- a/internal/db/diff/pgadmin.go
+++ b/internal/db/diff/pgadmin.go
@@ -6,7 +6,6 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/go-errors/errors"
 	"github.com/jackc/pgconn"
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/internal/db/start"
@@ -63,8 +62,8 @@ func run(p utils.Program, ctx context.Context, schema []string, config pgconn.Co
 		return err
 	}
 	defer utils.DockerRemove(shadow)
-	if !start.WaitForHealthyService(ctx, shadow, start.HealthTimeout) {
-		return errors.New(start.ErrDatabase)
+	if err := start.WaitForHealthyService(ctx, start.HealthTimeout, shadow); err != nil {
+		return err
 	}
 	if err := MigrateShadowDatabase(ctx, shadow, fsys); err != nil {
 		return err
diff --git a/internal/db/dump/dump.go b/internal/db/dump/dump.go
index ae812dea..a72ec30b 100644
--- a/internal/db/dump/dump.go
+++ b/internal/db/dump/dump.go
@@ -96,11 +96,12 @@ func dumpData(ctx context.Context, config pgconn.Config, schema, excludeTable []
 		"extensions",
 		"pgbouncer",
 		"realtime",
-		"_realtime",
 		// "storage",
-		"_analytics",
 		// "supabase_functions",
 		"supabase_migrations",
+		"_analytics",
+		"_realtime",
+		"_supavisor",
 	}
 	var env []string
 	if len(schema) > 0 {
@@ -174,7 +175,7 @@ func dump(ctx context.Context, config pgconn.Config, script string, env []string
 			Cmd:   []string{"bash", "-c", script, "--"},
 		},
 		container.HostConfig{
-			NetworkMode: container.NetworkMode("host"),
+			NetworkMode: network.NetworkHost,
 		},
 		network.NetworkingConfig{},
 		"",
diff --git a/internal/db/reset/reset.go b/internal/db/reset/reset.go
index 01eadff3..7fb73ecb 100644
--- a/internal/db/reset/reset.go
+++ b/internal/db/reset/reset.go
@@ -8,12 +8,10 @@ import (
 	"os"
 	"strconv"
 	"strings"
-	"time"
 
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/errdefs"
-	"github.com/docker/docker/pkg/stdcopy"
 	"github.com/go-errors/errors"
 	"github.com/jackc/pgconn"
 	"github.com/jackc/pgerrcode"
@@ -23,14 +21,11 @@ import (
 	"github.com/supabase/cli/internal/gen/keys"
 	"github.com/supabase/cli/internal/migration/apply"
 	"github.com/supabase/cli/internal/migration/repair"
-	"github.com/supabase/cli/internal/status"
 	"github.com/supabase/cli/internal/utils"
 	"github.com/supabase/cli/internal/utils/pgxv5"
 )
 
 var (
-	ErrUnhealthy   = errors.New("service not healthy")
-	serviceTimeout = 30 * time.Second
 	//go:embed templates/drop.sql
 	dropObjects string
 	//go:embed templates/list.sql
@@ -133,8 +128,8 @@ func resetDatabase15(ctx context.Context, version string, fsys afero.Fs, options
 	if _, err := utils.DockerStart(ctx, config, hostConfig, networkingConfig, utils.DbId); err != nil {
 		return err
 	}
-	if !start.WaitForHealthyService(ctx, utils.DbId, start.HealthTimeout) {
-		return errors.New(start.ErrDatabase)
+	if err := start.WaitForHealthyService(ctx, start.HealthTimeout, utils.DbId); err != nil {
+		return err
 	}
 	conn, err := utils.ConnectLocalPostgres(ctx, pgconn.Config{}, options...)
 	if err != nil {
@@ -203,8 +198,8 @@ func RestartDatabase(ctx context.Context, w io.Writer) error {
 	if err := utils.Docker.ContainerRestart(ctx, utils.DbId, container.StopOptions{}); err != nil {
 		return errors.Errorf("failed to restart container: %w", err)
 	}
-	if !start.WaitForHealthyService(ctx, utils.DbId, start.HealthTimeout) {
-		return errors.New(start.ErrDatabase)
+	if err := start.WaitForHealthyService(ctx, start.HealthTimeout, utils.DbId); err != nil {
+		return err
 	}
 	return restartServices(ctx)
 }
@@ -222,39 +217,6 @@ func restartServices(ctx context.Context) error {
 	return errors.Join(result...)
 }
 
-func WaitForServiceReady(ctx context.Context, started []string) error {
-	probe := func() bool {
-		var unhealthy []string
-		for _, container := range started {
-			if !status.IsServiceReady(ctx, container) {
-				unhealthy = append(unhealthy, container)
-			}
-		}
-		started = unhealthy
-		return len(started) == 0
-	}
-	if !start.RetryEverySecond(ctx, probe, serviceTimeout) {
-		// Print container logs for easier debugging
-		for _, containerId := range started {
-			logs, err := utils.Docker.ContainerLogs(ctx, containerId, container.LogsOptions{
-				ShowStdout: true,
-				ShowStderr: true,
-			})
-			if err != nil {
-				fmt.Fprintln(os.Stderr, err)
-				continue
-			}
-			fmt.Fprintln(os.Stderr, containerId, "container logs:")
-			if _, err := stdcopy.StdCopy(os.Stderr, os.Stderr, logs); err != nil {
-				fmt.Fprintln(os.Stderr, err)
-			}
-			logs.Close()
-		}
-		return errors.Errorf("%w: %v", ErrUnhealthy, started)
-	}
-	return nil
-}
-
 func resetRemote(ctx context.Context, version string, config pgconn.Config, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
 	fmt.Fprintln(os.Stderr, "Resetting remote database"+toLogMessage(version))
 	conn, err := utils.ConnectByConfigStream(ctx, config, io.Discard, options...)
diff --git a/internal/db/start/start.go b/internal/db/start/start.go
index 778e3e5e..882281dc 100644
--- a/internal/db/start/start.go
+++ b/internal/db/start/start.go
@@ -10,6 +10,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/cenkalti/backoff/v4"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/client"
@@ -25,7 +26,6 @@ import (
 )
 
 var (
-	ErrDatabase   = errors.New("database is not healthy")
 	HealthTimeout = 120 * time.Second
 	//go:embed templates/schema.sql
 	initialSchema string
@@ -45,7 +45,7 @@ func Run(ctx context.Context, fsys afero.Fs) error {
 	utils.Config.Analytics.Enabled = false
 	err := StartDatabase(ctx, fsys, os.Stderr)
 	if err != nil {
-		if err := utils.DockerRemoveAll(context.Background(), io.Discard); err != nil {
+		if err := utils.DockerRemoveAll(context.Background(), os.Stderr); err != nil {
 			fmt.Fprintln(os.Stderr, err)
 		}
 	}
@@ -107,7 +107,6 @@ func NewHostConfig() container.HostConfig {
 			utils.DbId + ":/var/lib/postgresql/data",
 			utils.ConfigId + ":/etc/postgresql-custom",
 		},
-		ExtraHosts: []string{"host.docker.internal:host-gateway"},
 	})
 	return hostConfig
 }
@@ -137,8 +136,8 @@ func StartDatabase(ctx context.Context, fsys afero.Fs, w io.Writer, options ...f
 	if _, err := utils.DockerStart(ctx, config, hostConfig, networkingConfig, utils.DbId); err != nil {
 		return err
 	}
-	if !WaitForHealthyService(ctx, utils.DbId, HealthTimeout) {
-		return errors.New(ErrDatabase)
+	if err := WaitForHealthyService(ctx, HealthTimeout, utils.DbId); err != nil {
+		return err
 	}
 	// Initialize if we are on PG14 and there's no existing db volume
 	if utils.NoBackupVolume {
@@ -149,24 +148,40 @@ func StartDatabase(ctx context.Context, fsys afero.Fs, w io.Writer, options ...f
 	return initCurrentBranch(fsys)
 }
 
-func RetryEverySecond(ctx context.Context, callback func() bool, timeout time.Duration) bool {
-	now := time.Now()
-	expiry := now.Add(timeout)
-	ticker := time.NewTicker(time.Second)
-	defer ticker.Stop()
-	for t := now; t.Before(expiry) && ctx.Err() == nil; t = <-ticker.C {
-		if callback() {
-			return true
+func WaitForHealthyService(ctx context.Context, timeout time.Duration, started ...string) error {
+	probe := func() error {
+		var errHealth []error
+		var unhealthy []string
+		for _, container := range started {
+			if err := status.IsServiceReady(ctx, container); err != nil {
+				unhealthy = append(unhealthy, container)
+				errHealth = append(errHealth, err)
+			}
+		}
+		started = unhealthy
+		return errors.Join(errHealth...)
+	}
+	policy := backoff.WithContext(backoff.WithMaxRetries(
+		backoff.NewConstantBackOff(time.Second),
+		uint64(timeout.Seconds()),
+	), ctx)
+	err := backoff.Retry(probe, policy)
+	if err != nil && !errors.Is(err, context.Canceled) {
+		// Print container logs for easier debugging
+		for _, containerId := range started {
+			fmt.Fprintln(os.Stderr, containerId, "container logs:")
+			if err := utils.DockerStreamLogsOnce(context.Background(), containerId, os.Stderr, os.Stderr); err != nil {
+				fmt.Fprintln(os.Stderr, err)
+			}
 		}
 	}
-	return false
+	return err
 }
 
-func WaitForHealthyService(ctx context.Context, container string, timeout time.Duration) bool {
-	probe := func() bool {
-		return status.AssertContainerHealthy(ctx, container) == nil
-	}
-	return RetryEverySecond(ctx, probe, timeout)
+func IsUnhealthyError(err error) bool {
+	// Health check always returns a joinError
+	_, ok := err.(interface{ Unwrap() []error })
+	return ok
 }
 
 func WithSyslogConfig(hostConfig container.HostConfig) container.HostConfig {
@@ -208,7 +223,7 @@ func initSchema14(ctx context.Context, conn *pgx.Conn) error {
 func initSchema15(ctx context.Context, host string) error {
 	// Apply service migrations
 	logger := utils.GetDebugLogger()
-	if err := utils.DockerRunOnceWithStream(ctx, utils.RealtimeImage, []string{
+	if err := utils.DockerRunOnceWithStream(ctx, utils.Config.Realtime.Image, []string{
 		"PORT=4000",
 		"DB_HOST=" + host,
 		"DB_PORT=5432",
diff --git a/internal/db/start/templates/schema.sql b/internal/db/start/templates/schema.sql
index a215f0d8..0d001023 100644
--- a/internal/db/start/templates/schema.sql
+++ b/internal/db/start/templates/schema.sql
@@ -18,6 +18,9 @@ alter schema _realtime owner to postgres;
 create schema if not exists _analytics;
 alter schema _analytics owner to postgres;
 
+create schema if not exists _supavisor;
+alter schema _supavisor owner to postgres;
+
 BEGIN;
 
 -- Create pg_net extension
diff --git a/internal/functions/deploy/deploy.go b/internal/functions/deploy/deploy.go
index 8041a9d4..a03a432f 100644
--- a/internal/functions/deploy/deploy.go
+++ b/internal/functions/deploy/deploy.go
@@ -38,7 +38,7 @@ func Run(ctx context.Context, slugs []string, projectRef string, noVerifyJWT *bo
 		return err
 	}
 	if len(slugs) == 0 {
-		allSlugs, err := getFunctionSlugs(fsys)
+		allSlugs, err := GetFunctionSlugs(fsys)
 		if err != nil {
 			return err
 		}
@@ -57,14 +57,14 @@ func Run(ctx context.Context, slugs []string, projectRef string, noVerifyJWT *bo
 }
 
 func RunDefault(ctx context.Context, projectRef string, fsys afero.Fs) error {
-	slugs, err := getFunctionSlugs(fsys)
+	slugs, err := GetFunctionSlugs(fsys)
 	if len(slugs) == 0 {
 		return err
 	}
 	return deployAll(ctx, slugs, projectRef, "", nil, fsys)
 }
 
-func getFunctionSlugs(fsys afero.Fs) ([]string, error) {
+func GetFunctionSlugs(fsys afero.Fs) ([]string, error) {
 	pattern := filepath.Join(utils.FunctionsDir, "*", "index.ts")
 	paths, err := afero.Glob(fsys, pattern)
 	if err != nil {
@@ -102,9 +102,9 @@ func bundleFunction(ctx context.Context, slug, dockerEntrypointPath, importMapPa
 	binds := []string{
 		// Reuse deno cache directory, ie. DENO_DIR, between container restarts
 		// https://denolib.gitbook.io/guide/advanced/deno_dir-code-fetch-and-cache
-		utils.EdgeRuntimeId + ":/root/.cache/deno:rw,z",
-		filepath.Join(cwd, utils.FunctionsDir) + ":" + utils.DockerFuncDirPath + ":ro,z",
-		filepath.Join(cwd, hostOutputDir) + ":" + dockerOutputDir + ":rw,z",
+		utils.EdgeRuntimeId + ":/root/.cache/deno:rw",
+		filepath.Join(cwd, utils.FunctionsDir) + ":" + utils.DockerFuncDirPath + ":ro",
+		filepath.Join(cwd, hostOutputDir) + ":" + dockerOutputDir + ":rw",
 	}
 
 	cmd := []string{"bundle", "--entrypoint", dockerEntrypointPath, "--output", outputPath}
@@ -129,8 +129,7 @@ func bundleFunction(ctx context.Context, slug, dockerEntrypointPath, importMapPa
 			Cmd:   cmd,
 		},
 		start.WithSyslogConfig(container.HostConfig{
-			Binds:      binds,
-			ExtraHosts: []string{"host.docker.internal:host-gateway"},
+			Binds: binds,
 		}),
 		network.NetworkingConfig{},
 		"",
@@ -203,44 +202,15 @@ func deployFunction(ctx context.Context, projectRef, slug, entrypointUrl, import
 }
 
 func deployOne(ctx context.Context, slug, projectRef, importMapPath string, noVerifyJWT *bool, fsys afero.Fs) error {
-	// 1. Ensure noVerifyJWT is not nil.
-	if noVerifyJWT == nil {
-		x := false
-		if functionConfig, ok := utils.Config.Functions[slug]; ok && !*functionConfig.VerifyJWT {
-			x = true
-		}
-		noVerifyJWT = &x
-	}
-	resolved, err := utils.AbsImportMapPath(importMapPath, slug, fsys)
-	if err != nil {
-		return err
-	}
-	// Upstream server expects import map to be always defined
-	if importMapPath == "" {
-		resolved, err = filepath.Abs(utils.FallbackImportMapPath)
-		if err != nil {
-			return errors.Errorf("failed to resolve absolute path: %w", err)
-		}
-	}
-	exists, err := afero.Exists(fsys, resolved)
-	if err != nil {
-		logger := utils.GetDebugLogger()
-		fmt.Fprintln(logger, err)
-	}
-	if exists {
-		importMapPath = resolved
-	} else {
-		importMapPath = ""
-	}
-
-	// 2. Bundle Function.
+	// 1. Bundle Function.
 	fmt.Println("Bundling " + utils.Bold(slug))
+	fc := utils.GetFunctionConfig(slug, importMapPath, noVerifyJWT, fsys)
 	dockerEntrypointPath := path.Join(utils.DockerFuncDirPath, slug, "index.ts")
-	functionBody, err := bundleFunction(ctx, slug, dockerEntrypointPath, importMapPath, fsys)
+	functionBody, err := bundleFunction(ctx, slug, dockerEntrypointPath, fc.ImportMap, fsys)
 	if err != nil {
 		return err
 	}
-	// 3. Deploy new Function.
+	// 2. Deploy new Function.
 	functionSize := units.HumanSize(float64(functionBody.Len()))
 	fmt.Println("Deploying " + utils.Bold(slug) + " (script size: " + utils.Bold(functionSize) + ")")
 	policy := backoff.WithContext(backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 3), ctx)
@@ -251,7 +221,7 @@ func deployOne(ctx context.Context, slug, projectRef, importMapPath string, noVe
 			slug,
 			"file://"+dockerEntrypointPath,
 			"file://"+dockerImportMapPath,
-			!*noVerifyJWT,
+			*fc.VerifyJWT,
 			functionBody,
 		)
 	}, policy)
diff --git a/internal/functions/download/download.go b/internal/functions/download/download.go
index 06b84273..db3aabba 100644
--- a/internal/functions/download/download.go
+++ b/internal/functions/download/download.go
@@ -176,9 +176,9 @@ func extractOne(ctx context.Context, slug, eszipPath string) error {
 	binds := []string{
 		// Reuse deno cache directory, ie. DENO_DIR, between container restarts
 		// https://denolib.gitbook.io/guide/advanced/deno_dir-code-fetch-and-cache
-		utils.EdgeRuntimeId + ":/root/.cache/deno:rw,z",
-		hostEszipPath + ":" + dockerEszipPath + ":ro,z",
-		hostFuncDirPath + ":" + utils.DockerDenoDir + ":rw,z",
+		utils.EdgeRuntimeId + ":/root/.cache/deno:rw",
+		hostEszipPath + ":" + dockerEszipPath + ":ro",
+		hostFuncDirPath + ":" + utils.DockerDenoDir + ":rw",
 	}
 
 	return utils.DockerRunOnceWithConfig(
@@ -188,8 +188,7 @@ func extractOne(ctx context.Context, slug, eszipPath string) error {
 			Cmd:   []string{"unbundle", "--eszip", dockerEszipPath, "--output", utils.DockerDenoDir},
 		},
 		start.WithSyslogConfig(container.HostConfig{
-			Binds:      binds,
-			ExtraHosts: []string{"host.docker.internal:host-gateway"},
+			Binds: binds,
 		}),
 		network.NetworkingConfig{},
 		"",
diff --git a/internal/functions/serve/serve.go b/internal/functions/serve/serve.go
index a99acfc8..26f59f2c 100644
--- a/internal/functions/serve/serve.go
+++ b/internal/functions/serve/serve.go
@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"io"
 	"os"
+	"path"
 	"path/filepath"
 	"strings"
 
@@ -17,6 +18,7 @@ import (
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
 	"github.com/supabase/cli/internal/db/start"
+	"github.com/supabase/cli/internal/functions/deploy"
 	"github.com/supabase/cli/internal/secrets/set"
 	"github.com/supabase/cli/internal/utils"
 )
@@ -86,7 +88,7 @@ func Run(ctx context.Context, envFilePath string, noVerifyJWT *bool, importMapPa
 		Force:         true,
 	})
 	// Use network alias because Deno cannot resolve `_` in hostname
-	dbUrl := "postgresql://postgres:postgres@" + utils.DbAliases[0] + ":5432/postgres"
+	dbUrl := fmt.Sprintf("postgresql://postgres:postgres@%s:5432/postgres", utils.DbAliases[0])
 	// 3. Serve and log to console
 	if err := ServeFunctions(ctx, envFilePath, noVerifyJWT, importMapPath, dbUrl, runtimeOption, os.Stderr, fsys); err != nil {
 		return err
@@ -104,35 +106,23 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool,
 		if f, err := fsys.Stat(utils.FallbackEnvFilePath); err == nil && !f.IsDir() {
 			envFilePath = utils.FallbackEnvFilePath
 		}
-	} else if _, err := fsys.Stat(envFilePath); err != nil {
-		return errors.Errorf("Failed to read env file: %w", err)
-	}
-	cwd, err := os.Getwd()
-	if err != nil {
-		return errors.Errorf("failed to get working directory: %w", err)
-	}
-	if importMapPath != "" {
-		if !filepath.IsAbs(importMapPath) {
-			importMapPath = filepath.Join(cwd, importMapPath)
-		}
-		if _, err := fsys.Stat(importMapPath); err != nil {
-			return errors.Errorf("Failed to read import map: %w", err)
-		}
+	} else if !filepath.IsAbs(envFilePath) {
+		envFilePath = filepath.Join(utils.CurrentDirAbs, envFilePath)
 	}
 	// 2. Parse user defined env
-	userEnv, err := parseEnvFile(envFilePath, fsys)
+	env, err := parseEnvFile(envFilePath, fsys)
 	if err != nil {
 		return err
 	}
-	env := []string{
-		"SUPABASE_URL=http://" + utils.KongAliases[0] + ":8000",
-		"SUPABASE_ANON_KEY=" + utils.Config.Auth.AnonKey,
-		"SUPABASE_SERVICE_ROLE_KEY=" + utils.Config.Auth.ServiceRoleKey,
-		"SUPABASE_DB_URL=" + dbUrl,
-		"SUPABASE_INTERNAL_JWT_SECRET=" + utils.Config.Auth.JwtSecret,
+	env = append(env,
+		fmt.Sprintf("SUPABASE_URL=http://%s:8000", utils.KongAliases[0]),
+		"SUPABASE_ANON_KEY="+utils.Config.Auth.AnonKey,
+		"SUPABASE_SERVICE_ROLE_KEY="+utils.Config.Auth.ServiceRoleKey,
+		"SUPABASE_DB_URL="+dbUrl,
+		"SUPABASE_INTERNAL_JWT_SECRET="+utils.Config.Auth.JwtSecret,
 		fmt.Sprintf("SUPABASE_INTERNAL_HOST_PORT=%d", utils.Config.Api.Port),
-		"SUPABASE_INTERNAL_FUNCTIONS_PATH=" + utils.DockerFuncDirPath,
-	}
+		"SUPABASE_INTERNAL_FUNCTIONS_PATH="+utils.DockerFuncDirPath,
+	)
 	if viper.GetBool("DEBUG") {
 		env = append(env, "SUPABASE_INTERNAL_DEBUG=true")
 	}
@@ -140,44 +130,20 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool,
 		env = append(env, "SUPABASE_INTERNAL_WALLCLOCK_LIMIT_SEC=0")
 	}
 	// 3. Parse custom import map
-	binds := []string{
-		// Reuse deno cache directory, ie. DENO_DIR, between container restarts
-		// https://denolib.gitbook.io/guide/advanced/deno_dir-code-fetch-and-cache
-		utils.EdgeRuntimeId + ":/root/.cache/deno:rw,z",
-		filepath.Join(cwd, utils.FunctionsDir) + ":" + utils.DockerFuncDirPath + ":rw,z",
-	}
-	if importMapPath != "" {
-		modules, err := utils.BindImportMap(importMapPath, dockerFlagImportMapPath, fsys)
-		if err != nil {
-			return err
-		}
-		binds = append(binds, modules...)
-	}
-
-	fallbackImportMapPath := filepath.Join(cwd, utils.FallbackImportMapPath)
-	if exists, err := afero.Exists(fsys, fallbackImportMapPath); err != nil {
-		return errors.Errorf("Failed to read fallback import map: %w", err)
-	} else if !exists {
-		fallbackImportMapPath = utils.AbsTempImportMapPath(cwd, utils.ImportMapsDir)
-		if err := utils.WriteFile(fallbackImportMapPath, []byte(`{"imports":{}}`), fsys); err != nil {
-			return err
-		}
-	}
-	if fallbackImportMapPath != importMapPath {
-		modules, err := utils.BindImportMap(fallbackImportMapPath, dockerFallbackImportMapPath, fsys)
-		if err != nil {
-			return err
-		}
-		binds = append(binds, modules...)
-	}
-
-	if err := utils.MkdirIfNotExistFS(fsys, utils.FunctionsDir); err != nil {
+	binds, functionsConfigString, err := populatePerFunctionConfigs(importMapPath, noVerifyJWT, fsys)
+	if err != nil {
 		return err
 	}
-	binds, functionsConfigString, err := populatePerFunctionConfigs(binds, importMapPath, noVerifyJWT, fsys)
+	cwd, err := os.Getwd()
 	if err != nil {
-		return err
+		return errors.Errorf("failed to get working directory: %w", err)
 	}
+	binds = append(binds,
+		// Reuse deno cache directory, ie. DENO_DIR, between container restarts
+		// https://denolib.gitbook.io/guide/advanced/deno_dir-code-fetch-and-cache
+		utils.EdgeRuntimeId+":/root/.cache/deno:rw",
+		filepath.Join(cwd, utils.FunctionsDir)+":"+utils.DockerFuncDirPath+":rw",
+	)
 	env = append(env, "SUPABASE_INTERNAL_FUNCTIONS_CONFIG="+functionsConfigString)
 	// 4. Parse entrypoint script
 	cmd := append([]string{
@@ -191,7 +157,6 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool,
 		cmd = append(cmd, "--verbose")
 	}
 	cmdString := strings.Join(cmd, " ")
-
 	entrypoint := []string{"sh", "-c", `cat <<'EOF' > index.ts && ` + cmdString + `
 ` + mainFuncEmbed + `
 EOF
@@ -211,7 +176,7 @@ EOF
 		ctx,
 		container.Config{
 			Image:        utils.EdgeRuntimeImage,
-			Env:          append(env, userEnv...),
+			Env:          env,
 			Entrypoint:   entrypoint,
 			ExposedPorts: exposedPorts,
 			WorkingDir:   dockerRuntimeMainPath,
@@ -220,7 +185,6 @@ EOF
 		start.WithSyslogConfig(container.HostConfig{
 			Binds:        binds,
 			PortBindings: portBindings,
-			ExtraHosts:   []string{"host.docker.internal:host-gateway"},
 		}),
 		network.NetworkingConfig{
 			EndpointsConfig: map[string]*network.EndpointSettings{
@@ -253,58 +217,25 @@ func parseEnvFile(envFilePath string, fsys afero.Fs) ([]string, error) {
 	return env, nil
 }
 
-func populatePerFunctionConfigs(binds []string, importMapPath string, noVerifyJWT *bool, fsys afero.Fs) ([]string, string, error) {
-	type functionConfig struct {
-		ImportMapPath string `json:"importMapPath"`
-		VerifyJWT     bool   `json:"verifyJWT"`
-	}
-
-	functionsConfig := map[string]functionConfig{}
-
-	cwd, err := os.Getwd()
-	if err != nil {
-		return nil, "", errors.Errorf("failed to get working directory: %w", err)
-	}
-
-	functions, err := afero.ReadDir(fsys, utils.FunctionsDir)
+func populatePerFunctionConfigs(importMapPath string, noVerifyJWT *bool, fsys afero.Fs) ([]string, string, error) {
+	slugs, err := deploy.GetFunctionSlugs(fsys)
 	if err != nil {
-		return nil, "", errors.Errorf("failed to read directory: %w", err)
+		return nil, "", err
 	}
-	for _, function := range functions {
-		if !function.IsDir() {
-			continue
-		}
 
-		functionName := function.Name()
-		if !utils.FuncSlugPattern.MatchString(functionName) {
-			continue
-		}
-
-		// CLI flags take priority over config.toml.
-		dockerImportMapPath := dockerFallbackImportMapPath
-		if importMapPath != "" {
-			dockerImportMapPath = dockerFlagImportMapPath
-		} else if functionConfig, ok := utils.Config.Functions[functionName]; ok && functionConfig.ImportMap != "" {
-			dockerImportMapPath = utils.DockerDenoDir + "/import_maps/" + functionName + "/import_map.json"
-			hostImportMapPath := filepath.Join(cwd, utils.SupabaseDirPath, functionConfig.ImportMap)
-			modules, err := utils.BindImportMap(hostImportMapPath, dockerImportMapPath, fsys)
+	binds := []string{}
+	functionsConfig := make(map[string]interface{}, len(slugs))
+	for _, functionName := range slugs {
+		fc := utils.GetFunctionConfig(functionName, importMapPath, noVerifyJWT, fsys)
+		if hostImportMapPath := fc.ImportMap; hostImportMapPath != "" {
+			fc.ImportMap = path.Join(utils.DockerDenoDir, "import_maps", functionName, "import_map.json")
+			modules, err := utils.BindImportMap(hostImportMapPath, fc.ImportMap, fsys)
 			if err != nil {
 				return nil, "", err
 			}
 			binds = append(binds, modules...)
 		}
-
-		verifyJWT := true
-		if noVerifyJWT != nil {
-			verifyJWT = !*noVerifyJWT
-		} else if functionConfig, ok := utils.Config.Functions[functionName]; ok && functionConfig.VerifyJWT != nil {
-			verifyJWT = *functionConfig.VerifyJWT
-		}
-
-		functionsConfig[functionName] = functionConfig{
-			ImportMapPath: dockerImportMapPath,
-			VerifyJWT:     verifyJWT,
-		}
+		functionsConfig[functionName] = fc
 	}
 
 	functionsConfigBytes, err := json.Marshal(functionsConfig)
@@ -312,5 +243,5 @@ func populatePerFunctionConfigs(binds []string, importMapPath string, noVerifyJW
 		return nil, "", errors.Errorf("failed to marshal config json: %w", err)
 	}
 
-	return binds, string(functionsConfigBytes), nil
+	return utils.RemoveDuplicates(binds), string(functionsConfigBytes), nil
 }
diff --git a/internal/gen/types/typescript/typescript.go b/internal/gen/types/typescript/typescript.go
index 3e85369d..442afdb8 100644
--- a/internal/gen/types/typescript/typescript.go
+++ b/internal/gen/types/typescript/typescript.go
@@ -40,7 +40,7 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas
 		return nil
 	}
 
-	networkID := "host"
+	hostConfig := container.HostConfig{}
 	if utils.IsLocalDatabase(dbConfig) {
 		if err := utils.AssertSupabaseDbIsRunning(); err != nil {
 			return err
@@ -53,7 +53,8 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas
 		// Use custom network when connecting to local database
 		dbConfig.Host = utils.DbAliases[0]
 		dbConfig.Port = 5432
-		networkID = utils.NetId
+	} else {
+		hostConfig.NetworkMode = network.NetworkHost
 	}
 	// pg-meta does not set username as the default database, ie. postgres
 	if len(dbConfig.Database) == 0 {
@@ -81,9 +82,7 @@ func Run(ctx context.Context, projectId string, dbConfig pgconn.Config, schemas
 			},
 			Cmd: []string{"node", "dist/server/server.js"},
 		},
-		container.HostConfig{
-			NetworkMode: container.NetworkMode(networkID),
-		},
+		hostConfig,
 		network.NetworkingConfig{},
 		"",
 		os.Stdout,
diff --git a/internal/login/login.go b/internal/login/login.go
index 886e27d7..cd7a20f0 100644
--- a/internal/login/login.go
+++ b/internal/login/login.go
@@ -8,7 +8,6 @@ import (
 	"crypto/ecdh"
 	"crypto/rand"
 	"encoding/hex"
-	"encoding/json"
 	"fmt"
 	"io"
 	"net/http"
@@ -18,11 +17,13 @@ import (
 	"strings"
 	"time"
 
+	"github.com/cenkalti/backoff/v4"
 	"github.com/go-errors/errors"
 	"github.com/google/uuid"
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/internal/migration/new"
 	"github.com/supabase/cli/internal/utils"
+	"github.com/supabase/cli/pkg/fetcher"
 )
 
 type RunParams struct {
@@ -43,6 +44,7 @@ type AccessTokenResponse struct {
 }
 
 const defaultRetryAfterSeconds = 2
+const defaultMaxRetries = 90
 const decryptionErrorMsg = "cannot decrypt access token"
 
 var loggedInMsg = "You are now logged in. " + utils.Aqua("Happy coding!")
@@ -127,48 +129,29 @@ func (enc LoginEncryption) decryptAccessToken(accessToken string, publicKey stri
 }
 
 func pollForAccessToken(ctx context.Context, url string) (AccessTokenResponse, error) {
-	var accessTokenResponse AccessTokenResponse
-
 	// TODO: Move to OpenAPI-generated http client once we reach v1 on API schema.
-	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
-	if err != nil {
-		return accessTokenResponse, errors.Errorf("cannot fetch access token: %w", err)
-	}
-	resp, err := http.DefaultClient.Do(req)
-	if err != nil {
-		return accessTokenResponse, errors.Errorf("cannot fetch access token: %w", err)
-	}
-	defer resp.Body.Close()
-
-	if resp.StatusCode == http.StatusNotFound {
-		retryAfterSeconds, err := strconv.Atoi(resp.Header.Get("Retry-After"))
-		if err != nil {
-			retryAfterSeconds = defaultRetryAfterSeconds
+	client := fetcher.NewFetcher(
+		utils.GetSupabaseAPIHost(),
+		fetcher.WithHTTPClient(&http.Client{
+			Timeout: 10 * time.Second,
+		}),
+		fetcher.WithExpectedStatus(http.StatusOK),
+	)
+	timeout := backoff.NewConstantBackOff(defaultRetryAfterSeconds)
+	probe := func() (AccessTokenResponse, error) {
+		resp, err := client.Send(ctx, http.MethodGet, url, nil)
+		if err == nil {
+			defer resp.Body.Close()
+			return fetcher.ParseJSON[AccessTokenResponse](resp.Body)
+		} else if resp != nil {
+			if retryAfterSeconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
+				timeout.Interval = time.Duration(retryAfterSeconds) * time.Second
+			}
 		}
-		t := time.NewTimer(time.Duration(retryAfterSeconds) * time.Second)
-		select {
-		case <-ctx.Done():
-			t.Stop()
-		case <-t.C:
-		}
-		return pollForAccessToken(ctx, url)
+		return AccessTokenResponse{}, err
 	}
-
-	if resp.StatusCode == http.StatusOK {
-		body, err := io.ReadAll(resp.Body)
-
-		if err != nil {
-			return accessTokenResponse, errors.Errorf("cannot read access token response body: %w", err)
-		}
-
-		if err := json.Unmarshal(body, &accessTokenResponse); err != nil {
-			return accessTokenResponse, errors.Errorf("cannot unmarshal access token response: %w", err)
-		}
-
-		return accessTokenResponse, nil
-	}
-
-	return accessTokenResponse, errors.Errorf("HTTP %s: cannot retrieve access token", resp.Status)
+	policy := backoff.WithContext(backoff.WithMaxRetries(timeout, defaultMaxRetries), ctx)
+	return backoff.RetryWithData(probe, policy)
 }
 
 func Run(ctx context.Context, stdout io.Writer, params RunParams) error {
@@ -215,7 +198,7 @@ func Run(ctx context.Context, stdout io.Writer, params RunParams) error {
 	if err := utils.RunProgram(ctx, func(p utils.Program, ctx context.Context) error {
 		p.Send(utils.StatusMsg("Your token is now being generated and securely encrypted. Waiting for it to arrive..."))
 
-		sessionPollingUrl := utils.GetSupabaseAPIHost() + "/platform/cli/login/" + params.SessionId
+		sessionPollingUrl := "/platform/cli/login/" + params.SessionId
 		accessTokenResponse, err := pollForAccessToken(ctx, sessionPollingUrl)
 		if err != nil {
 			return err
diff --git a/internal/login/login_linux.go b/internal/login/login_linux.go
index 6475a60d..a8a182c5 100644
--- a/internal/login/login_linux.go
+++ b/internal/login/login_linux.go
@@ -1,4 +1,4 @@
-//go:build !windows && !darwin
+//go:build linux
 
 package login
 
diff --git a/internal/migration/list/list.go b/internal/migration/list/list.go
index ea22ff56..445239bc 100644
--- a/internal/migration/list/list.go
+++ b/internal/migration/list/list.go
@@ -7,7 +7,6 @@ import (
 	"os"
 	"regexp"
 	"strconv"
-	"time"
 
 	"github.com/charmbracelet/glamour"
 	"github.com/go-errors/errors"
@@ -15,7 +14,6 @@ import (
 	"github.com/jackc/pgerrcode"
 	"github.com/jackc/pgx/v4"
 	"github.com/spf13/afero"
-	"github.com/spf13/viper"
 	"github.com/supabase/cli/internal/utils"
 	"github.com/supabase/cli/internal/utils/pgxv5"
 )
@@ -66,22 +64,6 @@ func listMigrationVersions(ctx context.Context, conn *pgx.Conn) ([]string, error
 	return pgxv5.CollectStrings(rows)
 }
 
-const (
-	layoutVersion = "20060102150405"
-	layoutHuman   = "2006-01-02 15:04:05"
-)
-
-func formatTimestamp(version string) string {
-	timestamp, err := time.Parse(layoutVersion, version)
-	if err != nil {
-		if viper.GetBool("DEBUG") {
-			fmt.Fprintln(os.Stderr, err)
-		}
-		return version
-	}
-	return timestamp.Format(layoutHuman)
-}
-
 func makeTable(remoteMigrations, localMigrations []string) string {
 	var err error
 	table := "|Local|Remote|Time (UTC)|\n|-|-|-|\n"
@@ -102,13 +84,13 @@ func makeTable(remoteMigrations, localMigrations []string) string {
 		}
 		// Top to bottom chronological order
 		if localTimestamp < remoteTimestamp {
-			table += fmt.Sprintf("|`%s`|` `|`%s`|\n", localMigrations[j], formatTimestamp(localMigrations[j]))
+			table += fmt.Sprintf("|`%s`|` `|`%s`|\n", localMigrations[j], utils.FormatTimestampVersion(localMigrations[j]))
 			j++
 		} else if remoteTimestamp < localTimestamp {
-			table += fmt.Sprintf("|` `|`%s`|`%s`|\n", remoteMigrations[i], formatTimestamp(remoteMigrations[i]))
+			table += fmt.Sprintf("|` `|`%s`|`%s`|\n", remoteMigrations[i], utils.FormatTimestampVersion(remoteMigrations[i]))
 			i++
 		} else {
-			table += fmt.Sprintf("|`%s`|`%s`|`%s`|\n", localMigrations[j], remoteMigrations[i], formatTimestamp(remoteMigrations[i]))
+			table += fmt.Sprintf("|`%s`|`%s`|`%s`|\n", localMigrations[j], remoteMigrations[i], utils.FormatTimestampVersion(remoteMigrations[i]))
 			i++
 			j++
 		}
diff --git a/internal/migration/squash/squash.go b/internal/migration/squash/squash.go
index 027e57c2..8a955ed6 100644
--- a/internal/migration/squash/squash.go
+++ b/internal/migration/squash/squash.go
@@ -90,8 +90,8 @@ func squashMigrations(ctx context.Context, migrations []string, fsys afero.Fs, o
 		return err
 	}
 	defer utils.DockerRemove(shadow)
-	if !start.WaitForHealthyService(ctx, shadow, start.HealthTimeout) {
-		return errors.New(start.ErrDatabase)
+	if err := start.WaitForHealthyService(ctx, start.HealthTimeout, shadow); err != nil {
+		return err
 	}
 	conn, err := diff.ConnectShadowDatabase(ctx, 10*time.Second, options...)
 	if err != nil {
diff --git a/internal/secrets/list/list.go b/internal/secrets/list/list.go
index 12bc450f..e5b4d453 100644
--- a/internal/secrets/list/list.go
+++ b/internal/secrets/list/list.go
@@ -3,30 +3,43 @@ package list
 import (
 	"context"
 	"fmt"
+	"sort"
 	"strings"
 
 	"github.com/go-errors/errors"
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/internal/migration/list"
 	"github.com/supabase/cli/internal/utils"
+	"github.com/supabase/cli/pkg/api"
 )
 
 func Run(ctx context.Context, projectRef string, fsys afero.Fs) error {
-	resp, err := utils.GetSupabase().V1ListAllSecretsWithResponse(ctx, projectRef)
+	secrets, err := GetSecretDigests(ctx, projectRef)
 	if err != nil {
-		return errors.Errorf("failed to list secrets: %w", err)
-	}
-
-	if resp.JSON200 == nil {
-		return errors.New("Unexpected error retrieving project secrets: " + string(resp.Body))
+		return err
 	}
 
 	table := `|NAME|DIGEST|
 |-|-|
 `
-	for _, secret := range *resp.JSON200 {
+	for _, secret := range secrets {
 		table += fmt.Sprintf("|`%s`|`%s`|\n", strings.ReplaceAll(secret.Name, "|", "\\|"), secret.Value)
 	}
 
 	return list.RenderTable(table)
 }
+
+func GetSecretDigests(ctx context.Context, projectRef string) ([]api.SecretResponse, error) {
+	resp, err := utils.GetSupabase().V1ListAllSecretsWithResponse(ctx, projectRef)
+	if err != nil {
+		return nil, errors.Errorf("failed to list secrets: %w", err)
+	}
+	if resp.JSON200 == nil {
+		return nil, errors.New("Unexpected error retrieving project secrets: " + string(resp.Body))
+	}
+	secrets := *resp.JSON200
+	sort.Slice(secrets, func(i, j int) bool {
+		return secrets[i].Name < secrets[j].Name
+	})
+	return secrets, nil
+}
diff --git a/internal/secrets/set/set.go b/internal/secrets/set/set.go
index d5ee78d9..d2877c31 100644
--- a/internal/secrets/set/set.go
+++ b/internal/secrets/set/set.go
@@ -3,8 +3,10 @@ package set
 import (
 	"context"
 	"fmt"
+	"maps"
 	"net/http"
 	"os"
+	"path/filepath"
 	"strings"
 
 	"github.com/go-errors/errors"
@@ -16,51 +18,49 @@ import (
 
 func Run(ctx context.Context, projectRef, envFilePath string, args []string, fsys afero.Fs) error {
 	// 1. Sanity checks.
-	// 2. Set secret(s).
-	{
-		var secrets api.V1BulkCreateSecretsJSONBody
-		if envFilePath != "" {
-			envMap, err := ParseEnvFile(envFilePath, fsys)
-			if err != nil {
-				return err
-			}
-			for name, value := range envMap {
-				if strings.HasPrefix(name, "SUPABASE_") {
-					fmt.Fprintln(os.Stderr, "Env name cannot start with SUPABASE_, skipping: "+name)
-					continue
-				}
-				secret := api.CreateSecretBody{
-					Name:  name,
-					Value: value,
-				}
-				secrets = append(secrets, secret)
-			}
-		} else if len(args) == 0 {
-			return errors.New("No arguments found. Use --env-file to read from a .env file.")
-		} else {
-			for _, pair := range args {
-				name, value, found := strings.Cut(pair, "=")
-				if !found {
-					return errors.New("Invalid secret pair: " + utils.Aqua(pair) + ". Must be NAME=VALUE.")
-				}
-
-				secret := api.CreateSecretBody{
-					Name:  name,
-					Value: value,
-				}
-				secrets = append(secrets, secret)
-			}
+	envMap := make(map[string]string, len(args))
+	if len(envFilePath) > 0 {
+		if !filepath.IsAbs(envFilePath) {
+			envFilePath = filepath.Join(utils.CurrentDirAbs, envFilePath)
 		}
-
-		resp, err := utils.GetSupabase().V1BulkCreateSecretsWithResponse(ctx, projectRef, secrets)
+		parsed, err := ParseEnvFile(envFilePath, fsys)
 		if err != nil {
-			return errors.Errorf("failed to set secrets: %w", err)
+			return err
 		}
-
-		// TODO: remove the StatusOK case after 2022-08-20
-		if resp.StatusCode() != http.StatusCreated && resp.StatusCode() != http.StatusOK {
-			return errors.New("Unexpected error setting project secrets: " + string(resp.Body))
+		maps.Copy(envMap, parsed)
+	}
+	for _, pair := range args {
+		name, value, found := strings.Cut(pair, "=")
+		if !found {
+			return errors.Errorf("Invalid secret pair: %s. Must be NAME=VALUE.", pair)
 		}
+		envMap[name] = value
+	}
+	if len(envMap) == 0 {
+		return errors.New("No arguments found. Use --env-file to read from a .env file.")
+	}
+	// 2. Set secret(s).
+	var secrets api.V1BulkCreateSecretsJSONBody
+	for name, value := range envMap {
+		// Lower case prefix is accepted by API
+		if strings.HasPrefix(name, "SUPABASE_") {
+			fmt.Fprintln(os.Stderr, "Env name cannot start with SUPABASE_, skipping: "+name)
+			continue
+		}
+		secret := api.CreateSecretBody{
+			Name:  name,
+			Value: value,
+		}
+		secrets = append(secrets, secret)
+	}
+
+	resp, err := utils.GetSupabase().V1BulkCreateSecretsWithResponse(ctx, projectRef, secrets)
+	if err != nil {
+		return errors.Errorf("failed to set secrets: %w", err)
+	}
+
+	if resp.StatusCode() != http.StatusCreated {
+		return errors.New("Unexpected error setting project secrets: " + string(resp.Body))
 	}
 
 	fmt.Println("Finished " + utils.Aqua("supabase secrets set") + ".")
diff --git a/internal/secrets/unset/unset.go b/internal/secrets/unset/unset.go
index 1b06ca85..f6bbca8c 100644
--- a/internal/secrets/unset/unset.go
+++ b/internal/secrets/unset/unset.go
@@ -4,26 +4,46 @@ import (
 	"context"
 	"fmt"
 	"net/http"
+	"os"
+	"strings"
 
 	"github.com/go-errors/errors"
 	"github.com/spf13/afero"
+	"github.com/supabase/cli/internal/secrets/list"
 	"github.com/supabase/cli/internal/utils"
 )
 
 func Run(ctx context.Context, projectRef string, args []string, fsys afero.Fs) error {
-	// 1. Sanity checks.
-	// 2. Unset secret(s).
-	{
-		resp, err := utils.GetSupabase().V1BulkDeleteSecretsWithResponse(ctx, projectRef, args)
+	if len(args) == 0 {
+		secrets, err := list.GetSecretDigests(ctx, projectRef)
 		if err != nil {
-			return errors.Errorf("failed to delete secrets: %w", err)
+			return err
 		}
-
-		if resp.StatusCode() != http.StatusOK {
-			return errors.New("Unexpected error unsetting project secrets: " + string(resp.Body))
+		for _, secret := range secrets {
+			if !strings.HasPrefix(secret.Name, "SUPABASE_") {
+				args = append(args, secret.Name)
+			}
 		}
 	}
-
+	// 1. Sanity checks.
+	if len(args) == 0 {
+		fmt.Fprintln(os.Stderr, "You have not set any function secrets, nothing to do.")
+		return nil
+	}
+	msg := fmt.Sprintf("Do you want to unset these function secrets?\n • %s\n\n", strings.Join(args, "\n • "))
+	if shouldUnset, err := utils.NewConsole().PromptYesNo(ctx, msg, true); err != nil {
+		return err
+	} else if !shouldUnset {
+		return errors.New(context.Canceled)
+	}
+	// 2. Unset secret(s).
+	resp, err := utils.GetSupabase().V1BulkDeleteSecretsWithResponse(ctx, projectRef, args)
+	if err != nil {
+		return errors.Errorf("failed to delete secrets: %w", err)
+	}
+	if resp.StatusCode() != http.StatusOK {
+		return errors.New("Unexpected error unsetting project secrets: " + string(resp.Body))
+	}
 	fmt.Println("Finished " + utils.Aqua("supabase secrets unset") + ".")
 	return nil
 }
diff --git a/internal/services/services.go b/internal/services/services.go
index 626139f2..c98532b7 100644
--- a/internal/services/services.go
+++ b/internal/services/services.go
@@ -46,13 +46,13 @@ func GetServiceImages() []string {
 		utils.Config.Db.Image,
 		utils.Config.Auth.Image,
 		utils.Config.Api.Image,
-		utils.RealtimeImage,
+		utils.Config.Realtime.Image,
 		utils.Config.Storage.Image,
 		utils.EdgeRuntimeImage,
-		utils.StudioImage,
-		utils.PgmetaImage,
+		utils.Config.Studio.Image,
+		utils.Config.Studio.PgmetaImage,
 		utils.LogflareImage,
-		utils.PgbouncerImage,
+		utils.Config.Db.Pooler.Image,
 		utils.ImageProxyImage,
 	}
 }
diff --git a/internal/sso/internal/saml/files.go b/internal/sso/internal/saml/files.go
index 0fe3648d..3c327e6c 100644
--- a/internal/sso/internal/saml/files.go
+++ b/internal/sso/internal/saml/files.go
@@ -7,11 +7,13 @@ import (
 	"net/http"
 	"net/url"
 	"strings"
+	"time"
 	"unicode/utf8"
 
 	"github.com/go-errors/errors"
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/pkg/api"
+	"github.com/supabase/cli/pkg/fetcher"
 )
 
 var DefaultClient = http.DefaultClient
@@ -67,23 +69,21 @@ func ValidateMetadataURL(ctx context.Context, metadataURL string) error {
 		return errors.New("only HTTPS Metadata URLs are supported")
 	}
 
-	req, err := http.NewRequestWithContext(ctx, http.MethodGet, metadataURL, nil)
+	client := fetcher.NewFetcher("",
+		fetcher.WithHTTPClient(&http.Client{
+			Timeout: 10 * time.Second,
+		}),
+		fetcher.WithRequestEditor(func(req *http.Request) {
+			req.Header.Add("Accept", "application/xml")
+		}),
+		fetcher.WithExpectedStatus(http.StatusOK),
+	)
+	resp, err := client.Send(ctx, http.MethodGet, metadataURL, nil)
 	if err != nil {
-		return errors.Errorf("failed to initialise http request: %w", err)
-	}
-
-	req.Header.Add("Accept", "application/xml")
-
-	resp, err := DefaultClient.Do(req)
-	if err != nil {
-		return errors.Errorf("failed to send http request: %w", err)
+		return err
 	}
 	defer resp.Body.Close()
 
-	if resp.StatusCode != http.StatusOK {
-		return errors.Errorf("received HTTP %v when fetching metatada at %q", resp.Status, metadataURL)
-	}
-
 	data, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return errors.Errorf("failed to read http response: %w", err)
diff --git a/internal/start/start.go b/internal/start/start.go
index 16192be0..43628df2 100644
--- a/internal/start/start.go
+++ b/internal/start/start.go
@@ -5,7 +5,6 @@ import (
 	"context"
 	_ "embed"
 	"fmt"
-	"io"
 	"os"
 	"path"
 	"path/filepath"
@@ -21,7 +20,6 @@ import (
 	"github.com/jackc/pgconn"
 	"github.com/jackc/pgx/v4"
 	"github.com/spf13/afero"
-	"github.com/supabase/cli/internal/db/reset"
 	"github.com/supabase/cli/internal/db/start"
 	"github.com/supabase/cli/internal/functions/serve"
 	"github.com/supabase/cli/internal/services"
@@ -79,10 +77,10 @@ func Run(ctx context.Context, fsys afero.Fs, excludedContainers []string, ignore
 		}
 		return run(p, ctx, fsys, excludedContainers, dbConfig)
 	}); err != nil {
-		if ignoreHealthCheck && errors.Is(err, reset.ErrUnhealthy) {
+		if ignoreHealthCheck && start.IsUnhealthyError(err) {
 			fmt.Fprintln(os.Stderr, err)
 		} else {
-			if err := utils.DockerRemoveAll(context.Background(), io.Discard); err != nil {
+			if err := utils.DockerRemoveAll(context.Background(), os.Stderr); err != nil {
 				fmt.Fprintln(os.Stderr, err)
 			}
 			return err
@@ -136,6 +134,25 @@ var (
 	vectorConfigTemplate = template.Must(template.New("vectorConfig").Parse(vectorConfigEmbed))
 )
 
+type poolerTenant struct {
+	DbHost            string
+	DbPort            uint16
+	DbDatabase        string
+	DbPassword        string
+	ExternalId        string
+	ModeType          utils.PoolMode
+	DefaultMaxClients uint
+	DefaultPoolSize   uint
+}
+
+var (
+	//go:embed templates/pooler.exs
+	poolerTenantEmbed    string
+	poolerTenantTemplate = template.Must(template.New("poolerTenant").Parse(poolerTenantEmbed))
+)
+
+var serviceTimeout = 30 * time.Second
+
 func run(p utils.Program, ctx context.Context, fsys afero.Fs, excludedContainers []string, dbConfig pgconn.Config, options ...func(*pgx.ConnConfig)) error {
 	excluded := make(map[string]bool)
 	for _, name := range excludedContainers {
@@ -171,12 +188,9 @@ func run(p utils.Program, ctx context.Context, fsys afero.Fs, excludedContainers
 EOF
 `},
 				Healthcheck: &container.HealthConfig{
-					Test: []string{"CMD",
-						"wget",
-						"--no-verbose",
-						"--tries=1",
-						"--spider",
-						"http://127.0.0.1:9001/health"},
+					Test: []string{"CMD", "wget", "--no-verbose", "--tries=1", "--spider",
+						"http://127.0.0.1:9001/health",
+					},
 					Interval: 10 * time.Second,
 					Timeout:  2 * time.Second,
 					Retries:  3,
@@ -198,7 +212,7 @@ EOF
 		); err != nil {
 			return err
 		}
-		if err := reset.WaitForServiceReady(ctx, []string{utils.VectorId}); err != nil {
+		if err := start.WaitForHealthyService(ctx, serviceTimeout, utils.VectorId); err != nil {
 			return err
 		}
 	}
@@ -267,7 +281,9 @@ EOF
 EOF
 `},
 				Healthcheck: &container.HealthConfig{
-					Test:        []string{"CMD", "curl", "-sSfL", "--head", "-o", "/dev/null", "http://127.0.0.1:4000/health"},
+					Test: []string{"CMD", "curl", "-sSfL", "--head", "-o", "/dev/null",
+						"http://127.0.0.1:4000/health",
+					},
 					Interval:    10 * time.Second,
 					Timeout:     2 * time.Second,
 					Retries:     3,
@@ -291,7 +307,7 @@ EOF
 		); err != nil {
 			return err
 		}
-		if err := reset.WaitForServiceReady(ctx, []string{utils.LogflareId}); err != nil {
+		if err := start.WaitForHealthyService(ctx, serviceTimeout, utils.LogflareId); err != nil {
 			return err
 		}
 	}
@@ -328,7 +344,7 @@ EOF
 				}
 			}
 			dockerPath := path.Join(nginxEmailTemplateDir, id+filepath.Ext(hostPath))
-			binds = append(binds, fmt.Sprintf("%s:%s:rw,z", hostPath, dockerPath))
+			binds = append(binds, fmt.Sprintf("%s:%s:rw", hostPath, dockerPath))
 		}
 
 		if _, err := utils.DockerStart(
@@ -570,7 +586,9 @@ EOF
 				Env:          env,
 				ExposedPorts: nat.PortSet{"9999/tcp": {}},
 				Healthcheck: &container.HealthConfig{
-					Test:     []string{"CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9999/health"},
+					Test: []string{"CMD", "wget", "--no-verbose", "--tries=1", "--spider",
+						"http://127.0.0.1:9999/health",
+					},
 					Interval: 10 * time.Second,
 					Timeout:  2 * time.Second,
 					Retries:  3,
@@ -632,11 +650,11 @@ EOF
 	}
 
 	// Start Realtime.
-	if utils.Config.Realtime.Enabled && !isContainerExcluded(utils.RealtimeImage, excluded) {
+	if utils.Config.Realtime.Enabled && !isContainerExcluded(utils.Config.Realtime.Image, excluded) {
 		if _, err := utils.DockerStart(
 			ctx,
 			container.Config{
-				Image: utils.RealtimeImage,
+				Image: utils.Config.Realtime.Image,
 				Env: []string{
 					"PORT=4000",
 					"DB_HOST=" + dbConfig.Host,
@@ -663,8 +681,10 @@ EOF
 				},
 				ExposedPorts: nat.PortSet{"4000/tcp": {}},
 				Healthcheck: &container.HealthConfig{
-					Test: []string{"CMD", "curl", "-sSfL", "--head", "-o", "/dev/null", "-H", "Authorization: Bearer " + utils.Config.Auth.AnonKey,
-						fmt.Sprintf("http://127.0.0.1:4000/api/tenants/%s/health", utils.Config.Realtime.TenantId),
+					// Podman splits command by spaces unless it's quoted, but curl header can't be quoted.
+					Test: []string{"CMD", "curl", "-sSfL", "--head", "-o", "/dev/null",
+						"-H", "Host:" + utils.Config.Realtime.TenantId,
+						"http://127.0.0.1:4000/api/ping",
 					},
 					Interval: 10 * time.Second,
 					Timeout:  2 * time.Second,
@@ -752,8 +772,10 @@ EOF
 					"UPLOAD_FILE_SIZE_LIMIT_STANDARD=5242880000",
 				},
 				Healthcheck: &container.HealthConfig{
-					// For some reason, 127.0.0.1 resolves to IPv6 address on GitPod which breaks healthcheck.
-					Test:     []string{"CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:5000/status"},
+					// For some reason, localhost resolves to IPv6 address on GitPod which breaks healthcheck.
+					Test: []string{"CMD", "wget", "--no-verbose", "--tries=1", "--spider",
+						"http://127.0.0.1:5000/status",
+					},
 					Interval: 10 * time.Second,
 					Timeout:  2 * time.Second,
 					Retries:  3,
@@ -835,9 +857,10 @@ EOF
 					"PG_META_DB_USER=" + dbConfig.User,
 					fmt.Sprintf("PG_META_DB_PORT=%d", dbConfig.Port),
 					"PG_META_DB_PASSWORD=" + dbConfig.Password,
+					"AUTH_JWT_SECRET=" + utils.Config.Auth.JwtSecret,
 				},
 				Healthcheck: &container.HealthConfig{
-					Test:     []string{"CMD", "node", "-e", "fetch('http://127.0.0.1:8080/health').then((r) => {if (r.status !== 200) throw new Error(r.status)})"},
+					Test:     []string{"CMD", "node", `--eval='fetch("http://127.0.0.1:8080/health").then((r) => {if (r.status !== 200) throw new Error(r.status)})'`},
 					Interval: 10 * time.Second,
 					Timeout:  2 * time.Second,
 					Retries:  3,
@@ -882,7 +905,7 @@ EOF
 					"HOSTNAME=0.0.0.0",
 				},
 				Healthcheck: &container.HealthConfig{
-					Test:     []string{"CMD", "node", "-e", "fetch('http://127.0.0.1:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"},
+					Test:     []string{"CMD", "node", `--eval='fetch("http://127.0.0.1:3000/api/profile", (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})'`},
 					Interval: 10 * time.Second,
 					Timeout:  2 * time.Second,
 					Retries:  3,
@@ -907,34 +930,64 @@ EOF
 	}
 
 	// Start pooler.
-	if utils.Config.Db.Pooler.Enabled && !isContainerExcluded(utils.PgbouncerImage, excluded) {
+	if utils.Config.Db.Pooler.Enabled && !isContainerExcluded(utils.Config.Db.Pooler.Image, excluded) {
+		portSession := uint16(5432)
+		portTransaction := uint16(6543)
+		dockerPort := portTransaction
+		if utils.Config.Db.Pooler.PoolMode == utils.SessionMode {
+			dockerPort = portSession
+		}
+		// Create pooler tenant
+		var poolerTenantBuf bytes.Buffer
+		if err := poolerTenantTemplate.Execute(&poolerTenantBuf, poolerTenant{
+			DbHost:            dbConfig.Host,
+			DbPort:            dbConfig.Port,
+			DbDatabase:        dbConfig.Database,
+			DbPassword:        dbConfig.Password,
+			ExternalId:        utils.Config.Db.Pooler.TenantId,
+			ModeType:          utils.Config.Db.Pooler.PoolMode,
+			DefaultMaxClients: utils.Config.Db.Pooler.MaxClientConn,
+			DefaultPoolSize:   utils.Config.Db.Pooler.DefaultPoolSize,
+		}); err != nil {
+			return errors.Errorf("failed to exec template: %w", err)
+		}
 		if _, err := utils.DockerStart(
 			ctx,
 			container.Config{
-				Image: utils.PgbouncerImage,
+				Image: utils.Config.Db.Pooler.Image,
 				Env: []string{
-					"POSTGRESQL_HOST=" + dbConfig.Host,
-					fmt.Sprintf("POSTGRESQL_PORT=%d", dbConfig.Port),
-					"POSTGRESQL_USERNAME=pgbouncer",
-					"POSTGRESQL_PASSWORD=" + dbConfig.Password,
-					"POSTGRESQL_DATABASE=" + dbConfig.Database,
-					"PGBOUNCER_AUTH_USER=pgbouncer",
-					"PGBOUNCER_AUTH_QUERY=SELECT * FROM pgbouncer.get_auth($1)",
-					fmt.Sprintf("PGBOUNCER_POOL_MODE=%s", utils.Config.Db.Pooler.PoolMode),
-					fmt.Sprintf("PGBOUNCER_DEFAULT_POOL_SIZE=%d", utils.Config.Db.Pooler.DefaultPoolSize),
-					fmt.Sprintf("PGBOUNCER_MAX_CLIENT_CONN=%d", utils.Config.Db.Pooler.MaxClientConn),
-					// Default platform config: https://github.com/supabase/postgres/blob/develop/ansible/files/pgbouncer_config/pgbouncer.ini.j2
-					"PGBOUNCER_IGNORE_STARTUP_PARAMETERS=extra_float_digits",
+					"PORT=4000",
+					fmt.Sprintf("PROXY_PORT_SESSION=%d", portSession),
+					fmt.Sprintf("PROXY_PORT_TRANSACTION=%d", portTransaction),
+					fmt.Sprintf("DATABASE_URL=ecto://%s:%s@%s:%d/%s", dbConfig.User, dbConfig.Password, dbConfig.Host, dbConfig.Port, dbConfig.Database),
+					"CLUSTER_POSTGRES=true",
+					"SECRET_KEY_BASE=" + utils.Config.Db.Pooler.SecretKeyBase,
+					"VAULT_ENC_KEY=" + utils.Config.Db.Pooler.EncryptionKey,
+					"API_JWT_SECRET=" + utils.Config.Auth.JwtSecret,
+					"METRICS_JWT_SECRET=" + utils.Config.Auth.JwtSecret,
+					"REGION=local",
+					"ERL_AFLAGS=-proto_dist inet_tcp",
+				},
+				Cmd: []string{
+					"/bin/sh", "-c",
+					fmt.Sprintf("/app/bin/migrate && /app/bin/supavisor eval '%s' && /app/bin/server", poolerTenantBuf.String()),
+				},
+				ExposedPorts: nat.PortSet{
+					"4000/tcp": {},
+					nat.Port(fmt.Sprintf("%d/tcp", portSession)):     {},
+					nat.Port(fmt.Sprintf("%d/tcp", portTransaction)): {},
 				},
 				Healthcheck: &container.HealthConfig{
-					Test:     []string{"CMD", "bash", "-c", "printf \\0 > /dev/tcp/127.0.0.1/6432"},
+					Test:     []string{"CMD", "curl", "-sSfL", "--head", "-o", "/dev/null", "http://127.0.0.1:4000/api/health"},
 					Interval: 10 * time.Second,
 					Timeout:  2 * time.Second,
 					Retries:  3,
 				},
 			},
 			container.HostConfig{
-				PortBindings:  nat.PortMap{"6432/tcp": []nat.PortBinding{{HostPort: strconv.FormatUint(uint64(utils.Config.Db.Pooler.Port), 10)}}},
+				PortBindings: nat.PortMap{nat.Port(fmt.Sprintf("%d/tcp", dockerPort)): []nat.PortBinding{{
+					HostPort: strconv.FormatUint(uint64(utils.Config.Db.Pooler.Port), 10)},
+				}},
 				RestartPolicy: container.RestartPolicy{Name: "always"},
 			},
 			network.NetworkingConfig{
@@ -952,7 +1005,7 @@ EOF
 	}
 
 	p.Send(utils.StatusMsg("Waiting for health checks..."))
-	return reset.WaitForServiceReady(ctx, started)
+	return start.WaitForHealthyService(ctx, serviceTimeout, started...)
 }
 
 func isContainerExcluded(imageName string, excluded map[string]bool) bool {
diff --git a/internal/start/templates/pooler.exs b/internal/start/templates/pooler.exs
new file mode 100644
index 00000000..0178fa22
--- /dev/null
+++ b/internal/start/templates/pooler.exs
@@ -0,0 +1,28 @@
+Application.ensure_all_started(:supavisor)
+
+{:ok, version} =
+  case Supavisor.Repo.query!("select version()") do
+    %{rows: [[ver]]} -> Supavisor.Helpers.parse_pg_version(ver)
+    _ -> nil
+  end
+
+params = %{
+  "external_id" => "{{ .ExternalId }}",
+  "db_host" => "{{ .DbHost }}",
+  "db_port" => {{ .DbPort }},
+  "db_database" => "{{ .DbDatabase }}",
+  "require_user" => false,
+  "auth_query" => "SELECT * FROM pgbouncer.get_auth($1)",
+  "default_max_clients" => {{ .DefaultMaxClients }},
+  "default_pool_size" => {{ .DefaultPoolSize }},
+  "default_parameter_status" => %{"server_version" => version},
+  "users" => [%{
+    "db_user" => "pgbouncer",
+    "db_password" => "{{ .DbPassword }}",
+    "mode_type" => "{{ .ModeType }}",
+    "pool_size" => {{ .DefaultPoolSize }},
+    "is_manager" => true
+  }]
+}
+
+{:ok, _} = Supavisor.Tenants.create_tenant(params)
diff --git a/internal/status/status.go b/internal/status/status.go
index 3d90e309..1bf4ba94 100644
--- a/internal/status/status.go
+++ b/internal/status/status.go
@@ -8,11 +8,14 @@ import (
 	"net/url"
 	"os"
 	"reflect"
+	"sync"
+	"time"
 
-	"github.com/docker/docker/client"
+	"github.com/docker/docker/api/types/container"
 	"github.com/go-errors/errors"
 	"github.com/spf13/afero"
 	"github.com/supabase/cli/internal/utils"
+	"github.com/supabase/cli/pkg/fetcher"
 )
 
 type CustomName struct {
@@ -60,28 +63,17 @@ func (c *CustomName) toValues(exclude ...string) map[string]string {
 
 func Run(ctx context.Context, names CustomName, format string, fsys afero.Fs) error {
 	// Sanity checks.
-	{
-		if err := utils.LoadConfigFS(fsys); err != nil {
-			return err
-		}
-		if err := AssertContainerHealthy(ctx, utils.DbId); err != nil {
-			return err
-		}
+	if err := utils.LoadConfigFS(fsys); err != nil {
+		return err
+	}
+	if err := assertContainerHealthy(ctx, utils.DbId); err != nil {
+		return err
 	}
 
-	services := []string{
-		utils.KongId,
-		utils.GotrueId,
-		utils.InbucketId,
-		utils.RealtimeId,
-		utils.RestId,
-		utils.StorageId,
-		utils.ImgProxyId,
-		utils.PgmetaId,
-		utils.StudioId,
-		utils.LogflareId,
-	}
-	stopped := checkServiceHealth(ctx, services, os.Stderr)
+	stopped, err := checkServiceHealth(ctx)
+	if err != nil {
+		return err
+	}
 	if len(stopped) > 0 {
 		fmt.Fprintln(os.Stderr, "Stopped services:", stopped)
 	}
@@ -93,23 +85,31 @@ func Run(ctx context.Context, names CustomName, format string, fsys afero.Fs) er
 	return printStatus(names, format, os.Stdout, stopped...)
 }
 
-func checkServiceHealth(ctx context.Context, services []string, w io.Writer) (stopped []string) {
-	for _, name := range services {
-		if err := AssertContainerHealthy(ctx, name); err != nil {
-			if client.IsErrNotFound(err) {
-				stopped = append(stopped, name)
-			} else {
-				// Log unhealthy containers instead of failing
-				fmt.Fprintln(w, err)
-			}
+func checkServiceHealth(ctx context.Context) ([]string, error) {
+	resp, err := utils.Docker.ContainerList(ctx, container.ListOptions{
+		Filters: utils.CliProjectFilter(),
+	})
+	if err != nil {
+		return nil, errors.Errorf("failed to list running containers: %w", err)
+	}
+	running := make(map[string]struct{}, len(resp))
+	for _, c := range resp {
+		for _, n := range c.Names {
+			running[n] = struct{}{}
 		}
 	}
-	return stopped
+	var stopped []string
+	for _, n := range utils.GetDockerIds() {
+		if _, ok := running[n]; !ok {
+			stopped = append(stopped, n)
+		}
+	}
+	return stopped, nil
 }
 
-func AssertContainerHealthy(ctx context.Context, container string) error {
+func assertContainerHealthy(ctx context.Context, container string) error {
 	if resp, err := utils.Docker.ContainerInspect(ctx, container); err != nil {
-		return err
+		return errors.Errorf("failed to inspect container health: %w", err)
 	} else if !resp.State.Running {
 		return errors.Errorf("%s container is not running: %s", container, resp.State.Status)
 	} else if resp.State.Health != nil && resp.State.Health.Status != "healthy" {
@@ -118,36 +118,42 @@ func AssertContainerHealthy(ctx context.Context, container string) error {
 	return nil
 }
 
-func IsServiceReady(ctx context.Context, container string) bool {
+func IsServiceReady(ctx context.Context, container string) error {
 	if container == utils.RestId {
-		return isPostgRESTHealthy(ctx)
+		// PostgREST does not support native health checks
+		return checkHTTPHead(ctx, "/rest-admin/v1/ready")
 	}
 	if container == utils.EdgeRuntimeId {
-		return isEdgeRuntimeHealthy(ctx)
+		// Native health check logs too much hyper::Error(IncompleteMessage)
+		return checkHTTPHead(ctx, "/functions/v1/_internal/health")
 	}
-	return AssertContainerHealthy(ctx, container) == nil
+	return assertContainerHealthy(ctx, container)
 }
 
-func isPostgRESTHealthy(ctx context.Context) bool {
-	// PostgREST does not support native health checks
-	restUrl := fmt.Sprintf("http://%s:%d/rest-admin/v1/ready", utils.Config.Hostname, utils.Config.Api.Port)
-	return checkHTTPHead(ctx, restUrl)
-}
-
-func isEdgeRuntimeHealthy(ctx context.Context) bool {
-	// Native health check logs too much hyper::Error(IncompleteMessage)
-	restUrl := fmt.Sprintf("http://%s:%d/functions/v1/_internal/health", utils.Config.Hostname, utils.Config.Api.Port)
-	return checkHTTPHead(ctx, restUrl)
-}
+var (
+	healthClient *fetcher.Fetcher
+	healthOnce   sync.Once
+)
 
-func checkHTTPHead(ctx context.Context, url string) bool {
-	req, err := http.NewRequestWithContext(ctx, http.MethodHead, url, nil)
-	if err != nil {
-		return false
-	}
-	req.Header.Add("apikey", utils.Config.Auth.AnonKey)
-	resp, err := http.DefaultClient.Do(req)
-	return err == nil && resp.StatusCode == http.StatusOK
+func checkHTTPHead(ctx context.Context, path string) error {
+	healthOnce.Do(func() {
+		server := fmt.Sprintf("http://%s:%d", utils.Config.Hostname, utils.Config.Api.Port)
+		header := func(req *http.Request) {
+			req.Header.Add("apikey", utils.Config.Auth.AnonKey)
+		}
+		client := &http.Client{
+			Timeout: 10 * time.Second,
+		}
+		healthClient = fetcher.NewFetcher(
+			server,
+			fetcher.WithHTTPClient(client),
+			fetcher.WithRequestEditor(header),
+			fetcher.WithExpectedStatus(http.StatusOK),
+		)
+	})
+	// HEAD method does not return response body
+	_, err := healthClient.Send(ctx, http.MethodHead, path, nil)
+	return err
 }
 
 func printStatus(names CustomName, format string, w io.Writer, exclude ...string) (err error) {
diff --git a/internal/stop/stop.go b/internal/stop/stop.go
index 955622ad..b4bd94c2 100644
--- a/internal/stop/stop.go
+++ b/internal/stop/stop.go
@@ -15,7 +15,6 @@ func Run(ctx context.Context, backup bool, projectId string, fsys afero.Fs) erro
 	// Sanity checks.
 	if len(projectId) > 0 {
 		utils.Config.ProjectId = projectId
-		utils.UpdateDockerIds()
 	} else if err := utils.LoadConfigFS(fsys); err != nil {
 		return err
 	}
diff --git a/internal/utils/cloudflare/api.go b/internal/utils/cloudflare/api.go
index 7ba5c2ac..7c7cf10a 100644
--- a/internal/utils/cloudflare/api.go
+++ b/internal/utils/cloudflare/api.go
@@ -23,6 +23,7 @@ func NewCloudflareAPI() CloudflareAPI {
 		server,
 		fetcher.WithHTTPClient(client),
 		fetcher.WithRequestEditor(header),
+		fetcher.WithExpectedStatus(http.StatusOK),
 	)}
 	return api
 }
diff --git a/internal/utils/cloudflare/dns.go b/internal/utils/cloudflare/dns.go
index 0f36ccce..c21e4b4f 100644
--- a/internal/utils/cloudflare/dns.go
+++ b/internal/utils/cloudflare/dns.go
@@ -141,14 +141,14 @@ type DNSParams struct {
 
 // Performs DNS lookup via HTTPS, in case firewall blocks native netgo resolver.
 // Ref: https://developers.cloudflare.com/1.1.1.1/encryption/dns-over-https/make-api-requests/dns-json
-func (c *CloudflareAPI) DNSQuery(ctx context.Context, params DNSParams) (*DNSResponse, error) {
+func (c *CloudflareAPI) DNSQuery(ctx context.Context, params DNSParams) (DNSResponse, error) {
 	values, err := query.Values(params)
 	if err != nil {
-		return nil, errors.Errorf("failed to encode query params: %w", err)
+		return DNSResponse{}, errors.Errorf("failed to encode query params: %w", err)
 	}
 	resp, err := c.Send(ctx, http.MethodGet, "/dns-query?"+values.Encode(), nil)
 	if err != nil {
-		return nil, err
+		return DNSResponse{}, err
 	}
 	defer resp.Body.Close()
 	return fetcher.ParseJSON[DNSResponse](resp.Body)
diff --git a/internal/utils/config.go b/internal/utils/config.go
index 66e82871..73da5b56 100644
--- a/internal/utils/config.go
+++ b/internal/utils/config.go
@@ -74,7 +74,9 @@ func GetId(name string) string {
 }
 
 func UpdateDockerIds() {
-	NetId = GetId("network")
+	if NetId = viper.GetString("network-id"); len(NetId) == 0 {
+		NetId = GetId("network")
+	}
 	DbId = GetId(DbAliases[0])
 	ConfigId = GetId("config")
 	KongId = GetId(KongAliases[0])
@@ -93,6 +95,24 @@ func UpdateDockerIds() {
 	PoolerId = GetId(PoolerAliases[0])
 }
 
+func GetDockerIds() []string {
+	return []string{
+		KongId,
+		GotrueId,
+		InbucketId,
+		RealtimeId,
+		RestId,
+		StorageId,
+		ImgProxyId,
+		PgmetaId,
+		StudioId,
+		EdgeRuntimeId,
+		LogflareId,
+		VectorId,
+		PoolerId,
+	}
+}
+
 // Type for turning human-friendly bytes string ("5MB", "32kB") into an int64 during toml decoding.
 type sizeInBytes int64
 
@@ -174,8 +194,15 @@ var Config = config{
 		Image:    Pg15Image,
 		Password: "postgres",
 		RootKey:  "d4dc5b6d4a1d6a10b2c1e76112c994d65db7cec380572cc1839624d4be3fa275",
+		Pooler: pooler{
+			Image:         SupavisorImage,
+			TenantId:      "pooler-dev",
+			EncryptionKey: "12345678901234567890123456789032",
+			SecretKeyBase: "EAx3IQ/wRG1v47ZD4NE4/9RzBI8Jmil3x0yhcW4V2NHBP6c2iPIzwjofi2Ep4HIG",
+		},
 	},
 	Realtime: realtime{
+		Image:           RealtimeImage,
 		IpVersion:       AddressIPv4,
 		MaxHeaderLength: 4096,
 		TenantId:        "realtime-dev",
@@ -298,15 +325,20 @@ type (
 
 	pooler struct {
 		Enabled          bool     `toml:"enabled"`
+		Image            string   `toml:"-"`
 		Port             uint16   `toml:"port"`
 		PoolMode         PoolMode `toml:"pool_mode"`
 		DefaultPoolSize  uint     `toml:"default_pool_size"`
 		MaxClientConn    uint     `toml:"max_client_conn"`
 		ConnectionString string   `toml:"-"`
+		TenantId         string   `toml:"-"`
+		EncryptionKey    string   `toml:"-"`
+		SecretKeyBase    string   `toml:"-"`
 	}
 
 	realtime struct {
 		Enabled         bool          `toml:"enabled"`
+		Image           string        `toml:"-"`
 		IpVersion       AddressFamily `toml:"ip_version"`
 		MaxHeaderLength uint          `toml:"max_header_length"`
 		TenantId        string        `toml:"-"`
@@ -454,8 +486,8 @@ type (
 	}
 
 	function struct {
-		VerifyJWT *bool  `toml:"verify_jwt"`
-		ImportMap string `toml:"import_map"`
+		VerifyJWT *bool  `toml:"verify_jwt" json:"verifyJWT"`
+		ImportMap string `toml:"import_map" json:"importMapPath,omitempty"`
 	}
 
 	analytics struct {
@@ -613,6 +645,9 @@ func LoadConfigFS(fsys afero.Fs) error {
 			if !SliceContains(allowed, Config.Db.Pooler.PoolMode) {
 				return errors.Errorf("Invalid config for db.pooler.pool_mode. Must be one of: %v", allowed)
 			}
+			if version, err := afero.ReadFile(fsys, PoolerVersionPath); err == nil && len(version) > 0 {
+				Config.Db.Pooler.Image = replaceImageTag(SupavisorImage, string(version))
+			}
 		}
 		if connString, err := afero.ReadFile(fsys, PoolerUrlPath); err == nil && len(connString) > 0 {
 			Config.Db.Pooler.ConnectionString = string(connString)
@@ -623,6 +658,9 @@ func LoadConfigFS(fsys afero.Fs) error {
 			if !SliceContains(allowed, Config.Realtime.IpVersion) {
 				return errors.Errorf("Invalid config for realtime.ip_version. Must be one of: %v", allowed)
 			}
+			if version, err := afero.ReadFile(fsys, RealtimeVersionPath); err == nil && len(version) > 0 {
+				Config.Realtime.Image = replaceImageTag(RealtimeImage, string(version))
+			}
 		}
 		// Validate storage config
 		if Config.Storage.Enabled {
diff --git a/internal/utils/deno.go b/internal/utils/deno.go
index b2f35b2a..8babad83 100644
--- a/internal/utils/deno.go
+++ b/internal/utils/deno.go
@@ -255,18 +255,18 @@ func (m *ImportMap) BindModules(resolved ImportMap) []string {
 	if err != nil {
 		return nil
 	}
-	var binds []string
+	binds := []string{}
 	for k, dockerPath := range resolved.Imports {
 		if strings.HasPrefix(dockerPath, DockerModsDir) {
 			hostPath := filepath.Join(cwd, FunctionsDir, m.Imports[k])
-			binds = append(binds, hostPath+":"+dockerPath+":ro,z")
+			binds = append(binds, hostPath+":"+dockerPath+":ro")
 		}
 	}
 	for module, mapping := range resolved.Scopes {
 		for k, dockerPath := range mapping {
 			if strings.HasPrefix(dockerPath, DockerModsDir) {
 				hostPath := filepath.Join(cwd, FunctionsDir, m.Scopes[module][k])
-				binds = append(binds, hostPath+":"+dockerPath+":ro,z")
+				binds = append(binds, hostPath+":"+dockerPath+":ro")
 			}
 		}
 	}
@@ -287,15 +287,15 @@ func resolveHostPath(hostPath string, fsys afero.Fs) string {
 	if !exists {
 		return hostPath
 	}
-	if strings.HasPrefix(rel, FunctionsDir) {
-		suffix := strings.TrimPrefix(rel, FunctionsDir)
-		return path.Join(DockerFuncDirPath, filepath.ToSlash(suffix))
-	}
 	// Directory imports need to be suffixed with /
 	// Ref: https://deno.com/manual@v1.33.0/basics/import_maps
 	if strings.HasSuffix(hostPath, string(filepath.Separator)) {
 		rel += string(filepath.Separator)
 	}
+	if strings.HasPrefix(rel, FunctionsDir) {
+		suffix := strings.TrimPrefix(rel, FunctionsDir)
+		return DockerFuncDirPath + filepath.ToSlash(suffix)
+	}
 	return getModulePath(rel)
 }
 
@@ -314,33 +314,39 @@ func GetPathHash(path string) string {
 	return hex.EncodeToString(digest[:])
 }
 
-func AbsImportMapPath(importMapPath, slug string, fsys afero.Fs) (string, error) {
-	if importMapPath == "" {
-		if functionConfig, ok := Config.Functions[slug]; ok && functionConfig.ImportMap != "" {
-			importMapPath = functionConfig.ImportMap
-			if !filepath.IsAbs(importMapPath) {
-				importMapPath = filepath.Join(SupabaseDirPath, importMapPath)
-			}
-		} else if exists, err := afero.Exists(fsys, FallbackImportMapPath); exists {
-			importMapPath = FallbackImportMapPath
-		} else {
-			if err != nil {
-				logger := GetDebugLogger()
-				fmt.Fprintln(logger, err)
-			}
-			return importMapPath, nil
-		}
+func GetFunctionConfig(slug, importMapPath string, noVerifyJWT *bool, fsys afero.Fs) function {
+	fc := Config.Functions[slug]
+	// Precedence order: CLI flags > config.toml > fallback value
+	if noVerifyJWT != nil {
+		value := !*noVerifyJWT
+		fc.VerifyJWT = &value
+	} else if fc.VerifyJWT == nil {
+		fc.VerifyJWT = Ptr(true)
+	}
+	fc.ImportMap = getImportMapPath(importMapPath, fc.ImportMap, fsys)
+	return fc
+}
+
+func getImportMapPath(flagImportMap, slugImportMap string, fsys afero.Fs) string {
+	// Precedence order: CLI flags > config.toml > fallback value
+	if filepath.IsAbs(flagImportMap) {
+		return flagImportMap
 	}
-	resolved, err := filepath.Abs(importMapPath)
-	if err != nil {
-		return "", err
+	if flagImportMap != "" {
+		return filepath.Join(CurrentDirAbs, flagImportMap)
+	}
+	if filepath.IsAbs(slugImportMap) {
+		return slugImportMap
+	}
+	if slugImportMap != "" {
+		return filepath.Join(SupabaseDirPath, slugImportMap)
 	}
-	if f, err := fsys.Stat(resolved); err != nil {
-		return "", errors.Errorf("Failed to read import map: %w", err)
-	} else if f.IsDir() {
-		return "", errors.New("Importing directory is unsupported: " + resolved)
+	if exists, err := afero.Exists(fsys, FallbackImportMapPath); err != nil {
+		fmt.Fprintln(GetDebugLogger(), "failed to fallback import map:", err)
+	} else if exists {
+		return FallbackImportMapPath
 	}
-	return resolved, nil
+	return ""
 }
 
 func AbsTempImportMapPath(cwd, hostPath string) string {
@@ -370,6 +376,6 @@ func BindImportMap(hostImportMapPath, dockerImportMapPath string, fsys afero.Fs)
 			return nil, err
 		}
 	}
-	binds = append(binds, hostImportMapPath+":"+dockerImportMapPath+":ro,z")
+	binds = append(binds, hostImportMapPath+":"+dockerImportMapPath+":ro")
 	return binds, nil
 }
diff --git a/internal/utils/docker.go b/internal/utils/docker.go
index 5cb397bd..ee3e35f0 100644
--- a/internal/utils/docker.go
+++ b/internal/utils/docker.go
@@ -54,18 +54,15 @@ const (
 	composeProjectLabel = "com.docker.compose.project"
 )
 
-func DockerNetworkCreateIfNotExists(ctx context.Context, networkId string) error {
-	_, err := Docker.NetworkCreate(
-		ctx,
-		networkId,
-		types.NetworkCreate{
-			CheckDuplicate: true,
-			Labels: map[string]string{
-				CliProjectLabel:     Config.ProjectId,
-				composeProjectLabel: Config.ProjectId,
-			},
-		},
-	)
+func DockerNetworkCreateIfNotExists(ctx context.Context, mode container.NetworkMode, labels map[string]string) error {
+	// Non-user defined networks should already exist
+	if !isUserDefined(mode) {
+		return nil
+	}
+	_, err := Docker.NetworkCreate(ctx, mode.NetworkName(), types.NetworkCreate{
+		CheckDuplicate: true,
+		Labels:         labels,
+	})
 	// if error is network already exists, no need to propagate to user
 	if errdefs.IsConflict(err) || errors.Is(err, podman.ErrNetworkExists) {
 		return nil
@@ -94,6 +91,7 @@ func WaitAll[T any](containers []T, exec func(container T) error) []error {
 var NoBackupVolume = false
 
 func DockerRemoveAll(ctx context.Context, w io.Writer) error {
+	fmt.Fprintln(w, "Stopping containers...")
 	args := CliProjectFilter()
 	containers, err := Docker.ContainerList(ctx, container.ListOptions{
 		All:     true,
@@ -109,7 +107,6 @@ func DockerRemoveAll(ctx context.Context, w io.Writer) error {
 			ids = append(ids, c.ID)
 		}
 	}
-	fmt.Fprintln(w, "Stopping containers...")
 	result := WaitAll(ids, func(id string) error {
 		if err := Docker.ContainerStop(ctx, id, container.StopOptions{}); err != nil {
 			return errors.Errorf("failed to stop container: %w", err)
@@ -253,19 +250,21 @@ func DockerStart(ctx context.Context, config container.Config, hostConfig contai
 	// Setup default config
 	config.Image = GetRegistryImageUrl(config.Image)
 	if config.Labels == nil {
-		config.Labels = map[string]string{}
+		config.Labels = make(map[string]string, 2)
 	}
 	config.Labels[CliProjectLabel] = Config.ProjectId
 	config.Labels[composeProjectLabel] = Config.ProjectId
-	if len(hostConfig.NetworkMode) == 0 {
+	// Configure container network
+	hostConfig.ExtraHosts = append(hostConfig.ExtraHosts, extraHosts...)
+	if networkId := viper.GetString("network-id"); len(networkId) > 0 {
+		hostConfig.NetworkMode = container.NetworkMode(networkId)
+	} else if len(hostConfig.NetworkMode) == 0 {
 		hostConfig.NetworkMode = container.NetworkMode(NetId)
 	}
-	// Create network with name
-	if hostConfig.NetworkMode.IsUserDefined() && hostConfig.NetworkMode.UserDefined() != "host" {
-		if err := DockerNetworkCreateIfNotExists(ctx, hostConfig.NetworkMode.NetworkName()); err != nil {
-			return "", err
-		}
+	if err := DockerNetworkCreateIfNotExists(ctx, hostConfig.NetworkMode, config.Labels); err != nil {
+		return "", err
 	}
+	// Configure container volumes
 	var binds, sources []string
 	for _, bind := range hostConfig.Binds {
 		spec, err := loader.ParseVolume(bind)
@@ -382,6 +381,21 @@ func DockerStreamLogs(ctx context.Context, containerId string, stdout, stderr io
 	return nil
 }
 
+func DockerStreamLogsOnce(ctx context.Context, containerId string, stdout, stderr io.Writer) error {
+	logs, err := Docker.ContainerLogs(ctx, containerId, container.LogsOptions{
+		ShowStdout: true,
+		ShowStderr: true,
+	})
+	if err != nil {
+		return errors.Errorf("failed to read docker logs: %w", err)
+	}
+	defer logs.Close()
+	if _, err := stdcopy.StdCopy(stdout, stderr, logs); err != nil {
+		return errors.Errorf("failed to copy docker logs: %w", err)
+	}
+	return nil
+}
+
 // Exec a command once inside a container, returning stdout and throwing error on non-zero exit code.
 func DockerExecOnce(ctx context.Context, container string, env []string, cmd []string) (string, error) {
 	stderr := io.Discard
diff --git a/internal/utils/docker_darwin.go b/internal/utils/docker_darwin.go
new file mode 100644
index 00000000..af183bc3
--- /dev/null
+++ b/internal/utils/docker_darwin.go
@@ -0,0 +1,11 @@
+//go:build darwin
+
+package utils
+
+import "github.com/docker/docker/api/types/container"
+
+var extraHosts []string
+
+func isUserDefined(mode container.NetworkMode) bool {
+	return mode.IsUserDefined()
+}
diff --git a/internal/utils/docker_linux.go b/internal/utils/docker_linux.go
new file mode 100644
index 00000000..392fec4e
--- /dev/null
+++ b/internal/utils/docker_linux.go
@@ -0,0 +1,12 @@
+//go:build linux
+
+package utils
+
+import "github.com/docker/docker/api/types/container"
+
+// Allows containers to resolve host network: https://stackoverflow.com/a/62431165
+var extraHosts = []string{"host.docker.internal:host-gateway"}
+
+func isUserDefined(mode container.NetworkMode) bool {
+	return mode.IsUserDefined()
+}
diff --git a/internal/utils/docker_windows.go b/internal/utils/docker_windows.go
new file mode 100644
index 00000000..99e68d9b
--- /dev/null
+++ b/internal/utils/docker_windows.go
@@ -0,0 +1,15 @@
+//go:build windows
+
+package utils
+
+import (
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/network"
+)
+
+var extraHosts []string
+
+func isUserDefined(mode container.NetworkMode) bool {
+	// Host network requires explicit check on windows: https://github.com/supabase/cli/pull/952
+	return mode.IsUserDefined() && mode.UserDefined() != network.NetworkHost
+}
diff --git a/internal/utils/enum.go b/internal/utils/enum.go
index 426c45cb..6d800d6a 100644
--- a/internal/utils/enum.go
+++ b/internal/utils/enum.go
@@ -18,15 +18,7 @@ func (a EnumFlag) String() string {
 }
 
 func (a *EnumFlag) Set(p string) error {
-	isIncluded := func(opts []string, val string) bool {
-		for _, opt := range opts {
-			if val == opt {
-				return true
-			}
-		}
-		return false
-	}
-	if !isIncluded(a.Allowed, p) {
+	if !SliceContains(a.Allowed, p) {
 		return errors.Errorf("must be one of [ %s ]", strings.Join(a.Allowed, " | "))
 	}
 	a.Value = p
diff --git a/internal/utils/misc.go b/internal/utils/misc.go
index f8a2aa8e..397122d8 100644
--- a/internal/utils/misc.go
+++ b/internal/utils/misc.go
@@ -36,9 +36,9 @@ const (
 	PgmetaImage      = "supabase/postgres-meta:v0.80.0"
 	StudioImage      = "supabase/studio:20240422-5cf8f30"
 	ImageProxyImage  = "darthsim/imgproxy:v3.8.0"
-	EdgeRuntimeImage = "supabase/edge-runtime:v1.53.3"
+	EdgeRuntimeImage = "supabase/edge-runtime:v1.53.4"
 	VectorImage      = "timberio/vector:0.28.1-alpine"
-	PgbouncerImage   = "bitnami/pgbouncer:1.20.1-debian-11-r39"
+	SupavisorImage   = "supabase/supavisor:1.1.56"
 	PgProveImage     = "supabase/pg_prove:3.36"
 	GotrueImage      = "supabase/gotrue:v2.151.0"
 	RealtimeImage    = "supabase/realtime:v2.28.32"
@@ -61,7 +61,7 @@ var ServiceImages = []string{
 	EdgeRuntimeImage,
 	LogflareImage,
 	VectorImage,
-	PgbouncerImage,
+	SupavisorImage,
 }
 
 var JobImages = []string{
@@ -118,6 +118,7 @@ var (
 	ManagedSchemas = append([]string{
 		"_analytics",
 		"_realtime",
+		"_supavisor",
 		"pgbouncer",
 		"pgsodium",
 		"pgtle",
@@ -125,13 +126,14 @@ var (
 		"vault",
 	}, PgSchemas...)
 	InternalSchemas = append([]string{
+		"_analytics",
+		"_realtime",
+		"_supavisor",
 		"auth",
 		"extensions",
 		"pgbouncer",
 		"realtime",
-		"_realtime",
 		"storage",
-		"_analytics",
 		"supabase_functions",
 		"supabase_migrations",
 		// Owned by extensions
@@ -194,6 +196,8 @@ var (
 	StorageVersionPath    = filepath.Join(TempDir, "storage-version")
 	StudioVersionPath     = filepath.Join(TempDir, "studio-version")
 	PgmetaVersionPath     = filepath.Join(TempDir, "pgmeta-version")
+	PoolerVersionPath     = filepath.Join(TempDir, "pooler-version")
+	RealtimeVersionPath   = filepath.Join(TempDir, "realtime-version")
 	CliVersionPath        = filepath.Join(TempDir, "cli-latest")
 	CurrBranchPath        = filepath.Join(SupabaseDirPath, ".branches", "_current_branch")
 	SchemasDir            = filepath.Join(SupabaseDirPath, "schemas")
@@ -284,6 +288,9 @@ func ChangeWorkDir(fsys afero.Fs) error {
 	if err := os.Chdir(workdir); err != nil {
 		return errors.Errorf("failed to change workdir: %w", err)
 	}
+	if cwd, err := os.Getwd(); err == nil && cwd != CurrentDirAbs {
+		fmt.Fprintln(os.Stderr, "Using workdir", Bold(workdir))
+	}
 	return nil
 }
 
diff --git a/internal/utils/render.go b/internal/utils/render.go
index 6f494d9f..2d99f368 100644
--- a/internal/utils/render.go
+++ b/internal/utils/render.go
@@ -1,10 +1,28 @@
 package utils
 
-import "time"
+import (
+	"fmt"
+	"time"
+)
+
+const (
+	layoutVersion = "20060102150405"
+	layoutHuman   = "2006-01-02 15:04:05"
+)
 
 func FormatTimestamp(timestamp string) string {
-	if t, err := time.Parse(time.RFC3339, timestamp); err == nil {
-		return t.UTC().Format("2006-01-02 15:04:05")
+	return parse(time.RFC3339, timestamp)
+}
+
+func FormatTimestampVersion(timestamp string) string {
+	return parse(layoutVersion, timestamp)
+}
+
+func parse(layout, value string) string {
+	t, err := time.Parse(layout, value)
+	if err != nil {
+		fmt.Fprintln(GetDebugLogger(), err)
+		return value
 	}
-	return timestamp
+	return t.UTC().Format(layoutHuman)
 }
diff --git a/internal/utils/tenant/client.go b/internal/utils/tenant/client.go
index 4d46f12b..9fc86a67 100644
--- a/internal/utils/tenant/client.go
+++ b/internal/utils/tenant/client.go
@@ -70,6 +70,7 @@ func NewTenantAPI(ctx context.Context, projectRef, anonKey string) TenantAPI {
 		fetcher.WithHTTPClient(client),
 		fetcher.WithRequestEditor(header),
 		fetcher.WithUserAgent("SupabaseCLI/"+utils.Version),
+		fetcher.WithExpectedStatus(http.StatusOK),
 	)}
 	return api
 }
diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go
index 1ebdbb4b..6f2147c6 100644
--- a/pkg/api/client.gen.go
+++ b/pkg/api/client.gen.go
@@ -1,6 +1,6 @@
 // Package api provides primitives to interact with the openapi HTTP API.
 //
-// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.1.0 DO NOT EDIT.
+// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT.
 package api
 
 import (
diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go
index 059da1a0..1a225394 100644
--- a/pkg/api/types.gen.go
+++ b/pkg/api/types.gen.go
@@ -1,6 +1,6 @@
 // Package api provides primitives to interact with the openapi HTTP API.
 //
-// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.1.0 DO NOT EDIT.
+// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT.
 package api
 
 import (
diff --git a/pkg/fetcher/http.go b/pkg/fetcher/http.go
index 57b7be26..49e6fca3 100644
--- a/pkg/fetcher/http.go
+++ b/pkg/fetcher/http.go
@@ -14,6 +14,7 @@ type Fetcher struct {
 	server  string
 	client  *http.Client
 	editors []RequestEditor
+	status  []int
 }
 
 type FetcherOption func(*Fetcher)
@@ -35,6 +36,12 @@ func WithHTTPClient(client *http.Client) FetcherOption {
 	}
 }
 
+func WithExpectedStatus(statusCode ...int) FetcherOption {
+	return func(s *Fetcher) {
+		s.status = statusCode
+	}
+}
+
 func WithBearerToken(token string) FetcherOption {
 	addHeader := func(req *http.Request) {
 		req.Header.Add("Authorization", "Bearer "+token)
@@ -86,22 +93,28 @@ func (s *Fetcher) Send(ctx context.Context, method, path string, reqBody any, re
 	if err != nil {
 		return nil, errors.Errorf("failed to execute http request: %w", err)
 	}
-	if resp.StatusCode >= http.StatusBadRequest {
+	for _, expected := range s.status {
+		if resp.StatusCode == expected {
+			return resp, nil
+		}
+	}
+	// Reject unexpected status codes as error
+	if len(s.status) > 0 || resp.StatusCode >= http.StatusBadRequest {
 		defer resp.Body.Close()
 		data, err := io.ReadAll(resp.Body)
 		if err != nil {
-			return nil, errors.Errorf("Error status %d: %w", resp.StatusCode, err)
+			return resp, errors.Errorf("Error status %d: %w", resp.StatusCode, err)
 		}
-		return nil, errors.Errorf("Error status %d: %s", resp.StatusCode, data)
+		return resp, errors.Errorf("Error status %d: %s", resp.StatusCode, data)
 	}
 	return resp, nil
 }
 
-func ParseJSON[T any](r io.Reader) (*T, error) {
+func ParseJSON[T any](r io.Reader) (T, error) {
 	var data T
 	dec := json.NewDecoder(r)
 	if err := dec.Decode(&data); err != nil {
-		return nil, errors.Errorf("failed to parse response body: %w", err)
+		return data, errors.Errorf("failed to parse response body: %w", err)
 	}
-	return &data, nil
+	return data, nil
 }
diff --git a/pkg/storage/buckets.go b/pkg/storage/buckets.go
index 05a42ef4..c4633a34 100644
--- a/pkg/storage/buckets.go
+++ b/pkg/storage/buckets.go
@@ -24,11 +24,7 @@ func (s *StorageAPI) ListBuckets(ctx context.Context) ([]BucketResponse, error)
 		return nil, err
 	}
 	defer resp.Body.Close()
-	data, err := fetcher.ParseJSON[[]BucketResponse](resp.Body)
-	if err != nil {
-		return nil, err
-	}
-	return *data, nil
+	return fetcher.ParseJSON[[]BucketResponse](resp.Body)
 }
 
 type CreateBucketRequest struct {
@@ -43,11 +39,11 @@ type CreateBucketResponse struct {
 	Name string `json:"name"`
 }
 
-func (s *StorageAPI) CreateBucket(ctx context.Context, bucketName string) (*CreateBucketResponse, error) {
+func (s *StorageAPI) CreateBucket(ctx context.Context, bucketName string) (CreateBucketResponse, error) {
 	body := CreateBucketRequest{Name: bucketName}
 	resp, err := s.Send(ctx, http.MethodPost, "/storage/v1/bucket", body)
 	if err != nil {
-		return nil, err
+		return CreateBucketResponse{}, err
 	}
 	defer resp.Body.Close()
 	return fetcher.ParseJSON[CreateBucketResponse](resp.Body)
@@ -57,10 +53,10 @@ type DeleteBucketResponse struct {
 	Message string `json:"message"`
 }
 
-func (s *StorageAPI) DeleteBucket(ctx context.Context, bucketId string) (*DeleteBucketResponse, error) {
+func (s *StorageAPI) DeleteBucket(ctx context.Context, bucketId string) (DeleteBucketResponse, error) {
 	resp, err := s.Send(ctx, http.MethodDelete, "/storage/v1/bucket/"+bucketId, nil)
 	if err != nil {
-		return nil, err
+		return DeleteBucketResponse{}, err
 	}
 	defer resp.Body.Close()
 	return fetcher.ParseJSON[DeleteBucketResponse](resp.Body)
diff --git a/pkg/storage/objects.go b/pkg/storage/objects.go
index 7fa542de..7f417178 100644
--- a/pkg/storage/objects.go
+++ b/pkg/storage/objects.go
@@ -51,11 +51,7 @@ func (s *StorageAPI) ListObjects(ctx context.Context, bucket, prefix string, pag
 		return nil, err
 	}
 	defer resp.Body.Close()
-	data, err := fetcher.ParseJSON[[]ObjectResponse](resp.Body)
-	if err != nil {
-		return nil, err
-	}
-	return *data, nil
+	return fetcher.ParseJSON[[]ObjectResponse](resp.Body)
 }
 
 type FileOptions struct {
@@ -134,7 +130,7 @@ type MoveObjectRequest struct {
 
 type MoveObjectResponse = DeleteBucketResponse
 
-func (s *StorageAPI) MoveObject(ctx context.Context, bucketId, srcPath, dstPath string) (*MoveObjectResponse, error) {
+func (s *StorageAPI) MoveObject(ctx context.Context, bucketId, srcPath, dstPath string) (MoveObjectResponse, error) {
 	body := MoveObjectRequest{
 		BucketId:       bucketId,
 		SourceKey:      srcPath,
@@ -142,7 +138,7 @@ func (s *StorageAPI) MoveObject(ctx context.Context, bucketId, srcPath, dstPath
 	}
 	resp, err := s.Send(ctx, http.MethodPost, "/storage/v1/object/move", body)
 	if err != nil {
-		return nil, err
+		return MoveObjectResponse{}, err
 	}
 	defer resp.Body.Close()
 	return fetcher.ParseJSON[MoveObjectResponse](resp.Body)
@@ -154,7 +150,7 @@ type CopyObjectResponse struct {
 	Key string `json:"key"`
 }
 
-func (s *StorageAPI) CopyObject(ctx context.Context, bucketId, srcPath, dstPath string) (*CopyObjectResponse, error) {
+func (s *StorageAPI) CopyObject(ctx context.Context, bucketId, srcPath, dstPath string) (CopyObjectResponse, error) {
 	body := CopyObjectRequest{
 		BucketId:       bucketId,
 		SourceKey:      srcPath,
@@ -162,7 +158,7 @@ func (s *StorageAPI) CopyObject(ctx context.Context, bucketId, srcPath, dstPath
 	}
 	resp, err := s.Send(ctx, http.MethodPost, "/storage/v1/object/copy", body)
 	if err != nil {
-		return nil, err
+		return CopyObjectResponse{}, err
 	}
 	defer resp.Body.Close()
 	return fetcher.ParseJSON[CopyObjectResponse](resp.Body)
@@ -192,9 +188,5 @@ func (s *StorageAPI) DeleteObjects(ctx context.Context, bucket string, prefixes
 		return nil, err
 	}
 	defer resp.Body.Close()
-	data, err := fetcher.ParseJSON[[]DeleteObjectsResponse](resp.Body)
-	if err != nil {
-		return nil, err
-	}
-	return *data, nil
+	return fetcher.ParseJSON[[]DeleteObjectsResponse](resp.Body)
 }
diff --git a/tools/publish/main.go b/tools/publish/main.go
index 9ae5197a..685ca7f2 100644
--- a/tools/publish/main.go
+++ b/tools/publish/main.go
@@ -8,7 +8,6 @@ import (
 	"encoding/base64"
 	"flag"
 	"fmt"
-	"io"
 	"log"
 	"net/http"
 	"os"
@@ -16,9 +15,9 @@ import (
 	"strings"
 	"text/template"
 
-	"github.com/go-errors/errors"
 	"github.com/google/go-github/v62/github"
 	"github.com/supabase/cli/internal/utils"
+	"github.com/supabase/cli/pkg/fetcher"
 	"github.com/supabase/cli/tools/shared"
 )
 
@@ -82,21 +81,19 @@ type PackageConfig struct {
 }
 
 func fetchConfig(ctx context.Context, version string) (PackageConfig, error) {
+	client := fetcher.NewFetcher("https://github.com", fetcher.WithExpectedStatus(http.StatusOK))
+	checkPath := fmt.Sprintf("/%s/%s/releases/download/v%[3]s/supabase_%[3]s_checksums.txt",
+		utils.CLI_OWNER,
+		utils.CLI_REPO,
+		version,
+	)
+	log.Println("Downloading checksum:", checkPath)
 	config := PackageConfig{Version: version}
-	url := fmt.Sprintf("https://github.com/supabase/cli/releases/download/v%[1]v/supabase_%[1]v_checksums.txt", config.Version)
-	log.Println(url)
-	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
-	if err != nil {
-		return config, err
-	}
-	resp, err := http.DefaultClient.Do(req)
+	resp, err := client.Send(ctx, http.MethodGet, checkPath, nil)
 	if err != nil {
 		return config, err
 	}
 	defer resp.Body.Close()
-	if err := checkStatus(resp, http.StatusOK); err != nil {
-		return config, err
-	}
 	// Read checksums into map: filename -> sha256
 	config.Checksum = make(map[string]string)
 	scanner := bufio.NewScanner(resp.Body)
@@ -111,17 +108,6 @@ func fetchConfig(ctx context.Context, version string) (PackageConfig, error) {
 	return config, nil
 }
 
-func checkStatus(resp *http.Response, status int) error {
-	if resp.StatusCode == status {
-		return nil
-	}
-	data, err := io.ReadAll(resp.Body)
-	if err != nil {
-		return errors.Errorf("status %d: %w", resp.StatusCode, err)
-	}
-	return errors.Errorf("status %d: %s", resp.StatusCode, string(data))
-}
-
 func updatePackage(ctx context.Context, client *github.Client, repo, path string, tmpl *template.Template, config PackageConfig) error {
 	fmt.Fprintf(os.Stderr, "Updating %s: %s\n", repo, path)
 	// Render formula from template


Test patch:
diff --git a/internal/db/diff/diff_test.go b/internal/db/diff/diff_test.go
index 6eb1a609..edae9ca0 100644
--- a/internal/db/diff/diff_test.go
+++ b/internal/db/diff/diff_test.go
@@ -37,6 +37,7 @@ var dbConfig = pgconn.Config{
 var escapedSchemas = []string{
 	`\_analytics`,
 	`\_realtime`,
+	`\_supavisor`,
 	"pgbouncer",
 	"pgsodium",
 	"pgtle",
@@ -245,6 +246,15 @@ func TestDiffDatabase(t *testing.T) {
 		apitest.MockDockerStart(utils.Docker, utils.GetRegistryImageUrl(utils.Pg14Image), "test-shadow-db")
 		gock.New(utils.Docker.DaemonHost()).
 			Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json").
+			Reply(http.StatusOK).
+			JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{
+				State: &types.ContainerState{
+					Running: false,
+					Status:  "exited",
+				},
+			}})
+		gock.New(utils.Docker.DaemonHost()).
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/logs").
 			Reply(http.StatusServiceUnavailable)
 		gock.New(utils.Docker.DaemonHost()).
 			Delete("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db").
@@ -253,7 +263,7 @@ func TestDiffDatabase(t *testing.T) {
 		diff, err := DiffDatabase(context.Background(), []string{"public"}, dbConfig, io.Discard, fsys, DiffSchemaMigra)
 		// Check error
 		assert.Empty(t, diff)
-		assert.ErrorIs(t, err, start.ErrDatabase)
+		assert.ErrorContains(t, err, "test-shadow-db container is not running: exited")
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 
diff --git a/internal/db/pull/pull_test.go b/internal/db/pull/pull_test.go
index 98fb5efb..37c1ee8f 100644
--- a/internal/db/pull/pull_test.go
+++ b/internal/db/pull/pull_test.go
@@ -32,6 +32,7 @@ var dbConfig = pgconn.Config{
 var escapedSchemas = []string{
 	`\_analytics`,
 	`\_realtime`,
+	`\_supavisor`,
 	"pgbouncer",
 	"pgsodium",
 	"pgtle",
diff --git a/internal/db/reset/reset_test.go b/internal/db/reset/reset_test.go
index f8b5cc7c..3edc2e36 100644
--- a/internal/db/reset/reset_test.go
+++ b/internal/db/reset/reset_test.go
@@ -293,12 +293,24 @@ func TestRestartDatabase(t *testing.T) {
 		require.NoError(t, apitest.MockDocker(utils.Docker))
 		defer gock.OffAll()
 		gock.New(utils.Docker.DaemonHost()).
-			Post("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/restart").
+			Post("/v" + utils.Docker.ClientVersion() + "/containers/test-reset/restart").
 			Reply(http.StatusOK)
+		gock.New(utils.Docker.DaemonHost()).
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/test-reset/json").
+			Reply(http.StatusOK).
+			JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{
+				State: &types.ContainerState{
+					Running: false,
+					Status:  "exited",
+				},
+			}})
+		gock.New(utils.Docker.DaemonHost()).
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/test-reset/logs").
+			Reply(http.StatusServiceUnavailable)
 		// Run test
 		err := RestartDatabase(context.Background(), io.Discard)
 		// Check error
-		assert.ErrorIs(t, err, start.ErrDatabase)
+		assert.ErrorContains(t, err, "test-reset container is not running: exited")
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 }
@@ -308,6 +320,7 @@ var escapedSchemas = []string{
 	"public",
 	`\_analytics`,
 	`\_realtime`,
+	`\_supavisor`,
 	"pgbouncer",
 	"pgsodium",
 	"pgtle",
diff --git a/internal/db/test/test.go b/internal/db/test/test.go
index 2fb4e753..8ab6989e 100644
--- a/internal/db/test/test.go
+++ b/internal/db/test/test.go
@@ -42,7 +42,7 @@ func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afe
 		return errors.Errorf("failed to resolve absolute path: %w", err)
 	}
 	dstPath := "/tmp"
-	binds := []string{fmt.Sprintf("%s:%s:ro,z", srcPath, dstPath)}
+	binds := []string{fmt.Sprintf("%s:%s:ro", srcPath, dstPath)}
 	// Enable pgTAP if not already exists
 	alreadyExists := false
 	options = append(options, func(cc *pgx.ConnConfig) {
@@ -66,11 +66,12 @@ func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afe
 		}()
 	}
 	// Use custom network when connecting to local database
-	networkID := "host"
+	hostConfig := container.HostConfig{Binds: binds}
 	if utils.IsLocalDatabase(config) {
 		config.Host = utils.DbAliases[0]
 		config.Port = 5432
-		networkID = utils.NetId
+	} else {
+		hostConfig.NetworkMode = network.NetworkHost
 	}
 	// Run pg_prove on volume mount
 	return utils.DockerRunOnceWithConfig(
@@ -87,10 +88,7 @@ func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afe
 			Cmd:        cmd,
 			WorkingDir: dstPath,
 		},
-		container.HostConfig{
-			NetworkMode: container.NetworkMode(networkID),
-			Binds:       binds,
-		},
+		hostConfig,
 		network.NetworkingConfig{},
 		"",
 		os.Stdout,
diff --git a/internal/functions/serve/serve_test.go b/internal/functions/serve/serve_test.go
index c7cddc39..ab840590 100644
--- a/internal/functions/serve/serve_test.go
+++ b/internal/functions/serve/serve_test.go
@@ -3,6 +3,8 @@ package serve
 import (
 	"context"
 	"net/http"
+	"os"
+	"path/filepath"
 	"testing"
 
 	"github.com/docker/docker/api/types"
@@ -19,7 +21,7 @@ func TestServeCommand(t *testing.T) {
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
 		require.NoError(t, utils.InitConfig(utils.InitParams{ProjectId: "test"}, fsys))
-		require.NoError(t, afero.WriteFile(fsys, ".env", []byte{}, 0644))
+		require.NoError(t, afero.WriteFile(fsys, utils.FallbackEnvFilePath, []byte{}, 0644))
 		require.NoError(t, afero.WriteFile(fsys, utils.FallbackImportMapPath, []byte{}, 0644))
 		// Setup mock docker
 		require.NoError(t, apitest.MockDocker(utils.Docker))
@@ -35,8 +37,7 @@ func TestServeCommand(t *testing.T) {
 		apitest.MockDockerStart(utils.Docker, utils.GetRegistryImageUrl(utils.EdgeRuntimeImage), containerId)
 		require.NoError(t, apitest.MockDockerLogs(utils.Docker, containerId, "success"))
 		// Run test
-		noVerifyJWT := true
-		err := Run(context.Background(), ".env", &noVerifyJWT, "", RuntimeOption{}, fsys)
+		err := Run(context.Background(), "", nil, "", RuntimeOption{}, fsys)
 		// Check error
 		assert.NoError(t, err)
 		assert.Empty(t, apitest.ListUnmatchedRequests())
@@ -89,6 +90,8 @@ func TestServeCommand(t *testing.T) {
 		fsys := afero.NewMemMapFs()
 		require.NoError(t, utils.InitConfig(utils.InitParams{ProjectId: "test"}, fsys))
 		require.NoError(t, afero.WriteFile(fsys, ".env", []byte{}, 0644))
+		entrypoint := filepath.Join(utils.FunctionsDir, "hello", "index.ts")
+		require.NoError(t, afero.WriteFile(fsys, entrypoint, []byte{}, 0644))
 		// Setup mock docker
 		require.NoError(t, apitest.MockDocker(utils.Docker))
 		defer gock.OffAll()
@@ -97,9 +100,8 @@ func TestServeCommand(t *testing.T) {
 			Reply(http.StatusOK).
 			JSON(types.ContainerJSON{})
 		// Run test
-		err := Run(context.Background(), ".env", nil, "import_map.json", RuntimeOption{}, fsys)
+		err := Run(context.Background(), ".env", utils.Ptr(true), "import_map.json", RuntimeOption{}, fsys)
 		// Check error
-		assert.ErrorContains(t, err, "Failed to read import map")
-		assert.ErrorContains(t, err, "file does not exist")
+		assert.ErrorIs(t, err, os.ErrNotExist)
 	})
 }
diff --git a/internal/migration/squash/squash_test.go b/internal/migration/squash/squash_test.go
index a47b4fd2..a91c0651 100644
--- a/internal/migration/squash/squash_test.go
+++ b/internal/migration/squash/squash_test.go
@@ -218,6 +218,15 @@ func TestSquashMigrations(t *testing.T) {
 		apitest.MockDockerStart(utils.Docker, utils.GetRegistryImageUrl(utils.Config.Db.Image), "test-shadow-db")
 		gock.New(utils.Docker.DaemonHost()).
 			Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json").
+			Reply(http.StatusOK).
+			JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{
+				State: &types.ContainerState{
+					Running: false,
+					Status:  "exited",
+				},
+			}})
+		gock.New(utils.Docker.DaemonHost()).
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/logs").
 			Reply(http.StatusServiceUnavailable)
 		gock.New(utils.Docker.DaemonHost()).
 			Delete("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db").
@@ -225,7 +234,7 @@ func TestSquashMigrations(t *testing.T) {
 		// Run test
 		err := squashMigrations(context.Background(), nil, fsys)
 		// Check error
-		assert.ErrorIs(t, err, start.ErrDatabase)
+		assert.ErrorContains(t, err, "test-shadow-db container is not running: exited")
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 
diff --git a/internal/secrets/set/set_test.go b/internal/secrets/set/set_test.go
index baa5f851..6021804c 100644
--- a/internal/secrets/set/set_test.go
+++ b/internal/secrets/set/set_test.go
@@ -3,6 +3,7 @@ package set
 import (
 	"context"
 	"errors"
+	"net/http"
 	"testing"
 
 	"github.com/h2non/gock"
@@ -32,7 +33,7 @@ func TestSecretSetCommand(t *testing.T) {
 			Post("/v1/projects/" + project + "/secrets").
 			MatchType("json").
 			JSON(api.V1BulkCreateSecretsJSONRequestBody{dummy}).
-			Reply(200)
+			Reply(http.StatusCreated)
 		// Run test
 		err := Run(context.Background(), project, "", []string{dummyEnv}, fsys)
 		// Check error
@@ -55,7 +56,7 @@ func TestSecretSetCommand(t *testing.T) {
 			Post("/v1/projects/" + project + "/secrets").
 			MatchType("json").
 			JSON(api.V1BulkCreateSecretsJSONRequestBody{dummy}).
-			Reply(200)
+			Reply(http.StatusCreated)
 		// Run test
 		err := Run(context.Background(), project, "/tmp/.env", []string{}, fsys)
 		// Check error
diff --git a/internal/status/status_test.go b/internal/status/status_test.go
index c22e2219..16136307 100644
--- a/internal/status/status_test.go
+++ b/internal/status/status_test.go
@@ -4,10 +4,8 @@ import (
 	"bytes"
 	"context"
 	"errors"
-	"io"
 	"net/http"
 	"os"
-	"strings"
 	"testing"
 
 	"github.com/docker/docker/api/types"
@@ -21,33 +19,28 @@ import (
 
 func TestStatusCommand(t *testing.T) {
 	t.Run("shows service status", func(t *testing.T) {
-		services := []string{
-			"supabase_db_",
-			"supabase_kong_",
-			"supabase_auth_",
-			"supabase_inbucket_",
-			"supabase_realtime_",
-			"supabase_rest_",
-			"supabase_storage_",
-			"supabase_imgproxy_",
-			"supabase_pg_meta_",
-			"supabase_studio_",
-			"supabase_analytics_",
+		var running []types.Container
+		for _, name := range utils.GetDockerIds() {
+			running = append(running, types.Container{
+				Names: []string{name + "_test"},
+			})
 		}
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
-		require.NoError(t, utils.WriteConfig(fsys, false))
+		require.NoError(t, utils.InitConfig(utils.InitParams{ProjectId: "test"}, fsys))
 		// Setup mock docker
 		require.NoError(t, apitest.MockDocker(utils.Docker))
 		defer gock.OffAll()
-		for _, container := range services {
-			gock.New(utils.Docker.DaemonHost()).
-				Get("/v" + utils.Docker.ClientVersion() + "/containers/" + container).
-				Reply(http.StatusOK).
-				JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{
-					State: &types.ContainerState{Running: true},
-				}})
-		}
+		gock.New(utils.Docker.DaemonHost()).
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/supabase_db_test/json").
+			Reply(http.StatusOK).
+			JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{
+				State: &types.ContainerState{Running: true},
+			}})
+		gock.New(utils.Docker.DaemonHost()).
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/json").
+			Reply(http.StatusOK).
+			JSON(running)
 		// Run test
 		assert.NoError(t, Run(context.Background(), CustomName{}, utils.OutputPretty, fsys))
 		// Check error
@@ -88,56 +81,57 @@ func TestStatusCommand(t *testing.T) {
 }
 
 func TestServiceHealth(t *testing.T) {
-	services := []string{"supabase_db", "supabase_auth"}
-
 	t.Run("checks all services", func(t *testing.T) {
+		var running []types.Container
+		for _, name := range utils.GetDockerIds() {
+			running = append(running, types.Container{
+				Names: []string{name},
+			})
+		}
 		// Setup mock docker
 		require.NoError(t, apitest.MockDocker(utils.Docker))
 		defer gock.OffAll()
 		gock.New(utils.Docker.DaemonHost()).
-			Get("/v" + utils.Docker.ClientVersion() + "/containers/" + services[0] + "/json").
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/json").
 			Reply(http.StatusOK).
-			JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{
-				State: &types.ContainerState{
-					Running: true,
-					Health:  &types.Health{Status: "Unhealthy"},
-				},
-			}})
+			JSON(running)
+		// Run test
+		stopped, err := checkServiceHealth(context.Background())
+		// Check error
+		assert.NoError(t, err)
+		assert.Empty(t, stopped)
+		assert.Empty(t, apitest.ListUnmatchedRequests())
+	})
+
+	t.Run("shows stopped container", func(t *testing.T) {
+		// Setup mock docker
+		require.NoError(t, apitest.MockDocker(utils.Docker))
+		defer gock.OffAll()
 		gock.New(utils.Docker.DaemonHost()).
-			Get("/v" + utils.Docker.ClientVersion() + "/containers/" + services[1] + "/json").
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/json").
 			Reply(http.StatusOK).
-			JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{
-				State: &types.ContainerState{Status: "exited"},
-			}})
+			JSON([]types.Container{})
 		// Run test
-		var stderr bytes.Buffer
-		stopped := checkServiceHealth(context.Background(), services, &stderr)
+		stopped, err := checkServiceHealth(context.Background())
 		// Check error
-		assert.Empty(t, stopped)
-		lines := strings.Split(strings.TrimSpace(stderr.String()), "\n")
-		assert.ElementsMatch(t, []string{
-			"supabase_db container is not ready: Unhealthy",
-			"supabase_auth container is not running: exited",
-		}, lines)
+		assert.NoError(t, err)
+		assert.ElementsMatch(t, utils.GetDockerIds(), stopped)
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 
-	t.Run("throws error on missing container", func(t *testing.T) {
-		// Setup in-memory fs
-		fsys := afero.NewMemMapFs()
-		require.NoError(t, utils.WriteConfig(fsys, false))
+	t.Run("throws error on network error", func(t *testing.T) {
+		errNetwork := errors.New("network error")
 		// Setup mock docker
 		require.NoError(t, apitest.MockDocker(utils.Docker))
 		defer gock.OffAll()
-		for _, name := range services {
-			gock.New(utils.Docker.DaemonHost()).
-				Get("/v" + utils.Docker.ClientVersion() + "/containers/" + name + "/json").
-				Reply(http.StatusNotFound)
-		}
+		gock.New(utils.Docker.DaemonHost()).
+			Get("/v" + utils.Docker.ClientVersion() + "/containers/json").
+			ReplyError(errNetwork)
 		// Run test
-		stopped := checkServiceHealth(context.Background(), services, io.Discard)
+		stopped, err := checkServiceHealth(context.Background())
 		// Check error
-		assert.ElementsMatch(t, services, stopped)
+		assert.ErrorIs(t, err, errNetwork)
+		assert.Empty(t, stopped)
 		assert.Empty(t, apitest.ListUnmatchedRequests())
 	})
 }
diff --git a/internal/utils/deno_test.go b/internal/utils/deno_test.go
index e75e2dcb..96594211 100644
--- a/internal/utils/deno_test.go
+++ b/internal/utils/deno_test.go
@@ -1,7 +1,6 @@
 package utils
 
 import (
-	"os"
 	"path/filepath"
 	"testing"
 
@@ -17,7 +16,7 @@ func TestResolveImports(t *testing.T) {
 				"abs/":    "/tmp/",
 				"root":    "../../common",
 				"parent":  "../tests",
-				"child":   "child",
+				"child":   "child/",
 				"missing": "../missing",
 			},
 		}
@@ -32,7 +31,7 @@ func TestResolveImports(t *testing.T) {
 		assert.Equal(t, "/home/deno/modules/ac351c7174c8f47a9a9056bd96bcd71cfb980c906daee74ab9bce8308c68b811/", resolved.Imports["abs/"])
 		assert.Equal(t, "/home/deno/modules/92a5dc04bd6f9fb8f29f8066fed8a5c1e81bc59ad48a11283b63736867e4f2a8", resolved.Imports["root"])
 		assert.Equal(t, "/home/deno/modules/faaed96206118cf98625ea8065b6b3864f8cf9484814c423b58ebaa9b2d1e47b", resolved.Imports["parent"])
-		assert.Equal(t, "/home/deno/functions/child", resolved.Imports["child"])
+		assert.Equal(t, "/home/deno/functions/child/", resolved.Imports["child"])
 		assert.Equal(t, "../missing", resolved.Imports["missing"])
 	})
 
@@ -58,14 +57,10 @@ func TestImportMapPath(t *testing.T) {
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
 		require.NoError(t, afero.WriteFile(fsys, FallbackImportMapPath, []byte("{}"), 0644))
-		absPath, err := filepath.Abs(FallbackImportMapPath)
-		require.NoError(t, err)
-		require.NoError(t, afero.WriteFile(fsys, absPath, []byte("{}"), 0644))
 		// Run test
-		resolved, err := AbsImportMapPath("", "", fsys)
+		fc := GetFunctionConfig("", "", nil, fsys)
 		// Check error
-		assert.NoError(t, err)
-		assert.Equal(t, absPath, resolved)
+		assert.Equal(t, FallbackImportMapPath, fc.ImportMap)
 	})
 
 	t.Run("per function config takes precedence", func(t *testing.T) {
@@ -73,49 +68,46 @@ func TestImportMapPath(t *testing.T) {
 		Config.Functions = map[string]function{
 			slug: {ImportMap: "import_map.json"},
 		}
-		absPath, err := filepath.Abs("supabase/import_map.json")
-		require.NoError(t, err)
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
 		require.NoError(t, afero.WriteFile(fsys, FallbackImportMapPath, []byte("{}"), 0644))
-		require.NoError(t, afero.WriteFile(fsys, absPath, []byte("{}"), 0644))
 		// Run test
-		resolved, err := AbsImportMapPath("", slug, fsys)
+		fc := GetFunctionConfig(slug, "", nil, fsys)
 		// Check error
-		assert.NoError(t, err)
-		assert.Equal(t, absPath, resolved)
+		assert.Equal(t, "supabase/import_map.json", fc.ImportMap)
 	})
 
-	t.Run("returns empty string if no fallback", func(t *testing.T) {
+	t.Run("overrides with cli flag", func(t *testing.T) {
+		slug := "hello"
+		Config.Functions = map[string]function{
+			slug: {ImportMap: "import_map.json"},
+		}
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
+		require.NoError(t, afero.WriteFile(fsys, FallbackImportMapPath, []byte("{}"), 0644))
 		// Run test
-		resolved, err := AbsImportMapPath("", "", fsys)
+		fc := GetFunctionConfig(slug, FallbackImportMapPath, Ptr(false), fsys)
 		// Check error
-		assert.NoError(t, err)
-		assert.Empty(t, resolved)
+		assert.Equal(t, FallbackImportMapPath, fc.ImportMap)
 	})
 
-	t.Run("throws error on missing file", func(t *testing.T) {
-		path := "/tmp/import_map"
+	t.Run("returns empty string if no fallback", func(t *testing.T) {
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
 		// Run test
-		resolved, err := AbsImportMapPath(path, "", fsys)
+		fc := GetFunctionConfig("", "", nil, fsys)
 		// Check error
-		assert.ErrorIs(t, err, os.ErrNotExist)
-		assert.Empty(t, resolved)
+		assert.Empty(t, fc.ImportMap)
 	})
 
-	t.Run("throws error on importing directory", func(t *testing.T) {
-		path := "/tmp/import_map"
+	t.Run("preserves absolute path", func(t *testing.T) {
+		path := "/tmp/import_map.json"
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
-		require.NoError(t, fsys.MkdirAll(path, 0755))
+		require.NoError(t, afero.WriteFile(fsys, FallbackImportMapPath, []byte("{}"), 0644))
 		// Run test
-		resolved, err := AbsImportMapPath(path, "", fsys)
+		fc := GetFunctionConfig("", path, nil, fsys)
 		// Check error
-		assert.ErrorContains(t, err, "Importing directory is unsupported: "+path)
-		assert.Empty(t, resolved)
+		assert.Equal(t, path, fc.ImportMap)
 	})
 }
diff --git a/test/status_test.go b/test/status_test.go
index d309d243..509345d1 100644
--- a/test/status_test.go
+++ b/test/status_test.go
@@ -28,6 +28,7 @@ type StatusTestSuite struct {
 
 // test functions
 func (suite *StatusTestSuite) TestStatus() {
+	suite.T().Skip("Status command is no longer mocked")
 	// run command
 	status, _, err := suite.cmd.Find([]string{"status"})
 	status.SetContext(context.Background())