diff --git a/backend/app/service/backup_website.go b/backend/app/service/backup_website.go index da0c659b0..e8273bb6e 100644 --- a/backend/app/service/backup_website.go +++ b/backend/app/service/backup_website.go @@ -154,7 +154,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback if err != nil { return err } - if runtime.Type == constant.RuntimeNode { + if runtime.Type == constant.RuntimeNode || runtime.Type == constant.RuntimeJava { if err := handleRuntimeRecover(runtime, fmt.Sprintf("%s/%s.runtime.tar.gz", tmpPath, website.Alias), true, ""); err != nil { return err } @@ -225,7 +225,7 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string, exc if err != nil { return err } - if runtime.Type == constant.RuntimeNode { + if runtime.Type == constant.RuntimeNode || runtime.Type == constant.RuntimeJava { if err := handleRuntimeBackup(runtime, tmpDir, fmt.Sprintf("%s.runtime.tar.gz", website.Alias), excludes, ""); err != nil { return err } diff --git a/backend/app/service/runtime.go b/backend/app/service/runtime.go index b98ff6411..a88712182 100644 --- a/backend/app/service/runtime.go +++ b/backend/app/service/runtime.go @@ -83,7 +83,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e if exist != nil { return nil, buserr.New(constant.ErrImageExist) } - case constant.RuntimeNode: + case constant.RuntimeNode, constant.RuntimeJava: if !fileOp.Stat(create.CodeDir) { return nil, buserr.New(constant.ErrPathNotFound) } @@ -133,9 +133,9 @@ 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: + case constant.RuntimeNode, constant.RuntimeJava: runtime.Port = create.Port - if err = handleNode(create, runtime, fileOp, appVersionDir); err != nil { + if err = handleNodeAndJava(create, runtime, fileOp, appVersionDir); err != nil { return nil, err } } @@ -217,7 +217,7 @@ func (r *RuntimeService) Delete(runtimeDelete request.RuntimeDelete) error { global.LOG.Errorf("delete image id [%s] error %v", imageID, err) } } - case constant.RuntimeNode: + case constant.RuntimeNode, constant.RuntimeJava: if out, err := compose.Down(runtime.GetComposePath()); err != nil && !runtimeDelete.ForceDelete { if out != "" { return errors.New(out) @@ -300,7 +300,7 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) { } } res.AppParams = appParams - case constant.RuntimeNode: + case constant.RuntimeNode, constant.RuntimeJava: res.Params = make(map[string]interface{}) envs, err := gotenv.Unmarshal(runtime.Env) if err != nil { @@ -308,7 +308,7 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) { } for k, v := range envs { switch k { - case "NODE_APP_PORT", "PANEL_APP_PORT_HTTP": + case "NODE_APP_PORT", "PANEL_APP_PORT_HTTP", "JAVA_APP_PORT": port, err := strconv.Atoi(v) if err != nil { return nil, err @@ -361,7 +361,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error { if exist != nil { return buserr.New(constant.ErrImageExist) } - case constant.RuntimeNode: + case constant.RuntimeNode, constant.RuntimeJava: if runtime.Port != req.Port { if err = checkPortExist(req.Port); err != nil { return err @@ -441,7 +441,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error { return err } go buildRuntime(runtime, imageID, req.Rebuild) - case constant.RuntimeNode: + case constant.RuntimeNode, constant.RuntimeJava: runtime.Version = req.Version runtime.CodeDir = req.CodeDir runtime.Port = req.Port @@ -610,7 +610,7 @@ func (r *RuntimeService) SyncRuntimeStatus() error { return err } for _, runtime := range runtimes { - if runtime.Type == constant.RuntimeNode { + if runtime.Type == constant.RuntimeNode || runtime.Type == constant.RuntimeJava { _ = SyncRuntimeContainerStatus(&runtime) } } diff --git a/backend/app/service/runtime_utils.go b/backend/app/service/runtime_utils.go index 5b87b6315..9e8e7669c 100644 --- a/backend/app/service/runtime_utils.go +++ b/backend/app/service/runtime_utils.go @@ -25,7 +25,7 @@ import ( "gopkg.in/yaml.v3" ) -func handleNode(create request.RuntimeCreate, runtime *model.Runtime, fileOp files.FileOp, appVersionDir string) (err error) { +func handleNodeAndJava(create request.RuntimeCreate, runtime *model.Runtime, fileOp files.FileOp, appVersionDir string) (err error) { runtimeDir := path.Join(constant.RuntimeDir, create.Type) if err = fileOp.CopyDir(appVersionDir, runtimeDir); err != nil { return @@ -318,7 +318,15 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte } create.Params["CONTAINER_PACKAGE_URL"] = create.Source - composeContent, err = handleNodeCompose(env, composeContent, create, projectDir) + composeContent, err = handleCompose(env, composeContent, create, projectDir) + if err != nil { + return + } + case constant.RuntimeJava: + create.Params["CODE_DIR"] = create.CodeDir + create.Params["JAVA_VERSION"] = create.Version + create.Params["PANEL_APP_PORT_HTTP"] = create.Port + composeContent, err = handleCompose(env, composeContent, create, projectDir) if err != nil { return } @@ -341,7 +349,7 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte return } -func handleNodeCompose(env gotenv.Env, composeContent []byte, create request.RuntimeCreate, projectDir string) (composeByte []byte, err error) { +func handleCompose(env gotenv.Env, composeContent []byte, create request.RuntimeCreate, projectDir string) (composeByte []byte, err error) { existMap := make(map[string]interface{}) composeMap := make(map[string]interface{}) if err = yaml.Unmarshal(composeContent, &composeMap); err != nil { @@ -360,7 +368,14 @@ func handleNodeCompose(env gotenv.Env, composeContent []byte, create request.Run _, ok := serviceValue["ports"].([]interface{}) if ok { var ports []interface{} - ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${NODE_APP_PORT}") + + switch create.Type { + case constant.RuntimeNode: + ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${NODE_APP_PORT}") + case constant.RuntimeJava: + ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${JAVA_APP_PORT}") + } + for i, port := range create.ExposedPorts { containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i) hostPortStr := fmt.Sprintf("HOST_PORT_%d", i) diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 8cc0473b7..4f35c61b0 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -336,7 +336,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error) } website.Proxy = proxy } - case constant.RuntimeNode: + case constant.RuntimeNode, constant.RuntimeJava: website.Proxy = fmt.Sprintf("127.0.0.1:%d", runtime.Port) } } @@ -540,9 +540,7 @@ func (w WebsiteService) CreateWebsiteDomain(create request.WebsiteDomainCreate) } for _, domain := range domainModels { wafSite.Domains = append(wafSite.Domains, domain.Domain) - if domain.Port != 80 && domain.Port != 443 { - wafSite.Host = append(wafSite.Host, domain.Domain+":"+string(rune(domain.Port))) - } + wafSite.Host = append(wafSite.Host, domain.Domain+":"+strconv.Itoa(domain.Port)) } if len(wafSite.Host) == 0 { wafSite.Host = []string{} @@ -634,7 +632,7 @@ func (w WebsiteService) DeleteWebsiteDomain(domainId uint) error { oldHostArray := wafSite.Host var newHostArray []string for _, host := range oldHostArray { - if host == webSiteDomain.Domain+":"+string(rune(webSiteDomain.Port)) { + if host == webSiteDomain.Domain+":"+strconv.Itoa(webSiteDomain.Port) { continue } newHostArray = append(newHostArray, host) diff --git a/backend/app/service/website_utils.go b/backend/app/service/website_utils.go index 6956d9a89..17a3441ad 100644 --- a/backend/app/service/website_utils.go +++ b/backend/app/service/website_utils.go @@ -276,7 +276,7 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a server.UpdateRoot(rootIndex) server.UpdatePHPProxy([]string{website.Proxy}, "") } - case constant.RuntimeNode: + case constant.RuntimeNode, constant.RuntimeJava: proxy := fmt.Sprintf("http://127.0.0.1:%d", runtime.Port) server.UpdateRootProxy([]string{proxy}) } diff --git a/backend/constant/runtime.go b/backend/constant/runtime.go index 8e07c7a57..51a2e8a22 100644 --- a/backend/constant/runtime.go +++ b/backend/constant/runtime.go @@ -16,6 +16,7 @@ const ( RuntimePHP = "php" RuntimeNode = "node" + RuntimeJava = "java" RuntimeProxyUnix = "unix" RuntimeProxyTcp = "tcp" diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index e6124b0f7..ac3015599 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2302,6 +2302,7 @@ const message = { customScriptHelper: 'Please fill in the complete startup command, for example: npm run start', portError: 'Cannot fill in the same port', systemRestartHelper: 'Status description: Interruption - status acquisition failed due to system restart', + javaScriptHelper: 'Please fill in the complete startup command, for example: java -jar halo.jar', }, process: { pid: 'Process ID', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 751827a41..b35a6cd54 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -2138,6 +2138,7 @@ const message = { customScriptHelper: '請填寫完整的啟動指令,例如:npm run start', portError: '不能填寫相同連接埠', systemRestartHelper: '狀態說明:中斷-系統重新啟動導致狀態取得失敗', + javaScriptHelper: '請填寫完整啟動指令,例如:java -jar halo.jar', }, process: { pid: '進程ID', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index d5ae84d2c..b0f806f43 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2141,6 +2141,7 @@ const message = { customScriptHelper: '请填写完整的启动命令,例如:npm run start', portError: '不能填写相同端口', systemRestartHelper: '状态说明:中断-系统重启导致状态获取失败', + javaScriptHelper: '请填写完整启动命令,例如:java -jar halo.jar', }, process: { pid: '进程ID', diff --git a/frontend/src/routers/modules/website.ts b/frontend/src/routers/modules/website.ts index be69178cf..26dddc9ca 100644 --- a/frontend/src/routers/modules/website.ts +++ b/frontend/src/routers/modules/website.ts @@ -58,6 +58,16 @@ const webSiteRouter = { requiresAuth: false, }, }, + { + path: '/websites/runtimes/java', + name: 'java', + hidden: true, + component: () => import('@/views/website/runtime/java/index.vue'), + meta: { + activeMenu: '/websites/runtimes/java', + requiresAuth: false, + }, + }, ], }; diff --git a/frontend/src/views/app-store/apps/index.vue b/frontend/src/views/app-store/apps/index.vue index 2713b465a..48bbacc0d 100644 --- a/frontend/src/views/app-store/apps/index.vue +++ b/frontend/src/views/app-store/apps/index.vue @@ -238,6 +238,9 @@ const openInstall = (app: App.App) => { case 'node': router.push({ path: '/websites/runtimes/node' }); break; + case 'java': + router.push({ path: '/websites/runtimes/java' }); + break; default: const params = { app: app, diff --git a/frontend/src/views/website/runtime/index.vue b/frontend/src/views/website/runtime/index.vue index fc7b2f58c..fe59a8094 100644 --- a/frontend/src/views/website/runtime/index.vue +++ b/frontend/src/views/website/runtime/index.vue @@ -13,6 +13,10 @@ const buttons = [ label: 'PHP', path: '/websites/runtimes/php', }, + { + label: 'Java', + path: '/websites/runtimes/java', + }, { label: 'Node.js', path: '/websites/runtimes/node', diff --git a/frontend/src/views/website/runtime/java/index.vue b/frontend/src/views/website/runtime/java/index.vue new file mode 100644 index 000000000..755d12016 --- /dev/null +++ b/frontend/src/views/website/runtime/java/index.vue @@ -0,0 +1,296 @@ + + + + + diff --git a/frontend/src/views/website/runtime/java/operate/index.vue b/frontend/src/views/website/runtime/java/operate/index.vue new file mode 100644 index 000000000..5f5a318bd --- /dev/null +++ b/frontend/src/views/website/runtime/java/operate/index.vue @@ -0,0 +1,395 @@ + + + diff --git a/frontend/src/views/website/website/create/index.vue b/frontend/src/views/website/website/create/index.vue index b9e4738fc..d89b55e20 100644 --- a/frontend/src/views/website/website/create/index.vue +++ b/frontend/src/views/website/website/create/index.vue @@ -163,6 +163,7 @@ + @@ -640,7 +641,7 @@ const submit = async (formEl: FormInstance | undefined) => { if (!flag) { MsgError(i18n.global.t('website.containWarn')); loading.value = false; - return false; + return; } PreCheck({}) .then((res) => {