- 全程使用docker方式部署
- 本地采用非标准端口部署,即非标准80端口
- 运行python,print (“hello world”),正常反馈结果
- 尝试python, base.auth() 时,反馈错误,超时
from seatable_api import Base, context
base = Base(context.api_token, context.server_url)
base.auth()
- 查看本地日志,/python-pipeline/logs/scheduler-logs/nginx.error.log
[error] 754#754: *51 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.192.5, server: _, request: "GET /run-script/26/?dtable_uuid=d5b9a51d-1d9b-47a4-aa13-f361f5847045&script_name=W938.py HTTP/1.1", upstream: "http://[::1]:5055/run-script/26/?dtable_uuid=d5b9a51d-1d9b-47a4-aa13-f361f5847045&script_name=W938.py", host: "python-scheduler"
基本就是超时错误,怎么处理?
确认docker容器都运行了,网络也构建了
您好,您是在同一台服务器上部署的是吗?可以提供下相关 docker-compose.yml python-pipeline.yml 及 .env 文件吗?
同一台机上部署,都是docker镜像。按官方最新教程配的。
即:
附配置文件:
针对部署时使用的是非标准端口,对配置文件相应改8080端口,其他不变
具体地:
- docker-compose.yml
- 8080:80 仅变更对外端口为8080,其余没变
- python-pipeline.yml
- SEATABLE_SERVER_URL=${SEATABLE_SERVER_PROTOCOL}://${SEATABLE_SERVER_HOSTNAME}:8080
-
env
SEATABLE_SERVER_HOSTNAME=
PYTHON_SCHEDULER_AUTH_TOKEN= 已设置UUID
-
seatable-data/seatable/conf/dtable_web_settings.py 增加:
SEATABLE_FAAS_URL = ‘http://python-scheduler’
SEATABLE_FAAS_AUTH_TOKEN = 一致的UUID
现在情况
- 正常的Py脚本可以运行,如helloworld,有输出正确结果
- 但是鉴权,auth(),执行会报错,超时
您配置中的 python-pipeline.yml 中的 SEATABLE_SERVER_URL 恢复为默认,去掉 :8080 试下
一样的错误。实际上,一开始就没有加8080,报超时错误。取不取消,效果一样。
从scheduler-logs上看到错误日志?
[error] 754#754: *77 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.240.5, server: _, request: “GET /run-script/54/?dtable_uuid=d5b9a51d-1d9b-47a4-aa13-f361f5847045&script_name=W938.py HTTP/1.1”, upstream: “http://[::1]:5055/run-script/54/?dtable_uuid=d5b9a51d-1d9b-47a4-aa13-f361f5847045&script_name=W938.py”, host: “python-scheduler”
base = Base(context.api_token, context.server_url)
改成 base = Base(api_token, server_url)试试
bro,你认真的吗?肯定会报错,变量未定义呀… 我输出过值的
context.api_token, context.server_url 这两个变量有正确值输出,没问题?
抱歉, 我看错了自己的脚本
你这个提示应该是seatable找不到python scheduler docker服务器
你看下docker 网络是不是正常的, 特别是seatable mysql python scheduler那三个docker 要在同一个docker网络, 因为内部通讯都是靠 ‘[http://python-scheduler ]来访问的
确认问题的根源:在于容器之间的网络连通问题
具体来说,py脚本运行依次涉及容器:seatable → python-scheduler → python-starter → python-runner
上述seatable → python-scheduler → python-starter,这三者的网络连通正常,都是挂载在 frontend-net 下的内部网络中。
而实际脚本是运行在runner容器中的,由starter创建运行销毁,所以闲时看不到
实际runner是挂载在 bridge 默认的内部网络中。
问题的具体原因,在于runner可以访问到seatable,但seatable回应不了runner。
临时的解决方法,将 seatable 也添加至 bridge 网络。这样,鉴权成功!
但是,反馈的消息,反馈的 seatable 服务器的IP是宿主机的(反正不是bridge的IP),所以导致无法下一步base的使用操作…(应该要配置?)
… 做到这!是不是哪一个关于网络的配置我搞错了呢?导致这个连锁问题?
现在的情况:
- 本地可以运行脚本,可以鉴权,可以操作表单(正常)
- 云端无法运行脚本。可以鉴权,但是无法继续base操作
折衷方法,可以把鉴权部分的代码展开,就可以继续用了。这部分代码开源
根本方法,还是要解决runner和seatable-server之间的网络
seatable python 内部部署
部署环境
- 系统:Windows11内Ubuntu 20.04.6 LTS子系统
- dtable_web_settings.py:
DTABLE_WEB_SERVICE_URL='http://127.0.0.1/'
- .env:
PYTHON_STARTER_ALTERNATIVE_FILE_SERVER_ROOT=http://seatable
调整步骤
- 容器:python-starter
- 文件:runner.py
- 步骤:在python-runner容器启动参数里指定下network,然后Base鉴权的时候server_url改用
http://seatable
def run_python(data):
...原代码
logging.debug("prepare the command to start the python runner")
container_name = "python-runner" + tmp_id
command = [
"docker",
"run",
"--name",
container_name,
"--env-file",
env_file,
"-v",
"{}:/scripts".format(tmp_dir),
"--network=backend-seatable-net" # 指定容器网络
]
logging.debug("command: %s", command)
- 容器:seatable
- 文件:/opt/seatable/seatable-server-latest/dtable-web/seahub/api2/endpoints/dtable_api_token.py
- 步骤:引入re正则库,替换DTableAppAccessTokenView返回值中的链接
import re
class DTableAppAccessTokenView(APIView):
throttle_classes = (AppRateThrottle,)
def get(self, request):
# 原代码
host = request.build_absolute_uri().replace(request.path, '').strip("/") + "/"
if host not in dtable_server_url:
dtable_server_url = re.sub(r"https?://.*?/", host, dtable_server_url)
dtable_socket_url = dtable_server_url
if host not in DTABLE_DB_URL:
dtable_db = re.sub(r"https?://.*?/", host, DTABLE_DB_URL)
else:
dtable_db = DTABLE_DB_URL
return Response({
'app_name': app_name,
'access_token': access_token,
'dtable_uuid': str(dtable.uuid),
'dtable_server': dtable_server_url,
'dtable_socket': dtable_socket_url,
# 'dtable_db': DTABLE_DB_URL,
'dtable_db': dtable_db,
'workspace_id': workspace_id,
'dtable_name': dtable.name,
'use_api_gateway': True,
})
from seatable_api import Base, context
base = Base(context.api_token, 'http://seatable')
base.auth()
print(base)