@@ -130,6 +130,9 @@ async function createDockerProxy(proxyPort: number, httpsConfig: { certPath: str
130130 { apiVersion : dockerApiVersion ! } ,
131131 ) ;
132132
133+ const hasDockerComposeLabels = Object . keys ( config . Labels ?? [ ] )
134+ . includes ( "com.docker.compose.version" ) ;
135+
133136 const transformedConfig = transformContainerCreationConfig (
134137 config ,
135138 imageConfig ,
@@ -142,34 +145,38 @@ async function createDockerProxy(proxyPort: number, httpsConfig: { certPath: str
142145 ) ;
143146 requestBodyStream = stream . Readable . from ( JSON . stringify ( transformedConfig ) ) ;
144147
145- // If you try to create a container with a name that directly conflicts with another name
146- // that's currently in use by a non-intercepted container, we create a separate container
147- // with an _HTK$PORT suffix to avoid conflicts. This happens commonly, because of how
148+ // If you specify an explicit name in cases that will cause conflicts (when a container already
149+ // exists, or if you're using docker-compose) we try to create a separate container instead,
150+ // that uses a _HTK$PORT suffix to avoid conflicts. This happens commonly, because of how
148151 // docker-compose automatically generates container names.
149152 const containerName = reqUrl . searchParams . get ( 'name' ) ;
150153 if ( containerName ) {
151154 const existingContainer = await docker . getContainer ( containerName ) . inspect ( )
152155 . catch < false > ( ( ) => false ) ;
153- if ( existingContainer && ! isInterceptedContainer ( existingContainer , proxyPort ) ) {
154- if ( ! existingContainer . State . Running ) {
155- // If there's a duplicate but stopped container, we start the new container with an
156- // modified name, so that everything works with no conflicts:
157- reqUrl . searchParams . set ( 'name' , `${ containerName } _HTK${ proxyPort } ` ) ;
158- req . url = reqUrl . toString ( ) ;
159- } else {
160- // If there's a duplicate running container, we could to the same, but instead we return an error.
161- // It's likely that this will create conflicts otherwise, e.g. two running containers using the
162- // same volumes or the same network aliases. Better to play it safe.
163- res . statusCode = 409 ;
164- res . end ( JSON . stringify ( {
165- "message" : `Conflict. The container name ${
166- containerName
167- } is already in use by a running container.\n${ ''
168- } HTTP Toolkit won't intercept this by default to avoid conflicts with shared resources. ${ ''
169- } To create & intercept this container, either stop the existing unintercepted container, or use a different name.`
170- } ) ) ;
171- return ;
172- }
156+
157+ if ( existingContainer && existingContainer . State . Running ) {
158+ // If there's a duplicate running container, we could rename the new one, but instead we return
159+ // an error. It's likely that this will create conflicts otherwise - e.g. two running containers
160+ // using the same volumes or the same network aliases. Better to play it safe.
161+ res . statusCode = 409 ;
162+ res . end ( JSON . stringify ( {
163+ "message" : `Conflict. The container name ${
164+ containerName
165+ } is already in use by a running container.\n${ ''
166+ } HTTP Toolkit won't intercept this by default to avoid conflicts with shared resources. ${ ''
167+ } To create & intercept this container, either stop the existing unintercepted container, or use a different name.`
168+ } ) ) ;
169+ return ;
170+ } else if ( existingContainer || hasDockerComposeLabels ) {
171+ // If there's a naming conflict, and we can safely work around it (because the container isn't
172+ // running) then we do so.
173+
174+ // For Docker-Compose, we *always* rewrite names. This ensures that subsequent Docker-Compose usage
175+ // outside intercepted usage doesn't run into naming conflicts (however, this still only applies
176+ // after checking for running containers - we never create a duplicate parallel container ourselves)
177+
178+ reqUrl . searchParams . set ( 'name' , `${ containerName } _HTK${ proxyPort } ` ) ;
179+ req . url = reqUrl . toString ( ) ;
173180 }
174181 }
175182 }
0 commit comments