-
-
Notifications
You must be signed in to change notification settings - Fork 250
Description
Expected Behaviour
When a container is part of multiple networks, I should be able to consistently get the right port using getMappedPort.
Actual Behaviour
In these conditions, getMappedPort intermittently returns a port different to that in the Ports block of NetworkSettings, leading to clients using that port to fail to connect to their destination.
Testcontainer Logs
Logs of the failing run:
Run 10
Creating network a
testcontainers [INFO] Starting network "6f8b2d805b8c"... +0ms
testcontainers [DEBUG] Creating network "6f8b2d805b8c"... +0ms
testcontainers [DEBUG] Created network "6f8b2d805b8c" +140ms
testcontainers [INFO] Started network "6f8b2d805b8c" with ID "7d5be5268d87908a2d467086a20c8d6d0773cdd7c9c901b3417d68ef48ccf42e" +0ms
Creating network b
testcontainers [INFO] Starting network "202a305aaf98"... +0ms
testcontainers [DEBUG] Creating network "202a305aaf98"... +0ms
testcontainers [DEBUG] Created network "202a305aaf98" +141ms
testcontainers [INFO] Started network "202a305aaf98" with ID "33a686ac3a0725b8facfe86b90d31df75daaa56ca9882f9c6b13e1912f731820" +0ms
Starting ping-pong container
testcontainers [DEBUG] Image "briceburg/ping-pong:latest" already exists +1ms
testcontainers [DEBUG] Creating container for image "briceburg/ping-pong:latest"... +0ms
testcontainers [DEBUG] [ec638beb98c3] Created container for image "briceburg/ping-pong:latest" +44ms
testcontainers [INFO] [ec638beb98c3] Starting container for image "briceburg/ping-pong:latest"... +0ms
testcontainers [DEBUG] [ec638beb98c3] Starting container... +0ms
testcontainers [DEBUG] [ec638beb98c3] Started container +282ms
testcontainers [INFO] [ec638beb98c3] Started container for image "briceburg/ping-pong:latest" +1ms
testcontainers [DEBUG] [ec638beb98c3] Inspecting container... +0ms
testcontainers [DEBUG] [ec638beb98c3] Inspected container +4ms
testcontainers [DEBUG] [ec638beb98c3] Fetching container logs... +0ms
testcontainers [DEBUG] [ec638beb98c3] Demuxing stream... +10ms
testcontainers [DEBUG] [ec638beb98c3] Demuxed stream +0ms
testcontainers [DEBUG] [ec638beb98c3] Fetched container logs +0ms
testcontainers [DEBUG] [ec638beb98c3] Waiting for container to be ready... +0ms
testcontainers [DEBUG] [ec638beb98c3] Waiting for host port 55528... +0ms
testcontainers [DEBUG] [ec638beb98c3] Waiting for internal port 80... +1ms
testcontainers:containers [ec638beb98c3] +2s
testcontainers:containers [ec638beb98c3] [npm update] +0ms
testcontainers [DEBUG] [ec638beb98c3] Host port 55528 ready +2ms
testcontainers [DEBUG] [ec638beb98c3] Host port wait strategy complete +0ms
testcontainers:containers [ec638beb98c3] ping-pong@0.0.1 /app +6s
testcontainers:containers [ec638beb98c3] `-- express@4.21.1 +0ms
testcontainers:containers [ec638beb98c3] +0ms
testcontainers:containers [ec638beb98c3] npm WARN ping-pong@0.0.1 No repository field. +5ms
testcontainers:containers [ec638beb98c3] npm WARN ping-pong@0.0.1 No license field. +0ms
testcontainers:containers [ec638beb98c3] +20ms
testcontainers:containers [ec638beb98c3] [ping-pong] +1ms
testcontainers:containers [ec638beb98c3] ping-pong listening on http://localhost:80 +240ms
testcontainers [DEBUG] [ec638beb98c3] Internal port 80 ready +7s
testcontainers [INFO] [ec638beb98c3] Container is ready +0ms
testcontainers [DEBUG] [ec638beb98c3] Getting container by ID... +0ms
testcontainers [DEBUG] [ec638beb98c3] Got container by ID +0ms
testcontainers [DEBUG] Getting network by ID... +0ms
testcontainers [DEBUG] Got network by ID +0ms
Connecting container to network b
testcontainers [DEBUG] [ec638beb98c3] Connecting to network "33a686ac3a0725b8facfe86b90d31df75daaa56ca9882f9c6b13e1912f731820"... +0ms
testcontainers [DEBUG] [ec638beb98c3] Connected to network "33a686ac3a0725b8facfe86b90d31df75daaa56ca9882f9c6b13e1912f731820"... +110ms
AxiosError: read ECONNRESET
at Function.AxiosError.from (/Users/liam/Projects/Github/testcontainers-network/node_modules/axios/lib/core/AxiosError.js:92:14)
at RedirectableRequest.handleRequestError (/Users/liam/Projects/Github/testcontainers-network/node_modules/axios/lib/adapters/http.js:620:25)
at RedirectableRequest.emit (node:events:518:28)
at RedirectableRequest.emit (node:domain:489:12)
at ClientRequest.eventHandlers.<computed> (/Users/liam/Projects/Github/testcontainers-network/node_modules/follow-redirects/index.js:49:24)
at ClientRequest.emit (node:events:518:28)
at ClientRequest.emit (node:domain:489:12)
at emitErrorEvent (node:_http_client:103:11)
at Socket.socketErrorListener (node:_http_client:506:5)
at Socket.emit (node:events:518:28)
at Axios.request (/Users/liam/Projects/Github/testcontainers-network/node_modules/axios/lib/core/Axios.js:45:41)
at processTicksAndRejections (node:internal/process/task_queues:105:5) {
syscall: 'read',
code: 'ECONNRESET',
errno: -54,
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [ 'xhr', 'http', 'fetch' ],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function], Blob: [class Blob] },
validateStatus: [Function: validateStatus],
headers: Object [AxiosHeaders] {
Accept: 'application/json, text/plain, */*',
'Content-Type': undefined,
'User-Agent': 'axios/1.7.7',
'Accept-Encoding': 'gzip, compress, deflate, br'
},
baseURL: 'http://localhost:55528',
method: 'get',
url: '/ping',
data: undefined
},
request: <ref *1> Writable {
_events: {
close: undefined,
error: [Function: handleRequestError],
prefinish: undefined,
finish: undefined,
drain: undefined,
response: [Function: handleResponse],
socket: [Function: handleRequestSocket]
},
_writableState: WritableState {
highWaterMark: 65536,
length: 0,
corked: 0,
onwrite: [Function: bound onwrite],
writelen: 0,
bufferedIndex: 0,
pendingcb: 0,
[Symbol(kState)]: 17580812,
[Symbol(kBufferedValue)]: null
},
_maxListeners: undefined,
_options: {
maxRedirects: 21,
maxBodyLength: Infinity,
protocol: 'http:',
path: '/ping',
method: 'GET',
headers: [Object: null prototype],
agents: [Object],
auth: undefined,
family: undefined,
beforeRedirect: [Function: dispatchBeforeRedirect],
beforeRedirects: [Object],
hostname: 'localhost',
port: '55528',
agent: undefined,
nativeProtocols: [Object],
pathname: '/ping'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_eventsCount: 3,
_onNativeResponse: [Function (anonymous)],
_currentRequest: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: true,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
_header: 'GET /ping HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/1.7.7\r\n' +
'Accept-Encoding: gzip, compress, deflate, br\r\n' +
'Host: localhost:55528\r\n' +
'Connection: keep-alive\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/ping',
_ended: false,
res: null,
aborted: false,
timeoutCb: [Function: emitRequestTimeout],
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'localhost',
protocol: 'http:',
_redirectable: [Circular *1],
[Symbol(shapeMode)]: false,
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kChunkedBuffer)]: [],
[Symbol(kChunkedLength)]: 0,
[Symbol(kSocket)]: [Socket],
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kHighWaterMark)]: 65536,
[Symbol(kRejectNonStandardBodyWrites)]: false,
[Symbol(kUniqueHeaders)]: null
},
_currentUrl: 'http://localhost:55528/ping',
[Symbol(shapeMode)]: true,
[Symbol(kCapture)]: false
},
cause: Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:216:20) {
errno: -54,
code: 'ECONNRESET',
syscall: 'read'
}
}
testcontainers [DEBUG] [ec638beb98c3] Inspecting container... +23ms
testcontainers [DEBUG] [ec638beb98c3] Inspected container +5ms
Expected port: 55529 vs actual port: 55528
testcontainers [INFO] [ec638beb98c3] Stopping container... +0ms
testcontainers [DEBUG] [ec638beb98c3] Stopping container... +0ms
testcontainers [DEBUG] [ec638beb98c3] Stopped container +283ms
testcontainers [DEBUG] [ec638beb98c3] Removing container... +0ms
testcontainers [DEBUG] [ec638beb98c3] Removed container +49ms
testcontainers [INFO] [ec638beb98c3] Stopped container +0ms
testcontainers [INFO] Stopping network with ID "7d5be5268d87908a2d467086a20c8d6d0773cdd7c9c901b3417d68ef48ccf42e"... +0ms
testcontainers [DEBUG] Removing network "7d5be5268d87908a2d467086a20c8d6d0773cdd7c9c901b3417d68ef48ccf42e"... +0ms
testcontainers [DEBUG] Removed network "7d5be5268d87908a2d467086a20c8d6d0773cdd7c9c901b3417d68ef48ccf42e"... +106ms
testcontainers [INFO] Stopped network with ID "7d5be5268d87908a2d467086a20c8d6d0773cdd7c9c901b3417d68ef48ccf42e" +0ms
testcontainers [INFO] Stopping network with ID "33a686ac3a0725b8facfe86b90d31df75daaa56ca9882f9c6b13e1912f731820"... +0ms
testcontainers [DEBUG] Removing network "33a686ac3a0725b8facfe86b90d31df75daaa56ca9882f9c6b13e1912f731820"... +0ms
testcontainers [DEBUG] Removed network "33a686ac3a0725b8facfe86b90d31df75daaa56ca9882f9c6b13e1912f731820"... +139ms
testcontainers [INFO] Stopped network with ID "33a686ac3a0725b8facfe86b90d31df75daaa56ca9882f9c6b13e1912f731820" +0ms
Steps to Reproduce
I have created a small repository here to reproduce the issue.
There's a ReadMe included with the necessary instructions to run the project and see the issue (note that it's intermittent, so you might need to run it more than once)
Environment Information
I am seeing this in multiple environments (mac & windows)
Mac Information
ProductName: macOS
ProductVersion: 13.6
BuildVersion: 22G120
npm doctor:
❯ npm doctor
Connecting to the registry
Ok
Checking npm version
Ok
current: v10.9.0, latest: v10.9.0
Checking node version
Ok
current: v22.11.0, recommended: v22.11.0
Checking configured npm registry
Ok
using default registry (https://registry.npmjs.org/)
Checking for git executable in PATH
Ok
/usr/bin/git
Checking for global bin folder in PATH
Ok
/Users/liam/.nvm/versions/node/v22.11.0/bin
Checking permissions on cached files (this may take awhile)
Ok
Checking permissions on local node_modules (this may take awhile)
Ok
Checking permissions on global node_modules (this may take awhile)
Ok
Checking permissions on local bin folder
Ok
Checking permissions on global bin folder
Ok
Verifying cache contents (this may take awhile)
npm warn doctor verifyCachedFiles Content garbage-collected: 58 (106816249 bytes)
npm warn doctor verifyCachedFiles Cache issues have been fixed
Ok
verified 1970 tarballs