2828 ErrSocketNotFoundInPath = errors .New ("docker socket not found in " + DockerSocketPath )
2929 // ErrTestcontainersHostNotSetInProperties this error is specific to Testcontainers
3030 ErrTestcontainersHostNotSetInProperties = errors .New ("tc.host not set in ~/.testcontainers.properties" )
31+ ErrDockerSocketNotSetInDockerContext = errors .New ("socket not found in docker context" )
3132)
3233
3334var (
@@ -73,7 +74,7 @@ var dockerHostCheck = func(ctx context.Context, host string) error {
7374 return nil
7475}
7576
76- // MustExtractDockerHost Extracts the docker host from the different alternatives, caching the result to avoid unnecessary
77+ // MustExtractDockerHost extracts the docker host from the different alternatives, caching the result to avoid unnecessary
7778// calculations. Use this function to get the actual Docker host. This function does not consider Windows containers at the moment.
7879// The possible alternatives are:
7980//
@@ -86,7 +87,7 @@ var dockerHostCheck = func(ctx context.Context, host string) error {
8687// 7. Else, because the Docker host is not set, it panics.
8788func MustExtractDockerHost (ctx context.Context ) string {
8889 dockerHostOnce .Do (func () {
89- cache , err := extractDockerHost (ctx )
90+ cache , err := ExtractDockerHost (ctx )
9091 if err != nil {
9192 panic (err )
9293 }
@@ -118,13 +119,22 @@ func MustExtractDockerSocket(ctx context.Context) string {
118119 return dockerSocketPathCache
119120}
120121
121- // extractDockerHost Extracts the docker host from the different alternatives, without caching the result.
122- // This internal method is handy for testing purposes.
123- func extractDockerHost (ctx context.Context ) (string , error ) {
122+ // ExtractDockerHost Extracts the docker host from the different alternatives, without caching the result.
123+ // Use this function to get the actual Docker host. This function does not consider Windows containers at the moment.
124+ // The possible alternatives are:
125+ //
126+ // 1. Docker host from the "tc.host" property in the ~/.testcontainers.properties file.
127+ // 2. DOCKER_HOST environment variable.
128+ // 3. Docker host from context.
129+ // 4. Docker host from the default docker socket path, without the unix schema.
130+ // 5. Docker host from the "docker.host" property in the ~/.testcontainers.properties file.
131+ // 6. Rootless docker socket path.
132+ func ExtractDockerHost (ctx context.Context ) (string , error ) {
124133 dockerHostFns := []func (context.Context ) (string , error ){
125134 testcontainersHostFromProperties ,
126135 dockerHostFromEnv ,
127136 dockerHostFromContext ,
137+ dockerHostFromDockerContext ,
128138 dockerSocketPath ,
129139 dockerHostFromProperties ,
130140 rootlessDockerSocketPath ,
@@ -149,6 +159,7 @@ func extractDockerHost(ctx context.Context) (string, error) {
149159 }
150160
151161 if len (errs ) > 0 {
162+ panic (32 )
152163 return "" , errors .Join (errs ... )
153164 }
154165
@@ -212,7 +223,7 @@ func extractDockerSocketFromClient(ctx context.Context, cli client.APIClient) st
212223 return DockerSocketPath
213224 }
214225
215- dockerHost , err := extractDockerHost (ctx )
226+ dockerHost , err := ExtractDockerHost (ctx )
216227 if err != nil {
217228 panic (err ) // Docker host is required to get the Docker socket
218229 }
@@ -227,12 +238,14 @@ func isHostNotSet(err error) bool {
227238 case errors .Is (err , ErrTestcontainersHostNotSetInProperties ),
228239 errors .Is (err , ErrDockerHostNotSet ),
229240 errors .Is (err , ErrDockerSocketNotSetInContext ),
241+ errors .Is (err , ErrDockerSocketNotSetInDockerContext ),
230242 errors .Is (err , ErrDockerSocketNotSetInProperties ),
231243 errors .Is (err , ErrSocketNotFoundInPath ),
232244 errors .Is (err , ErrXDGRuntimeDirNotSet ),
233245 errors .Is (err , ErrRootlessDockerNotFoundHomeRunDir ),
234246 errors .Is (err , ErrRootlessDockerNotFoundHomeDesktopDir ),
235- errors .Is (err , ErrRootlessDockerNotFoundRunDir ):
247+ errors .Is (err , ErrRootlessDockerNotFoundRunDir ),
248+ errors .Is (err , ErrRootlessDockerNotFound ):
236249 return true
237250 default :
238251 return false
@@ -262,6 +275,17 @@ func dockerHostFromContext(ctx context.Context) (string, error) {
262275 return "" , ErrDockerSocketNotSetInContext
263276}
264277
278+ // dockerHostFromDockerContext returns the docker host from the DOCKER_CONTEXT environment variable, if it's not empty
279+ func dockerHostFromDockerContext (_ context.Context ) (string , error ) {
280+ // exec `docker context inspect -f='{{.Endpoints.docker.Host}}'`
281+ cmd := exec .Command ("docker" , "context" , "inspect" , "-f" , "{{.Endpoints.docker.Host}}" )
282+ output , err := cmd .CombinedOutput ()
283+ if err != nil {
284+ return "" , fmt .Errorf ("%w: %w" , ErrDockerSocketNotSetInDockerContext , err )
285+ }
286+ return strings .TrimSpace (string (output )), nil
287+ }
288+
265289// dockerHostFromProperties returns the docker host from the ~/.testcontainers.properties file, if it's not empty
266290func dockerHostFromProperties (_ context.Context ) (string , error ) {
267291 cfg := config .Read ()
0 commit comments