mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: Runtime environment supports running without port configuration (#7775)
This commit is contained in:
parent
90354451d2
commit
edf24dbc49
@ -42,8 +42,9 @@ type Volume struct {
|
||||
}
|
||||
|
||||
type ExposedPort struct {
|
||||
HostPort int `json:"hostPort"`
|
||||
ContainerPort int `json:"containerPort"`
|
||||
HostPort int `json:"hostPort"`
|
||||
ContainerPort int `json:"containerPort"`
|
||||
HostIP string `json:"hostIP"`
|
||||
}
|
||||
|
||||
type RuntimeDelete struct {
|
||||
|
@ -23,7 +23,7 @@ type RuntimeDTO struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
AppParams []AppParam `json:"appParams"`
|
||||
Port int `json:"port"`
|
||||
Port string `json:"port"`
|
||||
Path string `json:"path"`
|
||||
ExposedPorts []request.ExposedPort `json:"exposedPorts"`
|
||||
Environments []request.Environment `json:"environments"`
|
||||
|
@ -19,7 +19,7 @@ type Runtime struct {
|
||||
Type string `gorm:"not null" json:"type"`
|
||||
Status string `gorm:"not null" json:"status"`
|
||||
Resource string `gorm:"not null" json:"resource"`
|
||||
Port int `json:"port"`
|
||||
Port string `json:"port"`
|
||||
Message string `json:"message"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
ContainerName string `json:"containerName"`
|
||||
|
@ -18,6 +18,12 @@ func WithByID(id uint) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithByNOTID(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id != ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func WithByIDs(ids []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id in (?)", ids)
|
||||
|
@ -2,6 +2,7 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
@ -55,7 +56,9 @@ func (r *RuntimeRepo) WithNotId(id uint) DBOption {
|
||||
|
||||
func (r *RuntimeRepo) WithPort(port int) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("port = ?", port)
|
||||
portStr := fmt.Sprintf("%d", port)
|
||||
regexPattern := fmt.Sprintf("(^|,)%s(,|$)", portStr)
|
||||
return g.Where("port REGEXP ?", regexPattern)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var hostPorts []string
|
||||
switch create.Type {
|
||||
case constant.RuntimePHP:
|
||||
if create.Resource == constant.ResourceLocal {
|
||||
@ -116,17 +116,12 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||
}
|
||||
create.Install = true
|
||||
for _, export := range create.ExposedPorts {
|
||||
hostPorts = append(hostPorts, strconv.Itoa(export.HostPort))
|
||||
if err := checkPortExist(export.HostPort); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
portValue, _ := create.Params["PANEL_APP_PORT_HTTP"]
|
||||
if portValue != nil {
|
||||
if err := checkPortExist(int(portValue.(float64))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
containerName, ok := create.Params["CONTAINER_NAME"]
|
||||
if !ok {
|
||||
return nil, buserr.New("ErrContainerNameIsNull")
|
||||
@ -159,7 +154,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||
Resource: create.Resource,
|
||||
Version: create.Version,
|
||||
ContainerName: containerName.(string),
|
||||
Port: int(portValue.(float64)),
|
||||
Port: strings.Join(hostPorts, ","),
|
||||
}
|
||||
|
||||
switch create.Type {
|
||||
@ -352,34 +347,30 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range envs {
|
||||
switch k {
|
||||
case "APP_PORT", "PANEL_APP_PORT_HTTP":
|
||||
port, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.Params[k] = port
|
||||
default:
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
hostPort, err := strconv.Atoi(envs[fmt.Sprintf("HOST_PORT_%s", matches[1])])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.ExposedPorts = append(res.ExposedPorts, request.ExposedPort{
|
||||
ContainerPort: containerPort,
|
||||
HostPort: hostPort,
|
||||
})
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
res.Params[k] = v
|
||||
hostPort, err := strconv.Atoi(envs[fmt.Sprintf("HOST_PORT_%s", matches[1])])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hostIP := envs[fmt.Sprintf("HOST_IP_%s", matches[1])]
|
||||
if hostIP == "" {
|
||||
hostIP = "0.0.0.0"
|
||||
}
|
||||
res.ExposedPorts = append(res.ExposedPorts, request.ExposedPort{
|
||||
ContainerPort: containerPort,
|
||||
HostPort: hostPort,
|
||||
HostIP: hostIP,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
res.Params[k] = v
|
||||
}
|
||||
}
|
||||
if v, ok := envs["CONTAINER_PACKAGE_URL"]; ok {
|
||||
@ -437,7 +428,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||
}
|
||||
oldImage := runtime.Image
|
||||
oldEnv := runtime.Env
|
||||
port := int(req.Params["PANEL_APP_PORT_HTTP"].(float64))
|
||||
var hostPorts []string
|
||||
switch runtime.Type {
|
||||
case constant.RuntimePHP:
|
||||
exist, _ := runtimeRepo.GetFirst(runtimeRepo.WithImage(req.Name), runtimeRepo.WithNotId(req.ID))
|
||||
@ -445,14 +436,9 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||
return buserr.New("ErrImageExist")
|
||||
}
|
||||
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
||||
if runtime.Port != port {
|
||||
if err = checkPortExist(port); err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.Port = port
|
||||
}
|
||||
for _, export := range req.ExposedPorts {
|
||||
if err = checkPortExist(export.HostPort); err != nil {
|
||||
hostPorts = append(hostPorts, strconv.Itoa(export.HostPort))
|
||||
if err = checkRuntimePortExist(export.HostPort, false, runtime.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -522,7 +508,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
|
||||
runtime.Version = req.Version
|
||||
runtime.CodeDir = req.CodeDir
|
||||
runtime.Port = port
|
||||
runtime.Port = strings.Join(hostPorts, ",")
|
||||
runtime.Status = constant.RuntimeReCreating
|
||||
_ = runtimeRepo.Save(runtime)
|
||||
go reCreateRuntime(runtime)
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/common"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -319,7 +321,7 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte
|
||||
return
|
||||
}
|
||||
for k := range env {
|
||||
if strings.HasPrefix(k, "CONTAINER_PORT_") || strings.HasPrefix(k, "HOST_PORT_") {
|
||||
if strings.HasPrefix(k, "CONTAINER_PORT_") || strings.HasPrefix(k, "HOST_PORT_") || strings.HasPrefix(k, "HOST_IP_") || strings.Contains(k, "APP_PORT") {
|
||||
delete(env, k)
|
||||
}
|
||||
}
|
||||
@ -431,18 +433,19 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
|
||||
for name, service := range services {
|
||||
serviceName = name
|
||||
serviceValue = service.(map[string]interface{})
|
||||
_, ok := serviceValue["ports"].([]interface{})
|
||||
if ok {
|
||||
delete(serviceValue, "ports")
|
||||
if create.ExposedPorts != nil && len(create.ExposedPorts) > 0 {
|
||||
var ports []interface{}
|
||||
ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${APP_PORT}")
|
||||
for i, port := range create.ExposedPorts {
|
||||
containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i)
|
||||
hostPortStr := fmt.Sprintf("HOST_PORT_%d", i)
|
||||
existMap[containerPortStr] = struct{}{}
|
||||
existMap[hostPortStr] = struct{}{}
|
||||
ports = append(ports, fmt.Sprintf("${HOST_IP}:${%s}:${%s}", hostPortStr, containerPortStr))
|
||||
hostIPStr := fmt.Sprintf("HOST_IP_%d", i)
|
||||
ports = append(ports, fmt.Sprintf("${%s}:${%s}:${%s}", hostIPStr, hostPortStr, containerPortStr))
|
||||
create.Params[containerPortStr] = port.ContainerPort
|
||||
create.Params[hostPortStr] = port.HostPort
|
||||
create.Params[hostIPStr] = port.HostIP
|
||||
}
|
||||
serviceValue["ports"] = ports
|
||||
}
|
||||
@ -667,3 +670,34 @@ func getDockerComposeVolumes(yml []byte) ([]request.Volume, error) {
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func checkRuntimePortExist(port int, scanPort bool, runtimeID uint) error {
|
||||
errMap := make(map[string]interface{})
|
||||
errMap["port"] = port
|
||||
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithPort(port))
|
||||
if appInstall.ID > 0 {
|
||||
errMap["type"] = i18n.GetMsgByKey("TYPE_APP")
|
||||
errMap["name"] = appInstall.Name
|
||||
return buserr.WithMap("ErrPortExist", errMap, nil)
|
||||
}
|
||||
opts := []repo.DBOption{runtimeRepo.WithPort(port)}
|
||||
if runtimeID > 0 {
|
||||
opts = append(opts, repo.WithByNOTID(runtimeID))
|
||||
}
|
||||
runtime, _ := runtimeRepo.GetFirst(opts...)
|
||||
if runtime != nil {
|
||||
errMap["type"] = i18n.GetMsgByKey("TYPE_RUNTIME")
|
||||
errMap["name"] = runtime.Name
|
||||
return buserr.WithMap("ErrPortExist", errMap, nil)
|
||||
}
|
||||
domain, _ := websiteDomainRepo.GetFirst(websiteDomainRepo.WithPort(port))
|
||||
if domain.ID > 0 {
|
||||
errMap["type"] = i18n.GetMsgByKey("TYPE_DOMAIN")
|
||||
errMap["name"] = domain.Domain
|
||||
return buserr.WithMap("ErrPortExist", errMap, nil)
|
||||
}
|
||||
if scanPort && common.ScanPort(port) {
|
||||
return buserr.WithDetail("ErrPortInUsed", port, nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ base:
|
||||
install_dir: /opt
|
||||
mode: dev
|
||||
|
||||
remote_rul:
|
||||
remote_url:
|
||||
repo_url: https://resource.fit2cloud.com/1panel/package
|
||||
resource_url: https://resource.fit2cloud.com/1panel/resource
|
||||
app_repo: https://apps-assets.fit2cloud.com
|
||||
|
@ -65,6 +65,7 @@ export namespace Runtime {
|
||||
export interface ExposedPort {
|
||||
hostPort: number;
|
||||
containerPort: number;
|
||||
hostIP: string;
|
||||
}
|
||||
|
||||
export interface Environment {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-drawer v-model="localOpenPage" :destroy-on-close="true" :close-on-click-modal="false" :size="size">
|
||||
<el-drawer v-model="localOpenPage" :destroy-on-close="true" :size="size">
|
||||
<template #header>
|
||||
<el-page-header @back="handleBack">
|
||||
<template #content>
|
||||
|
@ -47,11 +47,8 @@ import { FormRules } from 'element-plus';
|
||||
import CustomSetting from '@/xpack/views/appstore/index.vue';
|
||||
import DefaultDomain from './default-domain/index.vue';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const { isProductPro } = storeToRefs(globalStore);
|
||||
|
||||
const rules = ref<FormRules>({
|
||||
defaultDomain: [Rules.domainOrIP],
|
||||
});
|
||||
|
@ -43,8 +43,12 @@
|
||||
<el-table-column :label="$t('runtime.version')" prop="version"></el-table-column>
|
||||
<el-table-column :label="$t('runtime.externalPort')" prop="port" min-width="110px">
|
||||
<template #default="{ row }">
|
||||
{{ row.port }}
|
||||
<el-button link :icon="Promotion" @click="goDashboard(row.port, 'http')"></el-button>
|
||||
<span v-for="(port, index) in row.port.split(',')" :key="index">
|
||||
<el-button link @click="goDashboard(port, 'http')">
|
||||
{{ port }}
|
||||
<el-icon class="el-icon--right"><Promotion /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status">
|
||||
|
@ -122,8 +122,6 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (runtime.exposedPorts && runtime.exposedPorts.length > 0) {
|
||||
const containerPortMap = new Map();
|
||||
const hostPortMap = new Map();
|
||||
containerPortMap[runtime.params['APP_PORT']] = true;
|
||||
hostPortMap[runtime.port] = true;
|
||||
for (const port of runtime.exposedPorts) {
|
||||
if (containerPortMap[port.containerPort]) {
|
||||
MsgError(i18n.global.t('runtime.portError'));
|
||||
|
@ -15,7 +15,7 @@
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="removeEnv(index)" link>
|
||||
<el-button type="primary" @click="removeEnv(index)" link class="mt-1">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
@ -23,7 +23,7 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-button @click="addEnv">{{ $t('commons.button.add') }}{{ $t('runtime.environment') }}</el-button>
|
||||
<el-button @click="addEnv">{{ $t('commons.button.add') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -43,8 +43,12 @@
|
||||
<el-table-column :label="$t('runtime.version')" prop="version"></el-table-column>
|
||||
<el-table-column :label="$t('runtime.externalPort')" prop="port" min-width="110px">
|
||||
<template #default="{ row }">
|
||||
{{ row.port }}
|
||||
<el-button link :icon="Promotion" @click="goDashboard(row.port, 'http')"></el-button>
|
||||
<span v-for="(port, index) in row.port.split(',')" :key="index">
|
||||
<el-button link @click="goDashboard(port, 'http')">
|
||||
{{ port }}
|
||||
<el-icon class="el-icon--right"><Promotion /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status">
|
||||
|
@ -144,8 +144,6 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (runtime.exposedPorts && runtime.exposedPorts.length > 0) {
|
||||
const containerPortMap = new Map();
|
||||
const hostPortMap = new Map();
|
||||
containerPortMap[runtime.params['APP_PORT']] = true;
|
||||
hostPortMap[runtime.port] = true;
|
||||
for (const port of runtime.exposedPorts) {
|
||||
if (containerPortMap[port.containerPort]) {
|
||||
MsgError(i18n.global.t('runtime.portError'));
|
||||
|
@ -43,8 +43,12 @@
|
||||
<el-table-column :label="$t('runtime.version')" prop="version"></el-table-column>
|
||||
<el-table-column :label="$t('runtime.externalPort')" prop="port" min-width="110px">
|
||||
<template #default="{ row }">
|
||||
{{ row.port }}
|
||||
<el-button link :icon="Promotion" @click="goDashboard(row.port, 'http')"></el-button>
|
||||
<span v-for="(port, index) in row.port.split(',')" :key="index">
|
||||
<el-button link @click="goDashboard(port, 'http')">
|
||||
{{ port }}
|
||||
<el-icon class="el-icon--right"><Promotion /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status">
|
||||
|
@ -135,8 +135,6 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (runtime.exposedPorts && runtime.exposedPorts.length > 0) {
|
||||
const containerPortMap = new Map();
|
||||
const hostPortMap = new Map();
|
||||
containerPortMap[runtime.params['APP_PORT']] = true;
|
||||
hostPortMap[runtime.port] = true;
|
||||
for (const port of runtime.exposedPorts) {
|
||||
if (containerPortMap[port.containerPort]) {
|
||||
MsgError(i18n.global.t('runtime.portError'));
|
||||
|
@ -43,8 +43,12 @@
|
||||
<el-table-column :label="$t('runtime.version')" prop="version"></el-table-column>
|
||||
<el-table-column :label="$t('runtime.externalPort')" prop="port" min-width="110px">
|
||||
<template #default="{ row }">
|
||||
{{ row.port }}
|
||||
<el-button link :icon="Promotion" @click="goDashboard(row.port, 'http')"></el-button>
|
||||
<span v-for="(port, index) in row.port.split(',')" :key="index">
|
||||
<el-button link @click="goDashboard(port, 'http')">
|
||||
{{ port }}
|
||||
<el-icon class="el-icon--right"><Promotion /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status">
|
||||
|
@ -167,8 +167,6 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (runtime.exposedPorts && runtime.exposedPorts.length > 0) {
|
||||
const containerPortMap = new Map();
|
||||
const hostPortMap = new Map();
|
||||
containerPortMap[runtime.params['APP_PORT']] = true;
|
||||
hostPortMap[runtime.port] = true;
|
||||
for (const port of runtime.exposedPorts) {
|
||||
if (containerPortMap[port.containerPort]) {
|
||||
MsgError(i18n.global.t('runtime.portError'));
|
||||
|
@ -1,49 +1,42 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="7">
|
||||
<el-form-item :label="$t('runtime.appPort')" prop="params.APP_PORT" :rules="rules.port">
|
||||
<el-input v-model.number="runtime.params.APP_PORT" />
|
||||
<span class="input-help">{{ $t('runtime.appPortHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item :label="$t('runtime.externalPort')" prop="params.PANEL_APP_PORT_HTTP" :rules="rules.port">
|
||||
<el-input v-model.number="runtime.params.PANEL_APP_PORT_HTTP" />
|
||||
<span class="input-help">{{ $t('runtime.externalPortHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item :label="$t('commons.button.add') + $t('commons.table.port')">
|
||||
<el-button @click="addPort">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item :label="$t('app.allowPort')">
|
||||
<el-switch v-model="runtime.params.HOST_IP" :active-value="'0.0.0.0'" :inactive-value="'127.0.0.1'" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20" v-for="(port, index) in runtime.exposedPorts" :key="index">
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`exposedPorts.${index}.containerPort`" :rules="rules.port">
|
||||
<el-input v-model.number="port.containerPort" :placeholder="$t('runtime.appPort')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`exposedPorts.${index}.hostPort`" :rules="rules.port">
|
||||
<el-input v-model.number="port.hostPort" :placeholder="$t('runtime.externalPort')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="removePort(index)" link>
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="mt-1.5">
|
||||
<el-text>{{ $t('commons.table.port') }}</el-text>
|
||||
<div class="mt-1.5">
|
||||
<el-row :gutter="20" v-for="(port, index) in runtime.exposedPorts" :key="index">
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`exposedPorts.${index}.hostPort`" :rules="rules.port">
|
||||
<el-input v-model.number="port.hostPort" :placeholder="$t('runtime.externalPort')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item :prop="`exposedPorts.${index}.containerPort`" :rules="rules.port">
|
||||
<el-input v-model.number="port.containerPort" :placeholder="$t('runtime.appPort')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-text>{{ $t('app.allowPort') }}</el-text>
|
||||
<el-switch
|
||||
class="ml-1"
|
||||
v-model="port.hostIP"
|
||||
:active-value="'0.0.0.0'"
|
||||
:inactive-value="'127.0.0.1'"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="removePort(index)" link class="mt-1">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-button @click="addPort">{{ $t('commons.button.add') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -65,16 +58,6 @@ const props = defineProps({
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const runtime = useVModel(props, 'modelValue', emit);
|
||||
|
||||
watch(
|
||||
() => runtime.value.params['APP_PORT'],
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
runtime.value.params['PANEL_APP_PORT_HTTP'] = newVal;
|
||||
}
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
const rules = reactive<FormRules>({
|
||||
port: [Rules.requiredInput, Rules.paramPort, checkNumberRange(1, 65535)],
|
||||
});
|
||||
@ -83,6 +66,7 @@ const addPort = () => {
|
||||
runtime.value.exposedPorts.push({
|
||||
hostPort: undefined,
|
||||
containerPort: undefined,
|
||||
hostIP: '0.0.0.0',
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -43,8 +43,12 @@
|
||||
<el-table-column :label="$t('runtime.version')" prop="version"></el-table-column>
|
||||
<el-table-column :label="$t('runtime.externalPort')" prop="port" min-width="110px">
|
||||
<template #default="{ row }">
|
||||
{{ row.port }}
|
||||
<el-button link :icon="Promotion" @click="goDashboard(row.port, 'http')"></el-button>
|
||||
<span v-for="(port, index) in row.port.split(',')" :key="index">
|
||||
<el-button link @click="goDashboard(port, 'http')">
|
||||
{{ port }}
|
||||
<el-icon class="el-icon--right"><Promotion /></el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status">
|
||||
|
@ -111,8 +111,6 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (runtime.exposedPorts && runtime.exposedPorts.length > 0) {
|
||||
const containerPortMap = new Map();
|
||||
const hostPortMap = new Map();
|
||||
containerPortMap[runtime.params['APP_PORT']] = true;
|
||||
hostPortMap[runtime.port] = true;
|
||||
for (const port of runtime.exposedPorts) {
|
||||
if (containerPortMap[port.containerPort]) {
|
||||
MsgError(i18n.global.t('runtime.portError'));
|
||||
|
@ -15,7 +15,7 @@
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="removeEnv(index)" link>
|
||||
<el-button type="primary" @click="removeEnv(index)" link class="mt-1">
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
@ -23,7 +23,7 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-button @click="addEnv">{{ $t('commons.button.add') }}{{ $t('container.mount') }}</el-button>
|
||||
<el-button @click="addEnv">{{ $t('commons.button.add') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -164,7 +164,7 @@
|
||||
</div>
|
||||
<div v-if="website.type === 'subsite'">
|
||||
<el-form-item :label="$t('website.parentWbeiste')" prop="parentWebsiteID">
|
||||
<el-select v-model="website.parentWebsiteID" @change="getDirConfig(website.parentWebsiteID)">
|
||||
<el-select v-model="website.parentWebsiteID" @change="getDir(website.parentWebsiteID)">
|
||||
<el-option
|
||||
v-for="(site, index) in parentWebsites"
|
||||
:key="index"
|
||||
@ -521,7 +521,7 @@ import {
|
||||
listSSL,
|
||||
preCheck,
|
||||
searchAcmeAccount,
|
||||
GetDirConfig,
|
||||
getDirConfig,
|
||||
} from '@/api/modules/website';
|
||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
@ -923,14 +923,14 @@ const listWebsites = async () => {
|
||||
parentWebsites.value = res.data;
|
||||
if (res.data.length > 0) {
|
||||
website.value.parentWebsiteID = res.data[0].id;
|
||||
getDirConfig(res.data[0].id);
|
||||
getDir(res.data[0].id);
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
const getDirConfig = async (websiteID: number) => {
|
||||
const getDir = async (websiteID: number) => {
|
||||
try {
|
||||
const res = await GetDirConfig({ id: websiteID });
|
||||
const res = await getDirConfig({ id: websiteID });
|
||||
dirs.value = res.data.dirs;
|
||||
if (res.data.dirs.length > 0) {
|
||||
website.value.siteDir = res.data.dirs[0];
|
||||
|
@ -548,8 +548,11 @@ const getUrl = (domain: Website.Domain, website: Website.Website): string => {
|
||||
return url;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
listGroup();
|
||||
});
|
||||
onBeforeMount(() => {
|
||||
console.log('1111');
|
||||
}),
|
||||
onMounted(() => {
|
||||
search();
|
||||
listGroup();
|
||||
});
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user