diff --git a/bin/cmds/app/run.js b/bin/cmds/app/run.js index 9532870c..ab50862c 100644 --- a/bin/cmds/app/run.js +++ b/bin/cmds/app/run.js @@ -40,6 +40,11 @@ exports.builder = (yargs) => { default: undefined, type: 'string', description: 'Path to the Docker socket.', + }) + .option('docker-exposed-ports', { + default: [], + type: 'array', + description: 'Docker exposed ports, i.e. `6113/tcp` or `5683/udp`. Only works when running the app inside docker.', }); }; exports.handler = async (yargs) => { @@ -52,6 +57,7 @@ exports.handler = async (yargs) => { linkModules: yargs.linkModules, network: yargs.network, dockerSocketPath: yargs.dockerSocketPath, + dockerExposedPorts: yargs.dockerExposedPorts, }); } catch (err) { if (err instanceof Error && err.stack) { diff --git a/lib/App.js b/lib/App.js index a8012d83..1202eae5 100644 --- a/lib/App.js +++ b/lib/App.js @@ -165,6 +165,7 @@ class App { linkModules = '', network, dockerSocketPath, + dockerExposedPorts = [], } = {}) { const homey = await AthomApi.getActiveHomey(); @@ -193,6 +194,7 @@ class App { linkModules, network, dockerSocketPath, + dockerExposedPorts, }); } @@ -238,6 +240,7 @@ class App { linkModules, network, dockerSocketPath, + dockerExposedPorts, }) { // Prepare Docker const dockerOptions = {}; @@ -770,9 +773,37 @@ class App { }, }; + const exposedPorts = []; + if (Array.isArray(dockerExposedPorts)) { + const portRegex = /^\d+$/; + const portWithProtocolRegex = /^(\d+)\/(udp|tcp)$/; + dockerExposedPorts.forEach((port) => { + let portNumber; + let portProtocol; + if (portRegex.test(port)) { + portNumber = port; + portProtocol = 'tcp'; + } else if (portWithProtocolRegex.test(port)) { + const matches = portWithProtocolRegex.exec(port); + portNumber = matches[1]; + portProtocol = matches[2]; + } else { + throw new Error(`The requested port "${port}" is not valid`); + } + + const dockerPort = `${portNumber}/${portProtocol}`; + createOpts.ExposedPorts[dockerPort] = {}; + createOpts.HostConfig.PortBindings[dockerPort] = [{ + HostPort: `${portNumber}`, + }]; + exposedPorts.push(dockerPort); + }); + } + Log.success(`Starting debugger at 0.0.0.0:${inspectPort}...`); Log.info(' — Open `about://inspect` in Google Chrome and select the remote target.'); Log.success(`Starting \`${manifest.id}@${manifest.version}\` in a Docker container...`); + exposedPorts.forEach((port) => Log.info(` — Exposing Docker port ${port} on local machine...`)); Log.info(' — Press CTRL+C to quit.'); Log('─────────────── Logging stdout & stderr ───────────────');