无法使用节点

时间:2018-01-02 23:04:49

标签: python node.js docker stdout

我有 server.js 文件,该文件使用 child_process 来调用 python 文件:

const express = require('express')
const app = express()
path = require('path');
fs = require('fs')

app.get('/call_script', function(req, res) {

  function_choice = req.query.function_choice   
  args_choice = req.query.args_choice

  // call python scripts
  var spawn = require("child_process").spawn;
  var process = spawn("python",["test.py", function_args]);

  process.stdout.on("data", function (data){
    from_python = data.toString("utf8");
    from_python = from_python.replace(/\n/g, " ").replace(/\\n/g, " "); 
    res.json({
       "answer" : from_python
    })

});

python文件:

function_args = sys.argv[1]

# ..... retrieve function and arguments from function_args

result = locals()[function_choice](*arr_n)

print(result)
sys.stdout.flush()

如果我在终端中运行节点server.js,它将运行该文件,完美地运行。我可以使用带Ajax的URL调用express端点。调用python文件并正确返回输出。没问题。

如果我现在将server.js放入 Docker 容器中,则python的输出未返回。没有错误或崩溃,只是没有。 Ajax调用只是挂起并且什么都不返回。

Dockerfile和package.json包含所有必需的命令和依赖项。我可以使用除了python输出之外的所有工作来运行容器。

我知道issues Docker / node和stdout ,但是我无法让python输出到容器之外。

如果我将 console.log 放在process.stdout.on 终端,Docker 日志则不显示任何内容。

是否与缓冲或冲洗有关?

修改

似乎它与模块不可用有关。例如,找不到matplotlib,但它在docker build期间安装。

这是我的 Dockerfile

FROM node:9

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./

RUN npm install

RUN apt-get update -y && \
    apt-get install -y python3 && \
    rm -rf /var/lib/apt/lists/*

RUN apt-get update -y
RUN apt-get -y install python3-pip

# Bundle app source
COPY . .

RUN pip3 install -r requirements.txt

EXPOSE 8899
CMD ["npm","start"]

这是我的 requirements.txt

matplotlib

EDIT2

pip3 show matplotlib

名称:matplotlib

版本:2.1.1

位置:/usr/local/lib/python3.4/dist-packages

需要:numpy,six,python-dateutil,pytz,cycler,pyparsing

import sys, for p in sys.path: print(p)

/usr/lib/python3.4

/usr/lib/python3.4/plat-x86_64-linux-gnu

/usr/lib/python3.4/lib-dynload

/usr/local/lib/python3.4/dist-packages

/ usr / lib中/ python3 / DIST-封装

1 个答案:

答案 0 :(得分:1)

tl; dr::在调用python可执行文件时添加-u选项。

如果我将console.log放在终端上的process.stdout。中,而Docker日志什么也没显示。
与缓冲或刷新有关吗?

是的,在我的测试过程中,似乎在使用默认节点Docker映像时,stdout文件的缓冲存在一些问题,就像在链接的问题https://github.com/nodejs/docker-node/issues/453中已经看到的那样。

在python文档中,sys.stdout部分对此进行了记录: https://docs.python.org/3/library/sys.html#sys.stdout

交互式时,stdout和stderr流是行缓冲的。否则,它们像常规文本文件一样被块缓冲。您可以使用-u命令行选项覆盖此值。

我通过使用附加-u选项调用python可执行文件解决了此问题,该选项强制将stdout和stderr流取消缓冲(https://docs.python.org/3/using/cmdline.html#cmdoption-u

对于您而言,以下内容可能会解决您的问题:

var process = spawn("python", ["-u", "test.py", function_args]);