node.jsdockerdockerode

dockerode stream "data" listener echoes write data


I'm trying to figure out why dockerode stream directs all data written to the stream directly to the output of the stream.

This is how I create the container, I call the .write() method on the this.stream object.

        this.container = await this.dockerConnection.createContainer({
            Image: this.image,
            Tty: true,
            Cmd: cmd,
            HostConfig: {
                NetworkMode: "none",
                Binds: [this.mountPath + ":/home/appuser/workdir"],
            },
            OpenStdin: true,
            StdinOnce: false,
            AutoRemove: true,
        });

        this.stream = await this.container.attach({
            stream: true,
            stdin: true,
            stdout: true,
            stderr: true,
        });

        await this.container.start();

However after connecting this stream to a websocket which is connected to xterm.js, I noticed if I launch a shell like /bin/sh through the cmd argument and write to the resulting this.stream, the commands I run are echoed back to me on the this.stream.on("data", ...) listener.

For eg if I write ls\n, the data passed into the .on("data",...) looks like

ls
bin/ etc/ lib/ ... (etc.)

How do I prevent it from echoing the "ls" back to me?

Here is the code for the stream write and reads on the server:

    let sb = new Sandbox("alpine-sandbox");

    let stream = await sb.launchSHShell();

    stream.on("data", (data) => {
        socket.emit("response", data.toString());
    })

    socket.on("command", (cmd) => {
        stream.write(cmd);
    })



Solution

  • Okay, my current hack to solve this problem is to only read every other on("data", ...) response. I noticed that the data listener is called twice, once for the command I wrote and the next for the actual output from the shell. So reading every other response prevents this echo. Still looking for a better solution though.