ps2goat
ps2goat

Reputation: 8475

Can't debug when using `docker-compose run`, but `docker-compose up` works

I can create a test repo, if needed. But the gist of this issue is that I am able to debug a Docker image created by docker-compose, when I use the up command. I am NOT able to debug the same container when using the run command. In both cases, I can see my app start. The vs code debugger just doesn't seem to be able to connect to the docker container when using docker-compose run.

This is similar to my working launch task in vs code (one the debugger can connect to):

{
  "type": "node",
  "request": "launch",
  "name": "Docker: Debug",
  "runtimeExecutable": "docker-compose",
  "runtimeArgs": [
    "up"
  ],
  "port": 9229,
  "stopOnEntry": true,
  "restart": true,
  "timeout": 30000,
  "localRoot": "${workspaceRoot}",
  "remoteRoot": "/app",
  "outFiles": [ "${workspaceRoot}/dist/**/*.js" ],
  "console": "externalTerminal",
  "internalConsoleOptions": "neverOpen",
  "protocol": "inspector",
  "showAsyncStacks": true
}

My docker-compose file also specifies a command here (npm run start-app, for example), with start-app having the following definition:

nodemon --legacy-watch --watch ./dist/app1 --inspect=0.0.0.0:9229 --nolazy ./dist/app1/index.js

Why I have a problem:

I don't want a command specified in the docker-compose.yml file because I have one image with multiple processes inside. (There will be one container-per-process, but they all share the same image.) I currently have this working for a kubernetes deployment and local development run/debug. I'd like to get this running and debugging in a container by starting the container with a specified command.

I want to be able to run the container and specify which app to run in my vs code launch.json file, similar to the below:

{
  "type": "node",
  "request": "launch",
  "name": "Docker: Debug",
  "runtimeExecutable": "docker-compose",
  "runtimeArgs": [
        "run",
        "all",
        "npm",
        "run",
        "start-app"
  ],
  "port": 9229,
  "stopOnEntry": true,
  "restart": true,
  "timeout": 30000,
  "localRoot": "${workspaceRoot}",
  "remoteRoot": "/app",
  "outFiles": [ "${workspaceRoot}/dist/**/*.js" ],
  "console": "externalTerminal",
  "internalConsoleOptions": "neverOpen",
  "protocol": "inspector",
  "showAsyncStacks": true
}

FYI, the all in the arg list refers to the name of my service in the docker-compose.yml file.

Upvotes: 1

Views: 1372

Answers (1)

ps2goat
ps2goat

Reputation: 8475

A colleague found the following snippet in the documentation for docker-compose run:

...the docker-compose run command does not create any of the ports specified in the service configuration. This prevents port collisions with already-open ports. If you do want the service's ports to be created and mapped to the host, specify the --service-ports flag

So I changed my arguments for the launch task to include this flag, and it now works.

"runtimeArgs": [
    "run",
    "--service-ports",
    "all",
    "npm",
    "run",
    "start-app"
],

For re-clarification, --service-ports tells docker compose to honor my port mappings in the docker-compose.yml file, which the up command does by default. all is the name of my service in the docker-compose.yml file, and the rest of the command is npm run start-app, where start-app is my custom script in the package.json file.

Upvotes: 1

Related Questions