Node.js 使用JavaScript/Node访问docker上的文件

Node.js 使用JavaScript/Node访问docker上的文件,node.js,docker,Node.js,Docker,是否有一种方法可以在执行期间以编程方式访问容器(docker)上的文件。我尝试使用node docker api只是为了在第一个实例中进行设置,并建立连接: const docker = new Docker({ "host": "tcp://docker:port" }); // List docker.container.list() // Inspect .then(containers => containers[0].status()) .then(co

是否有一种方法可以在执行期间以编程方式访问容器(docker)上的文件。我尝试使用node docker api只是为了在第一个实例中进行设置,并建立连接:

const docker = new Docker({
    "host": "tcp://docker:port"
});

// List
docker.container.list()
// Inspect
    .then(containers => containers[0].status())
    .then(container => container.top())
    .then(processes => console.log(processes))
    .catch(error => console.log(error));
其中“端口”是4位端口号。但我得到了这个错误信息:

{ Error: connect ECONNREFUSED 127.0.0.1:80
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1081:14)
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 80 }
更新: 我在Java中使用dockerjava和httphijack做了类似的事情-


但是我似乎找不到一种使用javascript/node实现上述功能的方法,因为容器中的文件是短暂的,如果代码以某种方式依赖于这些文件,那么应该小心

最佳实践是用于存储数据。 在您的情况下,如果您可以将文件存储在docker卷中,那么您可以从另一个容器运行代码,并从中查看这些文件。因此,容器将共享相同的存储,这不是短暂的,并且在容器重新启动后仍然有效

如果docker卷不是您的情况,那么我脑海中唯一的想法就是使用,尤其是使用一种方法

使用此方法,您可以在容器中执行Linux命令


更新1: 如果程序在主机上运行,并且需要访问docker卷生成的数据,则还可以将主机目录绑定到docker容器内的目录

例如:
docker run-v/host/folder:/container/folder

这样,docker文件夹中的任何更改都将反映在主机中的文件夹上,以便您可以访问它们


更新2: 您可以使用Docker REST API以以下方式在Docker容器内执行命令:

  • 启用对REST API的TCP访问: 编辑
    /lib/systemd/system/docker.service
    并更改下一行:
    ExecStart=/usr/bin/dockerd-g/data/docker-H fd://
    to
    ExecStart=/usr/bin/dockerd-H fd://-Htcp://0.0.0.0:2375
    然后保存文件。 然后
    systemctl守护进程重新加载
    服务docker重新启动
    。现在您应该可以在
    http://127.0.0.1:2375
    -您应该得到
    {“消息”:“未找到页面”}
    作为响应

  • 使用RESTAPI创建Exec对象,示例:

  • 在这里:

    • dockerVersion
      -可以使用
      docker version
      命令检索docker引擎的版本(请参阅服务器的版本,在我的例子中是1.38-因此在URL中类似于v1.38不要忘记
      v
    • containerId
      -您在docker中的容器id,可以通过以下命令检索:
      curlhttp://127.0.0.1:2375/v{dockerVersion}/containers/json
    作为对
    /containers/{containerId}/exec
    的响应,您应该得到如下内容:
    {“Id”:“{objectId}”}

  • 执行以前创建的命令:
  • 在这里:

    • objectId
      -在上一步(步骤2)中从docker API返回的id
    作为响应,您应该得到一个纯文本—您的命令的输出


    注意:JSON正文中的
    Cmd
    是一个数组,因此您可以指定多个命令。

    您可以使用Docker API/getAchive方法从容器中提取文件,然后将其解压 在服务器端使用docker API的NodeJS实现

    然后导入它并运行文件所在的容器

    var Docker=require('dockerode');
    var docker=new docker({socketPath:'/var/run/docker.sock'})//或者任何通向你插座的路径
    let file=“abs/path/in/container/somefile.file”
    let tag=“docekerImageTag”//“repo/image”//“johndoe/docker\u image”
    runContainer(标记为“foo”)。然后(container=>{
    getFile(容器、文件、ws)
    })
    函数runContainer(containerName,param){
    返回docker.run(
    容器名称,
    ['Rscript','random.Rscript','-test','${param}',],
    [process.stdout,process.stderr],{Tty:false},//如果不需要拆分,只发送stdout不需要Tty
    ).then(功能(数据){
    var输出=数据[0]
    var容器=数据[1]
    返回容器
    },rej=>{
    console.log({rej})
    返回rej
    }
    )
    }
    函数getFile(容器、文件、ws){
    getArchive({path:file})。然后(file=>{
    if(ws)ws.sendMsg(file)//将它发送到某个我正在使用websocket的地方。这将为您提供一个带有tar文件的流。
    //使用websocket,您可能需要解析BufferList,迭代地发送缓冲区并在另一端组装它
    //write(文件,路径,“UTF8”)是另一个选项。尽管我认为您仍然需要迭代“fs”的缓冲区列表
    })
    }
    
    如果您想立即使用该文件,请不要忘记解除对其的授权


    还有一个客户端JavaScript包,用于解压流调用。一旦通过websocket/other将流调用发送到客户端,该调用就可以正常工作。

    感谢这些链接。我需要访问的文件是在执行过程中生成的,需要在几秒钟后访问,也就是说,需要复制到运行代码的工作目录中来自和处理。您是否有任何关于如何使用您建议的方法与容器交互的示例。我在你提供的链接上找不到任何例子。感谢您将生成的文件存储在docker卷中吗?基本上,我正在使用selenium docker运行一些selenium UI测试。在这些测试中,文件会被下载,下载后我会尝试访问它们。测试将作为CI流程的一部分在Jenkins上运行。请参阅我的更新答案。您可以将docker中的selenium文件夹绑定到主机目录并访问其中的文件。但也许应该有一些优雅的解决方案。我不熟悉selenium。如果我是唯一一个使用该容器的人,那将是一个很好的解决方案,但事实并非如此。与其使用每个人都可以访问的主机文件夹运行docker,不如使用ac
    ExecCreateCmdResponse execCreateResp = dck.execCreateCmd(cid).withCmd("bash")
            .withAttachStderr().withAttachStdout().withAttachStdin().withTty(false).exec();
    
    HashMap<String, String> headers = new HashMap<>();
    headers.put("Content-Type", "application/json");
    
    HttpHijack ws = new HttpHijack(new URI("http://127.0.0.1:2376/v1.19/exec/" + execCreateResp.getId() + "/start"));
    String payload = "{\"Detach\": false,\"Tty\": false}";
    ws.post(headers, payload);
    
    try (TarArchiveInputStream tarStream = new TarArchiveInputStream(
        docker.copyArchiveFromContainerCmd(containerId, "/home/seluser/Downloads/" + fileName).exec())) {
        unTar(tarStream, new File(filePath));
        return;
    }catch(NotFoundException e){
        e.printStackTrace();
    }
    
    curl --header "Content-Type: application/json" \
      --request POST \
      --data '{"AttachStdout": true,"AttachStderr": true,"Cmd": ["date"]}' \
    http://127.0.0.1:2375/v{dockerVersion}/containers/{containerId}/exec 
    
    curl --header "Content-Type: application/json" \
      --request POST \
      --data '{"Detach": false,"Tty": false}' \
    http://127.0.0.1:2375/v{dockerVersion}/exec/{objectId}/start
    
     npm i dockerode