@@ -7,11 +7,14 @@ import {
77import { env } from "../env.js" ;
88import { getDockerHostDomain , getRunnerId } from "../util.js" ;
99import Docker from "dockerode" ;
10+ import { tryCatch } from "@trigger.dev/core" ;
1011
1112export class DockerWorkloadManager implements WorkloadManager {
1213 private readonly logger = new SimpleStructuredLogger ( "docker-workload-manager" ) ;
1314 private readonly docker : Docker ;
1415
16+ private readonly runnerNetworks : string [ ] ;
17+
1518 constructor ( private opts : WorkloadManagerOptions ) {
1619 this . docker = new Docker ( ) ;
1720
@@ -20,6 +23,8 @@ export class DockerWorkloadManager implements WorkloadManager {
2023 domain : opts . workloadApiDomain ,
2124 } ) ;
2225 }
26+
27+ this . runnerNetworks = env . RUNNER_DOCKER_NETWORKS . split ( "," ) ;
2328 }
2429
2530 async create ( opts : WorkloadManagerCreateOptions ) {
@@ -67,10 +72,16 @@ export class DockerWorkloadManager implements WorkloadManager {
6772 }
6873
6974 const hostConfig : Docker . HostConfig = {
70- NetworkMode : env . DOCKER_NETWORK ,
7175 AutoRemove : ! ! this . opts . dockerAutoremove ,
7276 } ;
7377
78+ const [ firstNetwork , ...remainingNetworks ] = this . runnerNetworks ;
79+
80+ // Always attach the first network at container creation time. This has the following benefits:
81+ // - If there is only a single network to attach, this will prevent having to make a separate request.
82+ // - If there are multiple networks to attach, this will ensure the runner won't also be connected to the bridge network
83+ hostConfig . NetworkMode = firstNetwork ;
84+
7485 if ( env . ENFORCE_MACHINE_PRESETS ) {
7586 envVars . push ( `TRIGGER_MACHINE_CPU=${ opts . machine . cpu } ` ) ;
7687 envVars . push ( `TRIGGER_MACHINE_MEMORY=${ opts . machine . memory } ` ) ;
@@ -94,12 +105,71 @@ export class DockerWorkloadManager implements WorkloadManager {
94105 // Create container
95106 const container = await this . docker . createContainer ( containerCreateOpts ) ;
96107
108+ // If there are multiple networks to attach to we need to attach the remaining ones after creation
109+ if ( remainingNetworks . length > 0 ) {
110+ await this . attachContainerToNetworks ( {
111+ containerId : container . id ,
112+ networkNames : remainingNetworks ,
113+ } ) ;
114+ }
115+
97116 // Start container
98117 const startResult = await container . start ( ) ;
99118
100- this . logger . debug ( "create succeeded" , { opts, startResult, container, containerCreateOpts } ) ;
119+ this . logger . debug ( "create succeeded" , {
120+ opts,
121+ startResult,
122+ containerId : container . id ,
123+ containerCreateOpts,
124+ } ) ;
101125 } catch ( error ) {
102126 this . logger . error ( "create failed:" , { opts, error, containerCreateOpts } ) ;
103127 }
104128 }
129+
130+ private async attachContainerToNetworks ( {
131+ containerId,
132+ networkNames,
133+ } : {
134+ containerId : string ;
135+ networkNames : string [ ] ;
136+ } ) {
137+ this . logger . debug ( "Attaching container to networks" , { containerId, networkNames } ) ;
138+
139+ const [ error , networkResults ] = await tryCatch (
140+ this . docker . listNetworks ( {
141+ filters : {
142+ // Full name matches only to prevent unexpected results
143+ name : networkNames . map ( ( name ) => `^${ name } $` ) ,
144+ } ,
145+ } )
146+ ) ;
147+
148+ if ( error ) {
149+ this . logger . error ( "Failed to list networks" , { networkNames } ) ;
150+ return ;
151+ }
152+
153+ const results = await Promise . allSettled (
154+ networkResults . map ( ( networkInfo ) => {
155+ const network = this . docker . getNetwork ( networkInfo . Id ) ;
156+ return network . connect ( { Container : containerId } ) ;
157+ } )
158+ ) ;
159+
160+ if ( results . some ( ( r ) => r . status === "rejected" ) ) {
161+ this . logger . error ( "Failed to attach container to some networks" , {
162+ containerId,
163+ networkNames,
164+ results,
165+ } ) ;
166+ return ;
167+ }
168+
169+ this . logger . debug ( "Attached container to networks" , {
170+ containerId,
171+ networkNames,
172+ results,
173+ } ) ;
174+ }
105175}
0 commit comments