diff --git a/agent/app/service/runtime.go b/agent/app/service/runtime.go
index 9adb284ac..f143dae32 100644
--- a/agent/app/service/runtime.go
+++ b/agent/app/service/runtime.go
@@ -106,7 +106,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
if err := checkPortExist(int(portValue.(float64))); err != nil {
return nil, err
}
- case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo:
+ case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython:
if !fileOp.Stat(create.CodeDir) {
return nil, buserr.New(constant.ErrPathNotFound)
}
@@ -160,7 +160,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
if err = handlePHP(create, runtime, fileOp, appVersionDir); err != nil {
return nil, err
}
- case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo:
+ case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython:
runtime.Port = int(create.Params["port"].(float64))
if err = handleNodeAndJava(create, runtime, fileOp, appVersionDir); err != nil {
return nil, err
@@ -339,7 +339,7 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) {
}
}
res.AppParams = appParams
- case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo:
+ case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython:
res.Params = make(map[string]interface{})
envs, err := gotenv.Unmarshal(runtime.Env)
if err != nil {
@@ -400,6 +400,8 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) {
defaultVolumes = constant.RuntimeDefaultVolumes
case constant.RuntimeGo:
defaultVolumes = constant.GoDefaultVolumes
+ case constant.RuntimePython:
+ defaultVolumes = constant.RuntimeDefaultVolumes
}
for _, volume := range volumes {
exist := false
@@ -436,7 +438,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
if exist != nil {
return buserr.New(constant.ErrImageExist)
}
- case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo:
+ case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython:
if runtime.Port != req.Port {
if err = checkPortExist(req.Port); err != nil {
return err
@@ -512,7 +514,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
return err
}
go buildRuntime(runtime, imageID, oldEnv, req.Rebuild)
- case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo:
+ case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython:
runtime.Version = req.Version
runtime.CodeDir = req.CodeDir
runtime.Port = req.Port
@@ -678,7 +680,7 @@ func (r *RuntimeService) SyncRuntimeStatus() error {
return err
}
for _, runtime := range runtimes {
- if runtime.Type == constant.RuntimeNode || runtime.Type == constant.RuntimeJava || runtime.Type == constant.RuntimeGo {
+ if runtime.Type == constant.RuntimeNode || runtime.Type == constant.RuntimeJava || runtime.Type == constant.RuntimeGo || runtime.Type == constant.RuntimePython {
_ = SyncRuntimeContainerStatus(&runtime)
}
}
diff --git a/agent/app/service/runtime_utils.go b/agent/app/service/runtime_utils.go
index 87d4b985b..ddd4f646b 100644
--- a/agent/app/service/runtime_utils.go
+++ b/agent/app/service/runtime_utils.go
@@ -412,6 +412,14 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
if err != nil {
return
}
+ case constant.RuntimePython:
+ create.Params["CODE_DIR"] = create.CodeDir
+ create.Params["PYTHON_VERSION"] = create.Version
+ create.Params["PANEL_APP_PORT_HTTP"] = create.Port
+ composeContent, err = handleCompose(env, composeContent, create, projectDir)
+ if err != nil {
+ return
+ }
}
newMap := make(map[string]string)
@@ -457,6 +465,8 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${JAVA_APP_PORT}")
case constant.RuntimeGo:
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${GO_APP_PORT}")
+ case constant.RuntimePython:
+ ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${APP_PORT}")
}
for i, port := range create.ExposedPorts {
@@ -481,9 +491,7 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
var volumes []interface{}
defaultVolumes := make(map[string]string)
switch create.Type {
- case constant.RuntimeNode:
- defaultVolumes = constant.RuntimeDefaultVolumes
- case constant.RuntimeJava:
+ case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimePython:
defaultVolumes = constant.RuntimeDefaultVolumes
case constant.RuntimeGo:
defaultVolumes = constant.GoDefaultVolumes
diff --git a/agent/constant/runtime.go b/agent/constant/runtime.go
index 28c0967c4..6fbf18b25 100644
--- a/agent/constant/runtime.go
+++ b/agent/constant/runtime.go
@@ -15,10 +15,11 @@ const (
RuntimeCreating = "creating"
RuntimeStartErr = "startErr"
- RuntimePHP = "php"
- RuntimeNode = "node"
- RuntimeJava = "java"
- RuntimeGo = "go"
+ RuntimePHP = "php"
+ RuntimeNode = "node"
+ RuntimeJava = "java"
+ RuntimeGo = "go"
+ RuntimePython = "python"
RuntimeProxyUnix = "unix"
RuntimeProxyTcp = "tcp"
@@ -43,7 +44,7 @@ var GoDefaultVolumes = map[string]string{
}
var RuntimeDefaultVolumes = map[string]string{
- "./run.sh": "/run.sh",
- "./.env": "/.env",
- "./mod": "/go/pkg/mod",
+ "${CODE_DIR}": "/app",
+ "./run.sh": "/run.sh",
+ "./.env": "/.env",
}
diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index 1681eee8f..a296e2891 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -2534,6 +2534,8 @@ const message = {
envKey: 'Name',
envValue: 'Value',
environment: 'Environment Variable',
+ pythonHelper:
+ 'Please provide a complete start command, for example: pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000',
},
process: {
pid: 'Process ID',
diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts
index 88ce3a35e..75672ffd1 100644
--- a/frontend/src/lang/modules/tw.ts
+++ b/frontend/src/lang/modules/tw.ts
@@ -2351,6 +2351,8 @@ const message = {
envKey: '名稱',
envValue: '值',
environment: '環境變數',
+ pythonHelper:
+ '請填寫完整啟動指令,例如:pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000',
},
process: {
pid: '進程ID',
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 98f5d94fe..1982fcadf 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -2350,6 +2350,8 @@ const message = {
envKey: '名称',
envValue: '值',
environment: '环境变量',
+ pythonHelper:
+ '请填写完整启动命令,例如:pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000',
},
process: {
pid: '进程ID',
diff --git a/frontend/src/routers/modules/website.ts b/frontend/src/routers/modules/website.ts
index 7acb6044c..05ccd2c2f 100644
--- a/frontend/src/routers/modules/website.ts
+++ b/frontend/src/routers/modules/website.ts
@@ -78,6 +78,16 @@ const webSiteRouter = {
requiresAuth: false,
},
},
+ {
+ path: '/websites/runtimes/python',
+ name: 'python',
+ hidden: true,
+ component: () => import('@/views/website/runtime/python/index.vue'),
+ meta: {
+ activeMenu: '/websites/runtimes/php',
+ requiresAuth: false,
+ },
+ },
],
};
diff --git a/frontend/src/views/app-store/apps/index.vue b/frontend/src/views/app-store/apps/index.vue
index 5cd022049..27ef8be4e 100644
--- a/frontend/src/views/app-store/apps/index.vue
+++ b/frontend/src/views/app-store/apps/index.vue
@@ -243,16 +243,11 @@ const search = async (req: App.AppReq) => {
const openInstall = (app: App.App) => {
switch (app.type) {
case 'php':
- router.push({ path: '/websites/runtimes/php' });
- break;
case 'node':
- router.push({ path: '/websites/runtimes/node' });
- break;
case 'java':
- router.push({ path: '/websites/runtimes/java' });
- break;
case 'go':
- router.push({ path: '/websites/runtimes/go' });
+ case 'python':
+ router.push({ path: '/websites/runtimes/' + app.type });
break;
default:
const params = {
diff --git a/frontend/src/views/website/runtime/index.vue b/frontend/src/views/website/runtime/index.vue
index 7e403aa33..2fa8d18df 100644
--- a/frontend/src/views/website/runtime/index.vue
+++ b/frontend/src/views/website/runtime/index.vue
@@ -25,5 +25,9 @@ const buttons = [
label: 'Go',
path: '/websites/runtimes/go',
},
+ {
+ label: 'Python',
+ path: '/websites/runtimes/python',
+ },
];
diff --git a/frontend/src/views/website/runtime/python/index.vue b/frontend/src/views/website/runtime/python/index.vue
new file mode 100644
index 000000000..43d355be2
--- /dev/null
+++ b/frontend/src/views/website/runtime/python/index.vue
@@ -0,0 +1,267 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('runtime.create') }}
+
+
+
+
+
+
+
+ {{ row.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.port }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('website.check') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/website/runtime/python/operate/index.vue b/frontend/src/views/website/runtime/python/operate/index.vue
new file mode 100644
index 000000000..29326a4d9
--- /dev/null
+++ b/frontend/src/views/website/runtime/python/operate/index.vue
@@ -0,0 +1,332 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('runtime.pythonHelper') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('commons.button.cancel') }}
+
+ {{ $t('commons.button.confirm') }}
+
+
+
+
+
+