首页 > 解决方案 > dockerode,如何使容器中运行的进程独立于节点进程?

问题描述

dockerode我正在开发一个用于容器管理的小型应用程序。我正在尝试使在 docker 容器中运行的进程独立于node进程。

基本上我想要实现的是,如果节点进程在重新启动后崩溃,它可以重新连接到正在运行的容器并继续,就好像什么都没发生一样。

我遇到的问题即使容器本身独立于节点,容器内的进程也不是,如果节点被杀死,docker容器中的进程也是如此。有没有办法将容器中的进程与节点进程分离?

创建容器并重新附加到它的函数如下:

function createContainer() {
    docker.createContainer({
        Image: 'ubuntu',
        Tty: true,
        Cmd: ['/bin/bash']
    }, function (err, container) {
        if (err) return;

        container.start({}, function (err, data) {
            const stream = fs.createWriteStream('./containerID.json');
            stream.write(JSON.stringify({
                containerID: container.id
            }));

            shell.exec(`docker cp ./script.sh ${container.id}:/`) // copy the file to the container

            runExec(container);
        });
    });
}

exports.containerAttach = (container) => {
    container.attach({
        stream: true,
        stdout: true,
        stderr: true
    }, function (err, stream) {
        stream.pipe(process.stdout);
    })
}

标签: node.jsdocker

解决方案


该容器最初是使用空闲的 BASH shell 创建的。

docker.createContainer({
        Image: 'ubuntu',
        Tty: true,
        Cmd: ['/bin/bash']
    },...)

当附加函数运行时,它附加到这个空闲的 TTY。解决方案是切换到docker.run()然后附加到正在运行的进程。

docker.run('node', ['./home/run-in-container.sh'], false, {
        Hostconfig: {
            Binds: [`${__dirname}:/home`]
        }
    }, {}, (err, data, container) => {
        if (err) throw err;
        console.log(data.StatusCode)
        console.log(container)
    })
    .on('container', (container) => {
        setTimeout(() => {
            fs.writeFileSync(path.join(__dirname, 'container.json'), JSON.stringify({
                id: container.id
            }));
            process.exit(0);
        }, 5000)
    })
    .on('stream', (stream) => {
        stream.on('data', data => console.log('-- STREAM --\n', data.toString()));
    })
    .on('data', (data) => {
        console.log('data', data);
    });

attach 函数基本保持不变,但稍作修改以匹配新的 run 函数。

container.attach({
        stream: true,
        stderr: true,
        stdout: true
    }, (err, stream) => {
        if (err) console.log(`The container has ${container.id} been removed:\n\n${err}`);
        console.log(`Reattached to container: ${container.id}`);

        stream.on('data', (data) => console.log('-- STREAM --\n', data.toString()));
        stream.on('end', () => {
            console.log('\n-- STREAM END --')
        });
    });

推荐阅读