i want to create a websocket proxy which connect client in browser to a docker container. The docker host is open on tcp and am using dockerode which is JS sdk for docker. The requirement is to start an exec shell in the container and use that to read and write.
i am able to create the exec process in the container but am not able to stream data to and from the client to container.
wss.on("connection", async (ws) => {
const container = docker.getContainer("76941c597e89");
console.log("client connected");
const exec = await container.exec({
Cmd: ["/bin/sh"],
AttachStdin: true,
AttachStdout: true,
User: "root",
});
exec.start({ Tty: true, hijack: true }, (err, stream) => {
if (err) {
console.log(err);
}
stream?.on("data", (data) => {
ws.send(data.toString());
});
ws.on("message", (msg) => {
stream?.emit("data", msg);
});
});
});
I got it working. This is the final code.
wss.on("connection", async (ws, req) => {
const CONTAINER_ID = req.url?.split("=")[1];
try {
const container = docker.getContainer(CONTAINER_ID as string);
const exec = await container.exec({
Cmd: ["/bin/sh"],
AttachStdin: true,
AttachStdout: true,
User: "root",
Tty: true,
});
const stream = await exec.start({
stdin: true,
hijack: true,
Detach: false,
});
stream.on("data", (data) => {
ws.send(data.toString());
});
ws.on("message", (msg) => {
stream.write(msg);
});
ws.on("close", async () => {
stream.write("exit\n");
});
} catch (error) {
console.log(error);
ws.close();
}
});