我有 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-封装
答案 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]);