From f9a035f380e40aed63fba4d887980561c3a3d5d1 Mon Sep 17 00:00:00 2001
From: CityFun <31820853+zhengkunwang223@users.noreply.github.com>
Date: Fri, 9 May 2025 16:53:48 +0800
Subject: [PATCH] fix: fix somme issue with runtime (#8583)
#### What this PR does / why we need it?
#### Summary of your change
#### Please indicate you've done the following:
- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
---
agent/app/service/app_utils.go | 2 +-
agent/app/service/runtime.go | 27 ++-
agent/app/service/runtime_utils.go | 196 ++++++++++++------
.../cmd/server/nginx_conf/php_extensions.json | 14 +-
.../server/nginx_conf/website_default.conf | 1 +
agent/init/business/business.go | 13 +-
frontend/src/global/mimetype.ts | 20 +-
frontend/src/lang/modules/en.ts | 2 -
frontend/src/lang/modules/ja.ts | 2 -
frontend/src/lang/modules/ko.ts | 2 -
frontend/src/lang/modules/ms.ts | 2 -
frontend/src/lang/modules/pt-br.ts | 2 -
frontend/src/lang/modules/ru.ts | 2 -
frontend/src/lang/modules/zh-Hant.ts | 1 -
frontend/src/lang/modules/zh.ts | 5 +-
frontend/src/styles/common.scss | 2 +-
.../website/runtime/components/port-jump.vue | 8 +-
.../views/website/runtime/dotnet/index.vue | 9 -
.../website/runtime/dotnet/operate/index.vue | 12 +-
.../website/runtime/environment/index.vue | 52 +++--
.../src/views/website/runtime/go/index.vue | 9 -
.../website/runtime/go/operate/index.vue | 12 +-
.../src/views/website/runtime/java/index.vue | 9 -
.../website/runtime/java/operate/index.vue | 12 +-
.../src/views/website/runtime/node/index.vue | 9 -
.../website/runtime/node/operate/index.vue | 12 +-
.../website/runtime/php/create/index.vue | 3 +
.../src/views/website/runtime/port/index.vue | 54 ++---
.../views/website/runtime/python/index.vue | 9 -
.../website/runtime/python/operate/index.vue | 12 +-
.../views/website/runtime/volume/index.vue | 53 +++--
.../views/website/website/create/index.vue | 4 +-
.../website/website/domain-create/index.vue | 3 +
33 files changed, 313 insertions(+), 262 deletions(-)
diff --git a/agent/app/service/app_utils.go b/agent/app/service/app_utils.go
index 336c5ee88..3f76980ca 100644
--- a/agent/app/service/app_utils.go
+++ b/agent/app/service/app_utils.go
@@ -901,7 +901,7 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
}
}()
- if err = fileOp.DownloadFile(appDetail.DownloadUrl, filePath); err != nil {
+ if err = files.DownloadFileWithProxy(appDetail.DownloadUrl, filePath); err != nil {
if logger == nil {
global.LOG.Errorf("download app[%s] error %v", app.Name, err)
} else {
diff --git a/agent/app/service/runtime.go b/agent/app/service/runtime.go
index 0ebfe5450..e44ef2872 100644
--- a/agent/app/service/runtime.go
+++ b/agent/app/service/runtime.go
@@ -213,12 +213,35 @@ func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.Runt
}
runtimeDTO := response.NewRuntimeDTO(runtime)
runtimeDTO.Params = make(map[string]interface{})
- envMap, err := gotenv.Unmarshal(runtime.Env)
+ envs, err := gotenv.Unmarshal(runtime.Env)
if err != nil {
return 0, nil, err
}
- for k, v := range envMap {
+ for k, v := range envs {
runtimeDTO.Params[k] = v
+ if strings.Contains(k, "CONTAINER_PORT") || strings.Contains(k, "HOST_PORT") {
+ if strings.Contains(k, "CONTAINER_PORT") {
+ r := regexp.MustCompile(`_(\d+)$`)
+ matches := r.FindStringSubmatch(k)
+ containerPort, err := strconv.Atoi(v)
+ if err != nil {
+ continue
+ }
+ hostPort, err := strconv.Atoi(envs[fmt.Sprintf("HOST_PORT_%s", matches[1])])
+ if err != nil {
+ continue
+ }
+ hostIP := envs[fmt.Sprintf("HOST_IP_%s", matches[1])]
+ if hostIP == "" {
+ hostIP = "0.0.0.0"
+ }
+ runtimeDTO.ExposedPorts = append(runtimeDTO.ExposedPorts, request.ExposedPort{
+ ContainerPort: containerPort,
+ HostPort: hostPort,
+ HostIP: hostIP,
+ })
+ }
+ }
}
res = append(res, runtimeDTO)
}
diff --git a/agent/app/service/runtime_utils.go b/agent/app/service/runtime_utils.go
index 2b9193e58..7f486b72c 100644
--- a/agent/app/service/runtime_utils.go
+++ b/agent/app/service/runtime_utils.go
@@ -6,6 +6,7 @@ import (
"context"
"encoding/json"
"fmt"
+ cmd2 "github.com/1Panel-dev/1Panel/agent/utils/cmd"
"io"
"os"
"os/exec"
@@ -26,7 +27,6 @@ import (
"github.com/1Panel-dev/1Panel/agent/cmd/server/nginx_conf"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
- cmd2 "github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/compose"
"github.com/1Panel-dev/1Panel/agent/utils/docker"
"github.com/1Panel-dev/1Panel/agent/utils/files"
@@ -251,6 +251,18 @@ func getRuntimeEnv(envStr, key string) string {
return ""
}
+func deleteImageByID(oldImageID, imageName string, client docker.Client) {
+ newImageID, err := client.GetImageIDByName(imageName)
+ if err == nil && newImageID != oldImageID {
+ global.LOG.Infof("delete imageID [%s] ", oldImageID)
+ if err := client.DeleteImage(oldImageID); err != nil {
+ global.LOG.Errorf("delete imageID [%s] error %v", oldImageID, err)
+ } else {
+ global.LOG.Infof("delete old image success")
+ }
+ }
+}
+
func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebuild bool) {
runtimePath := runtime.GetPath()
composePath := runtime.GetComposePath()
@@ -283,74 +295,80 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
} else {
runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + stderrBuf.String()
}
- } else {
- if err = runComposeCmdWithLog(constant.RuntimeDown, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
+ _ = runtimeRepo.Save(runtime)
+ return
+ }
+ if err = runComposeCmdWithLog(constant.RuntimeDown, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
+ return
+ }
+ client, err := docker.NewClient()
+ if err != nil {
+ _, _ = logFile.WriteString(fmt.Sprintf("failed to connect to docker client: %v", err))
+ return
+ }
+ runtime.Message = ""
+ if rebuild && runtime.ID > 0 {
+ extensionsStr := getRuntimeEnv(runtime.Env, "PHP_EXTENSIONS")
+ extensionsArray := strings.Split(extensionsStr, ",")
+ oldExtensionStr := getRuntimeEnv(oldEnv, "PHP_EXTENSIONS")
+ oldExtensionArray := strings.Split(oldExtensionStr, ",")
+ var delExtensions []string
+ for _, oldExt := range oldExtensionArray {
+ exist := false
+ for _, ext := range extensionsArray {
+ if oldExt == ext {
+ exist = true
+ break
+ }
+ }
+ if !exist {
+ delExtensions = append(delExtensions, oldExt)
+ }
+ }
+ if err = unInstallPHPExtension(runtime, delExtensions); err != nil {
+ _, _ = logFile.WriteString(fmt.Sprintf("unInstallPHPExtension error %v", err))
+ }
+ }
+
+ defer func() {
+ _ = runtimeRepo.Save(runtime)
+ }()
+
+ if out, err := compose.Up(composePath); err != nil {
+ runtime.Status = constant.StatusStartErr
+ runtime.Message = out
+ return
+ }
+ deleteImageID := ""
+ extensions := getRuntimeEnv(runtime.Env, "PHP_EXTENSIONS")
+ if extensions != "" {
+ deleteImageID, _ = client.GetImageIDByName(runtime.Image)
+ cmdMgr := cmd2.NewCommandMgr(cmd2.WithTimeout(60*time.Minute), cmd2.WithOutputFile(logPath))
+ if err = cmdMgr.Run("docker", "exec", "-i", runtime.ContainerName, "install-ext", extensions); err != nil {
+ runtime.Status = constant.StatusError
+ runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + err.Error()
return
}
- runtime.Message = ""
- if oldImageID != "" {
- client, err := docker.NewClient()
- if err == nil {
- defer client.Close()
- newImageID, err := client.GetImageIDByName(runtime.Image)
- if err == nil && newImageID != oldImageID {
- global.LOG.Infof("delete imageID [%s] ", oldImageID)
- if err := client.DeleteImage(oldImageID); err != nil {
- global.LOG.Errorf("delete imageID [%s] error %v", oldImageID, err)
- } else {
- global.LOG.Infof("delete old image success")
- }
- }
- } else {
- global.LOG.Errorf("delete imageID [%s] error %v", oldImageID, err)
- }
+ commitMgr := cmd2.NewCommandMgr(cmd2.WithTimeout(10*time.Minute), cmd2.WithOutputFile(logPath))
+ err = commitMgr.Run("docker", "commit", runtime.ContainerName, runtime.Image)
+ if err != nil {
+ runtime.Status = constant.StatusError
+ runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + err.Error()
+ return
}
- if rebuild && runtime.ID > 0 {
- extensionsStr := getRuntimeEnv(runtime.Env, "PHP_EXTENSIONS")
- extensionsArray := strings.Split(extensionsStr, ",")
- oldExtensionStr := getRuntimeEnv(oldEnv, "PHP_EXTENSIONS")
- oldExtensionArray := strings.Split(oldExtensionStr, ",")
- var delExtensions []string
- for _, oldExt := range oldExtensionArray {
- exist := false
- for _, ext := range extensionsArray {
- if oldExt == ext {
- exist = true
- break
- }
- }
- if !exist {
- delExtensions = append(delExtensions, oldExt)
- }
- }
-
- if err = unInstallPHPExtension(runtime, delExtensions); err != nil {
- global.LOG.Errorf("unInstallPHPExtension error %v", err)
- }
- }
-
- if out, err := compose.Up(composePath); err != nil {
- runtime.Status = constant.StatusStartErr
- runtime.Message = out
- _ = runtimeRepo.Save(runtime)
- }
- extensions := getRuntimeEnv(runtime.Env, "PHP_EXTENSIONS")
- if extensions != "" {
- cmdMgr := cmd2.NewCommandMgr(cmd2.WithTimeout(60*time.Minute), cmd2.WithOutputFile(logPath))
- if err = cmdMgr.Run("docker", "exec", "-i", runtime.ContainerName, "install-ext", extensions); err != nil {
- runtime.Status = constant.StatusError
- runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + err.Error()
- _ = runtimeRepo.Save(runtime)
- return
- }
- }
- if out, err := compose.DownAndUp(composePath); err != nil {
- runtime.Status = constant.StatusStartErr
- runtime.Message = out
- _ = runtimeRepo.Save(runtime)
- }
- runtime.Status = constant.StatusRunning
}
+ if oldImageID != "" {
+ deleteImageByID(oldImageID, runtime.Image, client)
+ }
+ if deleteImageID != "" {
+ deleteImageByID(deleteImageID, runtime.Image, client)
+ }
+ if out, err := compose.DownAndUp(composePath); err != nil {
+ runtime.Status = constant.StatusStartErr
+ runtime.Message = out
+ return
+ }
+ runtime.Status = constant.StatusRunning
_ = runtimeRepo.Save(runtime)
}
@@ -405,6 +423,10 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
create.Params["CONTAINER_PACKAGE_URL"] = create.Source
siteDir, _ := settingRepo.Get(settingRepo.WithByKey("WEBSITE_DIR"))
create.Params["PANEL_WEBSITE_DIR"] = siteDir.Value
+ composeContent, err = handleEnvironments(composeContent, create, projectDir)
+ if err != nil {
+ return
+ }
case constant.RuntimeNode:
create.Params["CODE_DIR"] = create.CodeDir
create.Params["NODE_VERSION"] = create.Version
@@ -465,6 +487,42 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
return
}
+func handleEnvironments(composeContent []byte, create request.RuntimeCreate, projectDir string) (composeByte []byte, err error) {
+ composeMap := make(map[string]interface{})
+ if err = yaml.Unmarshal(composeContent, &composeMap); err != nil {
+ return
+ }
+ services, serviceValid := composeMap["services"].(map[string]interface{})
+ if !serviceValid {
+ err = buserr.New("ErrFileParse")
+ return
+ }
+ serviceName := ""
+ serviceValue := make(map[string]interface{})
+ for name, service := range services {
+ serviceName = name
+ serviceValue = service.(map[string]interface{})
+ var environments []interface{}
+ for _, e := range create.Environments {
+ environments = append(environments, fmt.Sprintf("%s=%s", e.Key, e.Value))
+ }
+ delete(serviceValue, "environment")
+ if len(environments) > 0 {
+ serviceValue["environment"] = environments
+ }
+ break
+ }
+ services[serviceName] = serviceValue
+ composeMap["services"] = services
+ composeByte, err = yaml.Marshal(composeMap)
+ if err != nil {
+ return
+ }
+ fileOp := files.NewFileOp()
+ _ = fileOp.SaveFile(path.Join(projectDir, "docker-compose.yml"), string(composeByte), constant.DirPerm)
+ return
+}
+
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{})
@@ -499,7 +557,7 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
}
var environments []interface{}
for _, e := range create.Environments {
- environments = append(environments, fmt.Sprintf("%s:%s", e.Key, e.Value))
+ environments = append(environments, fmt.Sprintf("%s=%s", e.Key, e.Value))
}
delete(serviceValue, "environment")
if len(environments) > 0 {
@@ -580,13 +638,15 @@ func unInstallPHPExtension(runtime *model.Runtime, delExtensions []string) error
if err := json.Unmarshal(nginx_conf.PHPExtensionsJson, &phpExtensions); err != nil {
return err
}
+ phpVersion := getRuntimeEnv(runtime.Env, "PHP_VERSION")
+ phpExtensionDir := path.Join(dir, "extensions", getExtensionDir(phpVersion))
+
delMap := make(map[string]struct{})
for _, ext := range phpExtensions {
for _, del := range delExtensions {
if ext.Name == del {
delMap[ext.Check] = struct{}{}
- detail, _ := appDetailRepo.GetFirst(repo.WithByID(runtime.AppDetailID))
- _ = fileOP.DeleteFile(path.Join(dir, "extensions", getExtensionDir(detail.Version), ext.File))
+ _ = fileOP.DeleteFile(path.Join(phpExtensionDir, ext.File))
_ = fileOP.DeleteFile(path.Join(dir, "conf", "conf.d", "docker-php-ext-"+ext.Check+".ini"))
_ = removePHPIniExt(path.Join(dir, "conf", "php.ini"), ext.File)
break
diff --git a/agent/cmd/server/nginx_conf/php_extensions.json b/agent/cmd/server/nginx_conf/php_extensions.json
index 971af6230..e090d6d44 100644
--- a/agent/cmd/server/nginx_conf/php_extensions.json
+++ b/agent/cmd/server/nginx_conf/php_extensions.json
@@ -342,13 +342,6 @@
"versions": ["56","70", "71", "72", "73", "74", "80", "81", "82", "83","84"],
"installed": false
},
- {
- "name": "igbinary",
- "check": "igbinary",
- "file": "igbinary.so",
- "versions": ["56","70", "71", "72", "73", "74", "80", "81", "82", "83","84"],
- "installed": false
- },
{
"name": "zip",
"check": "zip",
@@ -362,5 +355,12 @@
"file": "shmop.so",
"versions": ["56","70", "71", "72", "73", "74", "80", "81", "82", "83","84"],
"installed": false
+ },
+ {
+ "name": "gd",
+ "check": "gd",
+ "file": "gd.so",
+ "versions": ["56","70", "71", "72", "73", "74", "80", "81", "82", "83","84"],
+ "installed": false
}
]
diff --git a/agent/cmd/server/nginx_conf/website_default.conf b/agent/cmd/server/nginx_conf/website_default.conf
index a965fb53e..06e6852b8 100644
--- a/agent/cmd/server/nginx_conf/website_default.conf
+++ b/agent/cmd/server/nginx_conf/website_default.conf
@@ -18,5 +18,6 @@ server {
location ~ \.well-known{
allow all;
+ root /usr/share/nginx/html;
}
}
diff --git a/agent/init/business/business.go b/agent/init/business/business.go
index 4986c1df1..48d553f4b 100644
--- a/agent/init/business/business.go
+++ b/agent/init/business/business.go
@@ -58,13 +58,16 @@ func initAcmeAccount() {
count, _, _ := acmeAccountService.Page(search)
if count == 0 {
createAcmeAccount := request.WebsiteAcmeAccountCreate{
- Email: "acme@1paneldev.com",
- Type: "letsencrypt",
- KeyType: "2048",
- UseProxy: true,
+ Email: "acme@1paneldev.com",
+ Type: "letsencrypt",
+ KeyType: "2048",
+ }
+ systemProxy, _ := service.NewISettingService().GetSystemProxy()
+ if systemProxy.URL != "" {
+ createAcmeAccount.UseProxy = true
}
if _, err := acmeAccountService.Create(createAcmeAccount); err != nil {
- global.LOG.Errorf("create acme account error: %s", err.Error())
+ global.LOG.Warningf("create acme account error: %s", err.Error())
}
}
}
diff --git a/frontend/src/global/mimetype.ts b/frontend/src/global/mimetype.ts
index baf76e839..ea64fe745 100644
--- a/frontend/src/global/mimetype.ts
+++ b/frontend/src/global/mimetype.ts
@@ -177,12 +177,8 @@ export const DNSTypes = [
value: 'HuaweiCloud',
},
{
- label: i18n.global.t('website.volcengine'),
- value: 'Volcengine',
- },
- {
- label: 'DNSPod (' + i18n.global.t('ssl.deprecated') + ')',
- value: 'DnsPod',
+ label: 'GoDaddy',
+ value: 'Godaddy',
},
{
label: 'Cloudflare',
@@ -208,10 +204,6 @@ export const DNSTypes = [
label: 'Name.com',
value: 'NameCom',
},
- {
- label: 'GoDaddy',
- value: 'Godaddy',
- },
{
label: 'FreeMyIP',
value: 'FreeMyIP',
@@ -232,6 +224,14 @@ export const DNSTypes = [
label: 'Spaceship',
value: 'Spaceship',
},
+ {
+ label: i18n.global.t('website.volcengine'),
+ value: 'Volcengine',
+ },
+ {
+ label: 'DNSPod (' + i18n.global.t('ssl.deprecated') + ')',
+ value: 'DnsPod',
+ },
];
export const Fields = [
diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index c7485bb2d..32e05d0db 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -2700,8 +2700,6 @@ const message = {
open: 'Open',
operatorHelper:
'The {0} operation will be performed on the selected operating environment. Do you want to continue? ',
- statusHelper:
- 'Status description: Starting - the container has been started, but the application is starting; abnormal - the container has been started, but the application status is abnormal',
taobao: 'Taobao',
tencent: 'Tencent',
imageSource: 'Image source',
diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts
index 895bce446..5761eb5ac 100644
--- a/frontend/src/lang/modules/ja.ts
+++ b/frontend/src/lang/modules/ja.ts
@@ -2591,8 +2591,6 @@ const message = {
runScriptHelper: '起動コマンドリストは、ソースディレクトリのpackage.jsonファイルから解析されます。',
open: '開ける',
operatorHelper: '{0}操作は、選択した動作環境で実行されます。続けたいですか?',
- statusHelper:
- 'ステータスの説明:開始 - コンテナが開始されましたが、アプリケーションが開始されています。異常 - 容器が開始されましたが、アプリケーションステータスは異常です',
taobao: 'タオバオ',
tencent: 'テンセント',
imageSource: '画像ソース',
diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts
index 67b8c2a6b..3514fb1ff 100644
--- a/frontend/src/lang/modules/ko.ts
+++ b/frontend/src/lang/modules/ko.ts
@@ -2547,8 +2547,6 @@ const message = {
runScriptHelper: '시작 명령 목록은 소스 디렉터리의 package.json 파일에서 분석됩니다.',
open: '열기',
operatorHelper: '{0} 작업이 선택된 운영 환경에서 수행됩니다. 계속하시겠습니까?',
- statusHelper:
- '상태 설명: 시작 중 - 컨테이너가 시작되었으나 애플리케이션이 시작 중; 비정상 - 컨테이너가 시작되었으나 애플리케이션 상태가 비정상.',
taobao: '타오바오',
tencent: '텐센트',
imageSource: '이미지 소스',
diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts
index 83660ae56..77761117a 100644
--- a/frontend/src/lang/modules/ms.ts
+++ b/frontend/src/lang/modules/ms.ts
@@ -2651,8 +2651,6 @@ const message = {
open: 'Buka',
operatorHelper:
'Operasi {0} akan dilakukan pada persekitaran operasi yang dipilih. Adakah anda mahu meneruskan?',
- statusHelper:
- 'Huraian status: Memulakan - kontena telah dimulakan, tetapi aplikasi sedang dimulakan; tidak normal - kontena telah dimulakan, tetapi status aplikasi tidak normal',
taobao: 'Taobao',
tencent: 'Tencent',
imageSource: 'Sumber imej',
diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts
index b5af4642d..82962c527 100644
--- a/frontend/src/lang/modules/pt-br.ts
+++ b/frontend/src/lang/modules/pt-br.ts
@@ -2649,8 +2649,6 @@ const message = {
'A lista de comandos de inicialização é gerada a partir do arquivo package.json no diretório de origem.',
open: 'Abrir',
operatorHelper: 'A operação {0} será realizada no ambiente selecionado. Deseja continuar?',
- statusHelper:
- 'Descrição do status: Iniciando - o contêiner foi iniciado, mas a aplicação está carregando; anormal - o contêiner foi iniciado, mas o status da aplicação está incorreto.',
taobao: 'Taobao',
tencent: 'Tencent',
imageSource: 'Fonte da imagem',
diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts
index f639abb60..535748ad1 100644
--- a/frontend/src/lang/modules/ru.ts
+++ b/frontend/src/lang/modules/ru.ts
@@ -2647,8 +2647,6 @@ const message = {
runScriptHelper: 'Список команд запуска анализируется из файла package.json в исходной директории.',
open: 'Открыть',
operatorHelper: 'Операция {0} будет выполнена для выбранной среды выполнения. Хотите продолжить?',
- statusHelper:
- 'Описание статусов: Запускается - контейнер запущен, но приложение запускается; аномальный - контейнер запущен, но статус приложения аномальный',
taobao: 'Taobao',
tencent: 'Tencent',
imageSource: 'Источник образа',
diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts
index 0347039c7..bc753d01f 100644
--- a/frontend/src/lang/modules/zh-Hant.ts
+++ b/frontend/src/lang/modules/zh-Hant.ts
@@ -2499,7 +2499,6 @@ const message = {
runScriptHelper: '啟動命令是指容器啟動後運行的命令',
open: '開啟',
operatorHelper: '將對選取的執行環境進行 {0} 操作,是否繼續? ',
- statusHelper: '狀態說明:啟動中-容器已啟動,但應用正在啟動;異常-容器已啟動,但應用狀態異常',
taobao: '淘寶',
tencent: '騰訊',
imageSource: '鏡像源',
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 966971a79..f83750025 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -2009,7 +2009,7 @@ const message = {
applySSL: '证书申请',
SSLList: '证书列表',
createDnsAccount: 'DNS账户',
- aliyun: '阿里云DNS',
+ aliyun: '阿里云',
manual: '手动解析',
key: '密钥',
check: '查看',
@@ -2490,7 +2490,6 @@ const message = {
runScriptHelper: '启动命令列表是从源码目录下的 package.json 文件中解析而来',
open: '放开',
operatorHelper: '将对选中的运行环境进行 {0} 操作,是否继续?',
- statusHelper: '状态说明:启动中-容器已启动,但应用正在启动;异常-容器已启动,但应用状态异常',
taobao: '淘宝',
tencent: '腾讯',
imageSource: '镜像源',
@@ -3100,7 +3099,7 @@ const message = {
remote: '远程',
imagePrefix: '镜像前缀',
imagePrefixHelper:
- '作用:自定义镜像前缀,修改 compose 文件中的镜像字段,例如:当镜像前缀设置为 1panel/custom 时,MaxKB 的 image 字段将变更为 1panel/custom/maxkb:v1.10.0',
+ '用于自定义镜像前缀,自动修改 Compose 文件中的镜像字段。\n 例如,当镜像前缀设置为 1panel/custom 时,MaxKB 的镜像将变更为 1panel/custom/maxkb:v1.10.0。',
closeHelper: '是否取消使用自定义仓库',
appStoreUrlHelper: '仅支持 .tar.gz 格式',
postNode: '同步至子节点',
diff --git a/frontend/src/styles/common.scss b/frontend/src/styles/common.scss
index 3d1495c6c..f06e63a83 100644
--- a/frontend/src/styles/common.scss
+++ b/frontend/src/styles/common.scss
@@ -82,7 +82,7 @@ html {
color: #adb0bc;
width: 100%;
display: inline-block;
- white-space: normal;
+ white-space: pre-line;
}
.input-error {
diff --git a/frontend/src/views/website/runtime/components/port-jump.vue b/frontend/src/views/website/runtime/components/port-jump.vue
index e1916241c..21fe994dd 100644
--- a/frontend/src/views/website/runtime/components/port-jump.vue
+++ b/frontend/src/views/website/runtime/components/port-jump.vue
@@ -1,16 +1,14 @@
-
-
- {{ port }}
-
+
+
+ {{ port.hostIP }}:{{ port.hostPort }}->{{ port.containerPort }}