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 @@