docker / compose

Define and run multi-container applications with Docker
https://docs.docker.com/compose/
Apache License 2.0
33k stars 5.11k forks source link

[BUG] alpha watch <service> for 2.17.2 throws a runtime error and segmentation violation #10424

Closed shantanoo-desai closed 1 year ago

shantanoo-desai commented 1 year ago

Description

I am playing around with the alpha watch experimental setup with the following to see if I can play with configuration changes or at the least understand how could watch feature work.

Setup

I have a standard run-of-the-mill container called node-red available from DockerHub nodered/node-red. The image is used out of the box and not through a Dockerfile with its respective settings mounted as config .

Compose File docker-compose.nodered.yml

services:
  nodered:
    image: docker.io/nodered/node-red:3.0.1
    container_name: komponist_nodered
    configs:
      - nodered_settings
    user: "1000"
    entrypoint: node-red -s /nodered_settings
    logging:
      options:
        max-size: "5m"
    security_opt:
      - "no-new-privileges:true"
    x-develop:
      watch:
        - path: .
          action: sync
        - path: ./nodered/settings.js
          action: sync

configs:
  nodered_settings:
    file: ./nodered/settings.js

settings.js mounted as Docker Config

under nodered/settings.js the following content exists:

module.exports = {

    flowFile: 'flows.json',

    /** By default, credentials are encrypted in storage using a generated key. To
     * specify your own secret, set the following property.
     * If you want to disable encryption of credentials, set this property to false.
     * Note: once you set this property, do not change it - doing so will prevent
     * node-red from being able to decrypt your existing credentials and they will be
     * lost.
     */
    credentialSecret: "test",

    /** By default, the flow JSON will be formatted over multiple lines making
     * it easier to compare changes when using version control.
     * To disable pretty-printing of the JSON set the following property to false.
     */
    flowFilePretty: true,

     /** To password protect the Node-RED editor and admin API, the following
     * property can be used. See http://nodered.org/docs/security.html for details.
     */
    adminAuth: {
        type: "credentials",
        users: [
            {
                username: "admin",
                password: "$2b$08$vD9mLlYRTkJFTfmzqAD/Bea7a8wV53qGetUKWjOmHJlqmjvBc2xvS",
                permissions: "*"
            },{
                username: "ro_user",
                password: "$2b$08$TqtFcPpd6rtoaRrFeHnW/.DbKouK/LtS.PVzoa7VQzXFYuBupCBHS",
                permissions: "read"
            },
        ]
    },

    /** the tcp port that the Node-RED web server is listening on */
    uiPort: 1880,

    /** By default, the Node-RED UI is available at http://localhost:1880/
     * The following property can be used to specify a different root path.
     * If set to false, this is disabled.
     */
    httpAdminRoot: '/nodered1',

     /** Some nodes, such as HTTP In, can be used to listen for incoming http requests.
     * By default, these are served relative to '/'. The following property
     * can be used to specify a different root path. If set to false, this is
     * disabled.
     */
    httpNodeRoot: '/nodered',

    /** Configure diagnostics options
     * - enabled:  When `enabled` is `true` (or unset), diagnostics data will
     *   be available at http://localhost:1880/diagnostics
     * - ui: When `ui` is `true` (or unset), the action `show-system-info` will
     *   be available to logged in users of node-red editor
    */
    diagnostics: {
        /** enable or disable diagnostics endpoint. Must be set to `false` to disable */
        enabled: true,
        /** enable or disable diagnostics display in the node-red editor. Must be set to `false` to disable */
        ui: true,
    },

    /** Configure runtimeState options
     * - enabled:  When `enabled` is `true` flows runtime can be Started/Stopped
     *   by POSTing to available at http://localhost:1880/flows/state
     * - ui: When `ui` is `true`, the action `core:start-flows` and
     *   `core:stop-flows` will be available to logged in users of node-red editor
     *   Also, the deploy menu (when set to default) will show a stop or start button
     */
    runtimeState: {
        /** enable or disable flows/state endpoint. Must be set to `false` to disable */
        enabled: true,
        /** show or hide runtime stop/start options in the node-red editor. Must be set to `false` to hide */
        ui: true,
    },

    /** The following property can be used to disable the editor. The admin API
     * is not affected by this option. To disable both the editor and the admin
     * API, use either the httpRoot or httpAdminRoot properties
     */
    disableEditor: false,

    /** Customising the editor
     * See https://nodered.org/docs/user-guide/runtime/configuration#editor-themes
     * for all available options.
     */
    editorTheme: {
        /** To disable the 'Welcome to Node-RED' tour that is displayed the first
         * time you access the editor for each release of Node-RED, set this to false
         */
        tours: false,
    },

    logging: {
        console: {
            level: "info"
        },
    },

    /** Allow the Function node to load additional npm modules directly */
    functionExternalModules: true,

    /** If you installed the optional node-red-dashboard you can set it's path
     * relative to httpNodeRoot
     * Other optional properties include
     *  readOnly:{boolean},
     *  middleware:{function or array}, (req,res,next) - http middleware
     *  ioMiddleware:{function or array}, (socket,next) - socket.io middleware
     */
    ui: { path: "ui" },

    /** Colourise the console output of the debug node */
    debugUseColors: true,

    /** The maximum length, in characters, of any message sent to the debug sidebar tab */
    debugMaxLength: 1000,

    /** Maximum buffer size for the exec node. Defaults to 10Mb */
    execMaxBufferSize: 10000000,

    /** Timeout in milliseconds for HTTP request connections. Defaults to 120s */
    httpRequestTimeout: 120000,

    /** Retry time in milliseconds for MQTT connections */
    mqttReconnectTime: 15000,

    /** Retry time in milliseconds for Serial port connections */
    serialReconnectTime: 15000,
}

FileSystem Structure

- nodered
  - settings.js
- docker-compose.nodered.yml

Steps To Reproduce

For the filesystem structure above perform the following:

docker compose -f docker-compose.nodered.yml up -d && \
docker compose -f docker-compose.nodered.yml alpha watch nodered

The container is brought up but the watch breaks with a panic


[+] Running 1/0
 ✔ Container komponist_nodered  Running                                                                                                                                                                     0.0s
watch command is EXPERIMENTAL
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x19f0a02]

goroutine 1 [running]:
github.com/docker/compose/v2/pkg/compose.(*composeService).Watch(0xc0000aaa40, {0x22545e0, 0xc0000b6000}, 0xc000653760, {0xc0003ad190, 0x1, 0x1}, {})
        github.com/docker/compose/v2/pkg/compose/watch.go:120 +0x3e2
github.com/docker/compose/v2/pkg/api.(*ServiceProxy).Watch(0xc000634a80?, {0x22545e0?, 0xc0000b6000?}, 0x0?, {0xc0003ad190?, 0xc0000561b0?, 0x413ecb?}, {})
        github.com/docker/compose/v2/pkg/api/proxy.go:323 +0x47
github.com/docker/compose/v2/cmd/compose.runWatch({0x22545e0, 0xc0000b6000}, {0x226b150, 0xc0003bc1e0}, {0xc000634a80?, 0x78?}, {0xc0003ad190, 0x1, 0x1})
        github.com/docker/compose/v2/cmd/compose/watch.go:60 +0xf9
github.com/docker/compose/v2/cmd/compose.watchCommand.func2({0x22545e0?, 0xc0000b6000?}, {0xc0003ad190?, 0xc0000061a0?, 0x19f799a?})
        github.com/docker/compose/v2/cmd/compose/watch.go:44 +0x50
github.com/docker/compose/v2/cmd/compose.Adapt.func1({0x22545e0?, 0xc0000b6000?}, 0x2?, {0xc0003ad190?, 0x1?, 0x0?})
        github.com/docker/compose/v2/cmd/compose/compose.go:92 +0x36
github.com/docker/compose/v2/cmd/compose.AdaptCmd.func1(0xc0003fc900, {0xc0003ad190, 0x1, 0x1})
        github.com/docker/compose/v2/cmd/compose/compose.go:71 +0x21c
github.com/spf13/cobra.(*Command).execute(0xc0003fc900, {0xc000251610, 0x1, 0x1})
        github.com/spf13/cobra@v1.6.1/command.go:916 +0x862
github.com/spf13/cobra.(*Command).ExecuteC(0xc0003fcf00)
        github.com/spf13/cobra@v1.6.1/command.go:1044 +0x3bd
github.com/spf13/cobra.(*Command).Execute(...)
        github.com/spf13/cobra@v1.6.1/command.go:968
github.com/docker/cli/cli-plugins/plugin.RunPlugin(0xcb11b2f0b8?, 0xc000157200, {{0x1f19ac7, 0x5}, {0x1f232f1, 0xb}, {0x22319a8, 0x7}, {0x0, 0x0}, ...})
        github.com/docker/cli@v23.0.1+incompatible/cli-plugins/plugin/plugin.go:51 +0x130
github.com/docker/cli/cli-plugins/plugin.Run(0x2037fb8, {{0x1f19ac7, 0x5}, {0x1f232f1, 0xb}, {0x22319a8, 0x7}, {0x0, 0x0}, {0x0, ...}, ...})
        github.com/docker/cli@v23.0.1+incompatible/cli-plugins/plugin/plugin.go:64 +0xee
main.pluginMain()
        github.com/docker/compose/v2/cmd/main.go:36 +0xdf
main.main()
        github.com/docker/compose/v2/cmd/main.go:68 +0x198

Compose Version

Docker Compose version v2.17.2

Docker Environment

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.10.4
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.17.2
    Path:     /usr/libexec/docker/cli-plugins/docker-compose
  scan: Docker Scan (Docker Inc.)
    Version:  v0.23.0
    Path:     /usr/libexec/docker/cli-plugins/docker-scan

Server:
 Containers: 114
  Running: 1
  Paused: 0
  Stopped: 113
 Images: 105
 Server Version: 23.0.2
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1e1ea6e986c6c86565bc33d52e34b81b3e2bc71f
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 5.15.90.1-microsoft-standard-WSL2
 Operating System: Ubuntu 20.04.6 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 12
 Total Memory: 15.44GiB
 Name: 2KLD7G3
 ID: MYHY:EIJP:PMP7:PWBG:NBK7:7VYY:WZTK:RGPO:5SSH:OIEW:4JMF:VZH7
 Docker Root Dir: /home/shantanoo/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Experimental: false
 Insecure Registries:
  artifactory.emrsn.org
  docker.aug
  127.0.0.0/8
 Registry Mirrors:
  http://gblonaspengap0c.emrsn.org:5500/
 Live Restore Enabled: false

WARNING: No swap limit support

Anything else?

Note

On the slack channel #docker-compose @glours was kind enough to point out that the alpha watch feature is meant for a build based service with a dedicated Dockerfile, which is not the case here and I understand that maybe this Issue may not be valid for run-of-the-mill containers.

If so, please close this issue, if not I hope this issue helps solve a problem for the alpha watch feature not previously known.

shantanoo-desai commented 1 year ago

Update

Based on discussions with @ndeloof the current alpha spec for watch is meant for observation when build is part of the service and not for ready-to-use containers