diff --git a/dockertest/dockertest.go b/dockertest/dockertest.go
deleted file mode 100644
index a9a8f64..0000000
--- a/dockertest/dockertest.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package dockertest
-
-import "github.com/ory/dockertest/v3"
-
-// type and function aliasing to avoid conflicting dockertest name
-type Pool = dockertest.Pool
-type Resource = dockertest.Resource
-
-var NewPool = dockertest.NewPool
diff --git a/dockertest/README.md b/dockertestx/README.md
similarity index 90%
rename from dockertest/README.md
rename to dockertestx/README.md
index 87aea7e..be3b758 100644
--- a/dockertest/README.md
+++ b/dockertestx/README.md
@@ -1,4 +1,4 @@
-# dockertest
+# dockertestx
 
 This package is an abstraction of several dockerized data storages using `ory/dockertest` to bootstrap a specific dockerized instance.
 
@@ -44,7 +44,7 @@ if err != nil {
 // create postgres instance
 pgDocker, err := dockertest.CreatePostgres(
     dockertest.PostgresWithDockerPool(pool),
-    dockertest.PostgresWithDockerNetwork(network),
+    dockertest.PostgresWithDockertestNetwork(network),
     dockertest.PostgresWithDetail(
         pgUser, pgPass, pgDBName,
     ),
@@ -56,12 +56,12 @@ connString := pgDocker.GetInternalConnString()
 // create spice db instance
 spiceDocker, err := dockertest.CreateSpiceDB(connString,
     dockertest.SpiceDBWithDockerPool(pool),
-    dockertest.SpiceDBWithDockerNetwork(network),
+    dockertest.SpiceDBWithDockertestNetwork(network),
 )
 
 if err := dockertest.MigrateSpiceDB(connString,
     dockertest.MigrateSpiceDBWithDockerPool(pool),
-    dockertest.MigrateSpiceDBWithDockerNetwork(network),
+    dockertest.MigrateSpiceDBWithDockertestNetwork(network),
 ); err != nil {
     return err
 }
diff --git a/dockertest/configs/cortex/single_process_cortex.yaml b/dockertestx/configs/cortex/single_process_cortex.yaml
similarity index 100%
rename from dockertest/configs/cortex/single_process_cortex.yaml
rename to dockertestx/configs/cortex/single_process_cortex.yaml
diff --git a/dockertestx/configs/nginx/cortex_nginx.conf b/dockertestx/configs/nginx/cortex_nginx.conf
new file mode 100644
index 0000000..6298ae2
--- /dev/null
+++ b/dockertestx/configs/nginx/cortex_nginx.conf
@@ -0,0 +1,93 @@
+worker_processes  1;
+error_log  /dev/stderr;
+pid        /tmp/nginx.pid;
+worker_rlimit_nofile 8192;
+
+events {
+  worker_connections 1024;
+}
+
+
+http {
+  client_max_body_size 5M;
+  default_type application/octet-stream;
+  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
+    '"$request" $body_bytes_sent "$http_referer" '
+    '"$http_user_agent" "$http_x_forwarded_for" $http_x_scope_orgid';
+  access_log   /dev/stderr  main;
+  sendfile     on;
+  tcp_nopush   on;
+  resolver 127.0.0.11 ipv6=off;
+
+  server {
+    listen {{.ExposedPort}};
+    proxy_connect_timeout 300s;
+    proxy_send_timeout 300s;
+    proxy_read_timeout 300s;
+    proxy_http_version 1.1;
+
+    location = /healthz {
+      return 200 'alive';
+    }
+
+    # Distributor Config
+    location = /ring {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    location = /all_user_stats {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    location = /api/prom/push {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    ## New Remote write API. Ref: https://cortexmetrics.io/docs/api/#remote-write
+    location = /api/v1/push {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+
+    # Alertmanager Config
+    location ~ /api/prom/alertmanager/.* {
+      proxy_pass      http://{{.AlertManagerHost}}$request_uri;
+    }
+
+    location ~ /api/v1/alerts {
+      proxy_pass      http://{{.AlertManagerHost}}$request_uri;
+    }
+
+    location ~ /multitenant_alertmanager/status {
+      proxy_pass      http://{{.AlertManagerHost}}$request_uri;
+    }
+
+    # Ruler Config
+    location ~ /api/v1/rules {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    location ~ /ruler/ring {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    # Config Config
+    location ~ /api/prom/configs/.* {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    # Query Config
+    location ~ /api/prom/.* {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    ## New Query frontend APIs as per https://cortexmetrics.io/docs/api/#querier--query-frontend
+    location ~ ^/prometheus/api/v1/(read|metadata|labels|series|query_range|query) {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+
+    location ~ /prometheus/api/v1/label/.* {
+      proxy_pass      http://{{.RulerHost}}$request_uri;
+    }
+  }
+}
\ No newline at end of file
diff --git a/dockertest/cortex.go b/dockertestx/cortex.go
similarity index 93%
rename from dockertest/cortex.go
rename to dockertestx/cortex.go
index d6414c8..87969bd 100644
--- a/dockertest/cortex.go
+++ b/dockertestx/cortex.go
@@ -1,4 +1,4 @@
-package dockertest
+package dockertestx
 
 import (
 	"fmt"
@@ -15,14 +15,14 @@ import (
 
 type dockerCortexOption func(dc *dockerCortex)
 
-// CortexWithDockerNetwork is an option to assign docker network
-func CortexWithDockerNetwork(network *docker.Network) dockerCortexOption {
+// CortexWithDockertestNetwork is an option to assign docker network
+func CortexWithDockertestNetwork(network *dockertest.Network) dockerCortexOption {
 	return func(dc *dockerCortex) {
 		dc.network = network
 	}
 }
 
-// CortexWithDockerNetwork is an option to assign version tag
+// CortexWithDockertestNetwork is an option to assign version tag
 // of a `quay.io/cortexproject/cortex` image
 func CortexWithVersionTag(versionTag string) dockerCortexOption {
 	return func(dc *dockerCortex) {
@@ -60,7 +60,7 @@ func CortexWithS3Endpoint(s3URL string) dockerCortexOption {
 }
 
 type dockerCortex struct {
-	network            *docker.Network
+	network            *dockertest.Network
 	pool               *dockertest.Pool
 	moduleName         string
 	alertManagerURL    string
@@ -115,11 +115,13 @@ func CreateCortex(opts ...dockerCortexOption) (*dockerCortex, error) {
 			fmt.Sprintf("-alertmanager.storage.s3.endpoint=%s", dc.s3URL),
 		},
 		ExposedPorts: []string{"9009/tcp"},
-		ExtraHosts:   []string{"cortex.siren_nginx_1:127.0.0.1"},
+		ExtraHosts: []string{
+			"cortex.siren_nginx_1:127.0.0.1",
+		},
 	}
 
 	if dc.network != nil {
-		runOpts.NetworkID = dc.network.ID
+		runOpts.NetworkID = dc.network.Network.ID
 	}
 
 	pwd, err := os.Getwd()
diff --git a/dockertestx/dockertestx.go b/dockertestx/dockertestx.go
new file mode 100644
index 0000000..b0f7d71
--- /dev/null
+++ b/dockertestx/dockertestx.go
@@ -0,0 +1,11 @@
+package dockertestx
+
+import "runtime"
+
+func DockerHostAddress() string {
+	var dockerHostInternal = "host-gateway" // linux by default
+	if runtime.GOOS == "darwin" {
+		dockerHostInternal = "host.docker.internal"
+	}
+	return dockerHostInternal
+}
diff --git a/dockertest/minio.go b/dockertestx/minio.go
similarity index 93%
rename from dockertest/minio.go
rename to dockertestx/minio.go
index edf3d06..014f62d 100644
--- a/dockertest/minio.go
+++ b/dockertestx/minio.go
@@ -1,4 +1,4 @@
-package dockertest
+package dockertestx
 
 import (
 	"fmt"
@@ -18,8 +18,8 @@ const (
 
 type dockerMinioOption func(dm *dockerMinio)
 
-// MinioWithDockerNetwork is an option to assign docker network
-func MinioWithDockerNetwork(network *docker.Network) dockerMinioOption {
+// MinioWithDockertestNetwork is an option to assign docker network
+func MinioWithDockertestNetwork(network *dockertest.Network) dockerMinioOption {
 	return func(dm *dockerMinio) {
 		dm.network = network
 	}
@@ -41,7 +41,7 @@ func MinioWithDockerPool(pool *dockertest.Pool) dockerMinioOption {
 }
 
 type dockerMinio struct {
-	network             *docker.Network
+	network             *dockertest.Network
 	pool                *dockertest.Pool
 	rootUser            string
 	rootPassword        string
@@ -103,7 +103,7 @@ func CreateMinio(opts ...dockerMinioOption) (*dockerMinio, error) {
 	}
 
 	if dm.network != nil {
-		runOpts.NetworkID = dm.network.ID
+		runOpts.NetworkID = dm.network.Network.ID
 	}
 
 	dm.dockertestResource, err = dm.pool.RunWithOptions(
diff --git a/dockertest/minio_migrate.go b/dockertestx/minio_migrate.go
similarity index 90%
rename from dockertest/minio_migrate.go
rename to dockertestx/minio_migrate.go
index 0460336..0288ad0 100644
--- a/dockertest/minio_migrate.go
+++ b/dockertestx/minio_migrate.go
@@ -1,4 +1,4 @@
-package dockertest
+package dockertestx
 
 import (
 	"bytes"
@@ -14,8 +14,8 @@ const waitContainerTimeout = 60 * time.Second
 
 type dockerMigrateMinioOption func(dmm *dockerMigrateMinio)
 
-// MigrateMinioWithDockerNetwork is an option to assign docker network
-func MigrateMinioWithDockerNetwork(network *docker.Network) dockerMigrateMinioOption {
+// MigrateMinioWithDockertestNetwork is an option to assign docker network
+func MigrateMinioWithDockertestNetwork(network *dockertest.Network) dockerMigrateMinioOption {
 	return func(dm *dockerMigrateMinio) {
 		dm.network = network
 	}
@@ -37,7 +37,7 @@ func MigrateMinioWithDockerPool(pool *dockertest.Pool) dockerMigrateMinioOption
 }
 
 type dockerMigrateMinio struct {
-	network    *docker.Network
+	network    *dockertest.Network
 	pool       *dockertest.Pool
 	versionTag string
 }
@@ -79,7 +79,7 @@ func MigrateMinio(minioHost string, bucketName string, opts ...dockerMigrateMini
 	}
 
 	if dm.network != nil {
-		runOpts.NetworkID = dm.network.ID
+		runOpts.NetworkID = dm.network.Network.ID
 	}
 
 	resource, err := dm.pool.RunWithOptions(runOpts, func(config *docker.HostConfig) {
diff --git a/dockertestx/nginx.go b/dockertestx/nginx.go
new file mode 100644
index 0000000..5786c90
--- /dev/null
+++ b/dockertestx/nginx.go
@@ -0,0 +1,247 @@
+package dockertestx
+
+import (
+	"bytes"
+	_ "embed"
+	"fmt"
+	"io/fs"
+	"net/http"
+	"os"
+	"path"
+	"text/template"
+	"time"
+
+	"github.com/google/uuid"
+	"github.com/ory/dockertest/v3"
+	"github.com/ory/dockertest/v3/docker"
+)
+
+const (
+	nginxDefaultHealthEndpoint = "/healthz"
+	nginxDefaultExposedPort    = "8080"
+	nginxDefaultVersionTag     = "1.23"
+)
+
+var (
+	//go:embed configs/nginx/cortex_nginx.conf
+	NginxCortexConfig string
+)
+
+type dockerNginxOption func(dc *dockerNginx)
+
+// NginxWithHealthEndpoint is an option to assign health endpoint
+func NginxWithHealthEndpoint(healthEndpoint string) dockerNginxOption {
+	return func(dc *dockerNginx) {
+		dc.healthEndpoint = healthEndpoint
+	}
+}
+
+// NginxWithDockertestNetwork is an option to assign docker network
+func NginxWithDockertestNetwork(network *dockertest.Network) dockerNginxOption {
+	return func(dc *dockerNginx) {
+		dc.network = network
+	}
+}
+
+// NginxWithVersionTag is an option to assign version tag
+// of a `nginx` image
+func NginxWithVersionTag(versionTag string) dockerNginxOption {
+	return func(dc *dockerNginx) {
+		dc.versionTag = versionTag
+	}
+}
+
+// NginxWithDockerPool is an option to assign docker pool
+func NginxWithDockerPool(pool *dockertest.Pool) dockerNginxOption {
+	return func(dc *dockerNginx) {
+		dc.pool = pool
+	}
+}
+
+// NginxWithDockerPool is an option to assign docker pool
+func NginxWithExposedPort(port string) dockerNginxOption {
+	return func(dc *dockerNginx) {
+		dc.exposedPort = port
+	}
+}
+
+func NginxWithPresetConfig(presetConfig string) dockerNginxOption {
+	return func(dc *dockerNginx) {
+		dc.presetConfig = presetConfig
+	}
+}
+
+func NginxWithConfigVariables(cv map[string]string) dockerNginxOption {
+	return func(dc *dockerNginx) {
+		dc.configVariables = cv
+	}
+}
+
+type dockerNginx struct {
+	network            *dockertest.Network
+	pool               *dockertest.Pool
+	exposedPort        string
+	internalHost       string
+	externalHost       string
+	presetConfig       string
+	versionTag         string
+	healthEndpoint     string
+	configVariables    map[string]string
+	dockertestResource *dockertest.Resource
+}
+
+// CreateNginx is a function to create a dockerized nginx
+func CreateNginx(opts ...dockerNginxOption) (*dockerNginx, error) {
+	var (
+		err error
+		dc  = &dockerNginx{}
+	)
+
+	for _, opt := range opts {
+		opt(dc)
+	}
+
+	name := fmt.Sprintf("nginx-%s", uuid.New().String())
+
+	if dc.pool == nil {
+		dc.pool, err = dockertest.NewPool("")
+		if err != nil {
+			return nil, fmt.Errorf("could not create dockertest pool: %w", err)
+		}
+	}
+
+	if dc.versionTag == "" {
+		dc.versionTag = nginxDefaultVersionTag
+	}
+
+	if dc.exposedPort == "" {
+		dc.exposedPort = nginxDefaultExposedPort
+	}
+
+	if dc.healthEndpoint == "" {
+		dc.healthEndpoint = nginxDefaultHealthEndpoint
+	}
+
+	runOpts := &dockertest.RunOptions{
+		Name:         name,
+		Repository:   "nginx",
+		Tag:          dc.versionTag,
+		ExposedPorts: []string{fmt.Sprintf("%s/tcp", dc.exposedPort)},
+	}
+
+	if dc.network != nil {
+		runOpts.NetworkID = dc.network.Network.ID
+	}
+
+	var confString string
+	switch dc.presetConfig {
+	case "cortex":
+		confString = NginxCortexConfig
+	}
+
+	tmpl := template.New("nginx-config")
+	parsedTemplate, err := tmpl.Parse(confString)
+	if err != nil {
+		return nil, err
+	}
+	var generatedConf bytes.Buffer
+	err = parsedTemplate.Execute(&generatedConf, dc.configVariables)
+	if err != nil {
+		// it is unlikely that the code returns error here
+		return nil, err
+	}
+	confString = generatedConf.String()
+
+	pwd, err := os.Getwd()
+	if err != nil {
+		return nil, err
+	}
+
+	var (
+		confDestinationFolder = fmt.Sprintf("%s/tmp/dockertest-configs/nginx", pwd)
+	)
+
+	foldersPath := []string{confDestinationFolder}
+	for _, fp := range foldersPath {
+		if _, err := os.Stat(fp); os.IsNotExist(err) {
+			if err := os.MkdirAll(fp, 0777); err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	if err := os.WriteFile(path.Join(confDestinationFolder, "nginx.conf"), []byte(confString), fs.ModePerm); err != nil {
+		return nil, err
+	}
+
+	dc.dockertestResource, err = dc.pool.RunWithOptions(
+		runOpts,
+		func(config *docker.HostConfig) {
+			config.RestartPolicy = docker.RestartPolicy{
+				Name: "no",
+			}
+			config.Mounts = []docker.HostMount{
+				{
+					Target: "/etc/nginx/nginx.conf",
+					Source: path.Join(confDestinationFolder, "nginx.conf"),
+					Type:   "bind",
+				},
+			}
+		},
+	)
+	if err != nil {
+		return nil, err
+	}
+
+	externalPort := dc.dockertestResource.GetPort(fmt.Sprintf("%s/tcp", dc.exposedPort))
+	dc.internalHost = fmt.Sprintf("%s:%s", name, dc.exposedPort)
+	dc.externalHost = fmt.Sprintf("localhost:%s", externalPort)
+
+	if err = dc.dockertestResource.Expire(120); err != nil {
+		return nil, err
+	}
+
+	// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
+	dc.pool.MaxWait = 60 * time.Second
+
+	if err = dc.pool.Retry(func() error {
+		httpClient := &http.Client{}
+		res, err := httpClient.Get(fmt.Sprintf("http://localhost:%s%s", externalPort, dc.healthEndpoint))
+		if err != nil {
+			return err
+		}
+
+		if res.StatusCode != 200 {
+			return fmt.Errorf("nginx server return status %d", res.StatusCode)
+		}
+
+		return nil
+	}); err != nil {
+		err = fmt.Errorf("could not connect to docker: %w", err)
+		return nil, fmt.Errorf("could not connect to docker: %w", err)
+	}
+
+	return dc, nil
+}
+
+// GetPool returns docker pool
+func (dc *dockerNginx) GetPool() *dockertest.Pool {
+	return dc.pool
+}
+
+// GetResource returns docker resource
+func (dc *dockerNginx) GetResource() *dockertest.Resource {
+	return dc.dockertestResource
+}
+
+// GetInternalHost returns internal hostname and port
+// e.g. internal-xxxxxx:8080
+func (dc *dockerNginx) GetInternalHost() string {
+	return dc.internalHost
+}
+
+// GetExternalHost returns localhost and port
+// e.g. localhost:51113
+func (dc *dockerNginx) GetExternalHost() string {
+	return dc.externalHost
+}
diff --git a/dockertest/postgres.go b/dockertestx/postgres.go
similarity index 94%
rename from dockertest/postgres.go
rename to dockertestx/postgres.go
index 72409e1..f29df23 100644
--- a/dockertest/postgres.go
+++ b/dockertestx/postgres.go
@@ -1,4 +1,4 @@
-package dockertest
+package dockertestx
 
 import (
 	"fmt"
@@ -25,8 +25,8 @@ func PostgresWithLogger(logger log.Logger) dockerPostgresOption {
 	}
 }
 
-// PostgresWithDockerNetwork is an option to assign docker network
-func PostgresWithDockerNetwork(network *docker.Network) dockerPostgresOption {
+// PostgresWithDockertestNetwork is an option to assign docker network
+func PostgresWithDockertestNetwork(network *dockertest.Network) dockerPostgresOption {
 	return func(dpg *dockerPostgres) {
 		dpg.network = network
 	}
@@ -63,7 +63,7 @@ func PostgresWithDockerPool(pool *dockertest.Pool) dockerPostgresOption {
 
 type dockerPostgres struct {
 	logger             log.Logger
-	network            *docker.Network
+	network            *dockertest.Network
 	pool               *dockertest.Pool
 	username           string
 	password           string
@@ -123,7 +123,7 @@ func CreatePostgres(opts ...dockerPostgresOption) (*dockerPostgres, error) {
 	}
 
 	if dpg.network != nil {
-		runOpts.NetworkID = dpg.network.ID
+		runOpts.NetworkID = dpg.network.Network.ID
 	}
 
 	dpg.dockertestResource, err = dpg.pool.RunWithOptions(
diff --git a/dockertest/spicedb.go b/dockertestx/spicedb.go
similarity index 94%
rename from dockertest/spicedb.go
rename to dockertestx/spicedb.go
index e36fc8a..143e8ba 100644
--- a/dockertest/spicedb.go
+++ b/dockertestx/spicedb.go
@@ -1,4 +1,4 @@
-package dockertest
+package dockertestx
 
 import (
 	"context"
@@ -30,8 +30,8 @@ func SpiceDBWithLogLevel(logLevel string) dockerSpiceDBOption {
 	}
 }
 
-// SpiceDBWithDockerNetwork is an option to assign docker network
-func SpiceDBWithDockerNetwork(network *docker.Network) dockerSpiceDBOption {
+// SpiceDBWithDockertestNetwork is an option to assign docker network
+func SpiceDBWithDockertestNetwork(network *dockertest.Network) dockerSpiceDBOption {
 	return func(dsp *dockerSpiceDB) {
 		dsp.network = network
 	}
@@ -60,7 +60,7 @@ func SpiceDBWithPreSharedKey(preSharedKey string) dockerSpiceDBOption {
 }
 
 type dockerSpiceDB struct {
-	network            *docker.Network
+	network            *dockertest.Network
 	pool               *dockertest.Pool
 	preSharedKey       string
 	versionTag         string
@@ -110,7 +110,7 @@ func CreateSpiceDB(postgresConnectionURL string, opts ...dockerSpiceDBOption) (*
 	}
 
 	if dsp.network != nil {
-		runOpts.NetworkID = dsp.network.ID
+		runOpts.NetworkID = dsp.network.Network.ID
 	}
 
 	dsp.dockertestResource, err = dsp.pool.RunWithOptions(
diff --git a/dockertest/spicedb_migrate.go b/dockertestx/spicedb_migrate.go
similarity index 90%
rename from dockertest/spicedb_migrate.go
rename to dockertestx/spicedb_migrate.go
index 956b227..ec34e43 100644
--- a/dockertest/spicedb_migrate.go
+++ b/dockertestx/spicedb_migrate.go
@@ -1,4 +1,4 @@
-package dockertest
+package dockertestx
 
 import (
 	"bytes"
@@ -11,8 +11,8 @@ import (
 
 type dockerMigrateSpiceDBOption func(dmm *dockerMigrateSpiceDB)
 
-// MigrateSpiceDBWithDockerNetwork is an option to assign docker network
-func MigrateSpiceDBWithDockerNetwork(network *docker.Network) dockerMigrateSpiceDBOption {
+// MigrateSpiceDBWithDockertestNetwork is an option to assign docker network
+func MigrateSpiceDBWithDockertestNetwork(network *dockertest.Network) dockerMigrateSpiceDBOption {
 	return func(dm *dockerMigrateSpiceDB) {
 		dm.network = network
 	}
@@ -34,7 +34,7 @@ func MigrateSpiceDBWithDockerPool(pool *dockertest.Pool) dockerMigrateSpiceDBOpt
 }
 
 type dockerMigrateSpiceDB struct {
-	network    *docker.Network
+	network    *dockertest.Network
 	pool       *dockertest.Pool
 	versionTag string
 }
@@ -68,7 +68,7 @@ func MigrateSpiceDB(postgresConnectionURL string, opts ...dockerMigrateMinioOpti
 	}
 
 	if dm.network != nil {
-		runOpts.NetworkID = dm.network.ID
+		runOpts.NetworkID = dm.network.Network.ID
 	}
 
 	resource, err := dm.pool.RunWithOptions(runOpts, func(config *docker.HostConfig) {
