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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('runtime.create') }}
+
+
+
+ {{ $t('container.cleanBuildCache') }}
+
+
+
+
+
+
+
+ {{ row.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.port }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('website.check') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('runtime.customScriptHelper') }}
+
+
+
+
+
+
+
+
+ {{ $t('runtime.appPortHelper') }}
+
+
+
+
+
+ {{ $t('runtime.externalPortHelper') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('commons.button.delete') }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('commons.button.cancel') }}
+
+ {{ $t('commons.button.confirm') }}
+
+
+
+
+
+
+
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) => {