1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-02-08 01:20:07 +08:00

feat: Running environment website adapts to multiple ports (#7805)

This commit is contained in:
zhengkunwang 2025-02-06 13:55:37 +08:00 committed by GitHub
parent d093c0b25b
commit 6744504443
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 84 additions and 50 deletions

View File

@ -395,8 +395,12 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
} }
website.Proxy = proxy website.Proxy = proxy
} }
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo: case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
website.Proxy = fmt.Sprintf("127.0.0.1:%s", runtime.Port) proxyPort := runtime.Port
if create.Port > 0 {
proxyPort = strconv.Itoa(create.Port)
}
website.Proxy = fmt.Sprintf("127.0.0.1:%s", proxyPort)
} }
case constant.Subsite: case constant.Subsite:
parentWebsite, err := websiteRepo.GetFirst(repo.WithByID(create.ParentWebsiteID)) parentWebsite, err := websiteRepo.GetFirst(repo.WithByID(create.ParentWebsiteID))
@ -450,7 +454,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
} }
deleteWebsite := func(t *task.Task) { deleteWebsite := func(t *task.Task) {
_ = deleteWebsiteFolder(nginxInstall, website) _ = deleteWebsiteFolder(website)
} }
createTask.AddSubTask(i18n.GetMsgByKey("ConfigOpenresty"), configNginx, deleteWebsite) createTask.AddSubTask(i18n.GetMsgByKey("ConfigOpenresty"), configNginx, deleteWebsite)

View File

@ -225,9 +225,8 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a
server.UpdateRoot(rootIndex) server.UpdateRoot(rootIndex)
server.UpdatePHPProxy([]string{website.Proxy}, "") server.UpdatePHPProxy([]string{website.Proxy}, "")
} }
case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo: case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDotNet:
proxy := fmt.Sprintf("http://127.0.0.1:%d", runtime.Port) server.UpdateRootProxy([]string{fmt.Sprintf("http://%s", website.Proxy)})
server.UpdateRootProxy([]string{proxy})
} }
case constant.Subsite: case constant.Subsite:
parentWebsite, err := websiteRepo.GetFirst(repo.WithByID(website.ParentWebsiteID)) parentWebsite, err := websiteRepo.GetFirst(repo.WithByID(website.ParentWebsiteID))
@ -760,14 +759,13 @@ func toMapStr(m map[string]interface{}) map[string]string {
return ret return ret
} }
func deleteWebsiteFolder(nginxInstall model.AppInstall, website *model.Website) error { func deleteWebsiteFolder(website *model.Website) error {
nginxFolder := path.Join(global.Dir.AppInstallDir, constant.AppOpenresty, nginxInstall.Name) siteFolder := GetSitePath(*website, SiteDir)
siteFolder := path.Join(nginxFolder, "www", "sites", website.Alias)
fileOp := files.NewFileOp() fileOp := files.NewFileOp()
if fileOp.Stat(siteFolder) { if fileOp.Stat(siteFolder) {
_ = fileOp.DeleteDir(siteFolder) _ = fileOp.DeleteDir(siteFolder)
} }
nginxFilePath := path.Join(nginxFolder, "conf", "conf.d", website.PrimaryDomain+".conf") nginxFilePath := GetSitePath(*website, SiteConf)
if fileOp.Stat(nginxFilePath) { if fileOp.Stat(nginxFilePath) {
_ = fileOp.DeleteFile(nginxFilePath) _ = fileOp.DeleteFile(nginxFilePath)
} }

View File

@ -14,7 +14,7 @@ export namespace Runtime {
version: string; version: string;
status: string; status: string;
codeDir: string; codeDir: string;
port: number; port: string;
appID: number; appID: number;
} }

View File

@ -2294,6 +2294,8 @@ const message = {
changeDatabaseHelper2: 'Switching to another database will cause previous backups to be unrecoverable.', changeDatabaseHelper2: 'Switching to another database will cause previous backups to be unrecoverable.',
saveCustom: 'Save as Template', saveCustom: 'Save as Template',
rainyun: 'Rain Yun', rainyun: 'Rain Yun',
volcengine: 'Volcengine',
runtimePortHelper: 'The current runtime environment has multiple ports. Please select a proxy port.',
}, },
php: { php: {
short_open_tag: 'Short tag support', short_open_tag: 'Short tag support',

View File

@ -1883,7 +1883,6 @@ const message = {
SSLList: '証明書リスト', SSLList: '証明書リスト',
createDnsAccount: 'DNSアカウント', createDnsAccount: 'DNSアカウント',
aliyun: 'エイリアン', aliyun: 'エイリアン',
volcengine: 'volcengine',
manual: '手動解析', manual: '手動解析',
key: '鍵', key: '鍵',
check: 'ビュー', check: 'ビュー',
@ -2156,6 +2155,8 @@ const message = {
changeDatabaseHelper2: '別のデータベースに切り替えると以前のバックアップが復元できなくなる可能性があります', changeDatabaseHelper2: '別のデータベースに切り替えると以前のバックアップが復元できなくなる可能性があります',
saveCustom: 'テンプレートとして保存', saveCustom: 'テンプレートとして保存',
rainyun: '雨雲', rainyun: '雨雲',
volcengine: 'volcengine',
runtimePortHelper: '現在の実行環境には複数のポートがありますプロキシポートを選択してください',
}, },
php: { php: {
short_open_tag: '短いタグサポート', short_open_tag: '短いタグサポート',

View File

@ -1850,7 +1850,6 @@ const message = {
SSLList: '인증서 목록', SSLList: '인증서 목록',
createDnsAccount: 'DNS 계정 생성', createDnsAccount: 'DNS 계정 생성',
aliyun: '알리윤', aliyun: '알리윤',
volcengine: '볼크엔진',
manual: '수동 설정', manual: '수동 설정',
key: '키', key: '키',
check: '보기', check: '보기',
@ -2119,6 +2118,8 @@ const message = {
changeDatabaseHelper2: '다른 데이터베이스로 전환하면 이전 백업을 복원할 없게 있습니다.', changeDatabaseHelper2: '다른 데이터베이스로 전환하면 이전 백업을 복원할 없게 있습니다.',
saveCustom: '템플릿으로 저장', saveCustom: '템플릿으로 저장',
rainyun: 'Rainyun', rainyun: 'Rainyun',
volcengine: 'volcengine',
runtimePortHelper: '현재 실행 환경에 여러 포트가 있습니다. 프록시 포트를 선택하세요.',
}, },
php: { php: {
short_open_tag: '짧은 태그 지원', short_open_tag: '짧은 태그 지원',

View File

@ -1933,7 +1933,6 @@ const message = {
SSLList: 'Senarai Sijil', SSLList: 'Senarai Sijil',
createDnsAccount: 'Akaun DNS', createDnsAccount: 'Akaun DNS',
aliyun: 'Aliyun', aliyun: 'Aliyun',
volcengine: 'Volcengine',
manual: 'Penyelesaian Manual', manual: 'Penyelesaian Manual',
key: 'Kunci', key: 'Kunci',
check: 'Lihat', check: 'Lihat',
@ -2208,6 +2207,8 @@ const message = {
'Menukar ke pangkalan data lain mungkin menyebabkan sandaran sebelumnya tidak dapat dipulihkan.', 'Menukar ke pangkalan data lain mungkin menyebabkan sandaran sebelumnya tidak dapat dipulihkan.',
saveCustom: 'Simpan sebagai Templat', saveCustom: 'Simpan sebagai Templat',
rainyun: 'Rainyun', rainyun: 'Rainyun',
volcengine: 'Volcengine',
runtimePortHelper: 'Persekitaran runtime semasa mempunyai beberapa port. Sila pilih port proksi.',
}, },
php: { php: {
short_open_tag: 'Sokongan tag pendek', short_open_tag: 'Sokongan tag pendek',

View File

@ -1926,7 +1926,6 @@ const message = {
SSLList: 'Lista de certificados', SSLList: 'Lista de certificados',
createDnsAccount: 'Conta DNS', createDnsAccount: 'Conta DNS',
aliyun: 'Aliyun', aliyun: 'Aliyun',
volcengine: 'Volcengine',
manual: 'Análise manual', manual: 'Análise manual',
key: 'Chave', key: 'Chave',
check: 'Ver', check: 'Ver',
@ -2204,6 +2203,8 @@ const message = {
changeDatabaseHelper2: 'Alternar para outro banco de dados pode tornar backups anteriores irrecuperáveis.', changeDatabaseHelper2: 'Alternar para outro banco de dados pode tornar backups anteriores irrecuperáveis.',
saveCustom: 'Salvar como Modelo', saveCustom: 'Salvar como Modelo',
rainyun: 'Rainyun', rainyun: 'Rainyun',
volcengine: 'Volcengine',
runtimePortHelper: 'O ambiente de runtime atual possui várias portas. Por favor, selecione uma porta de proxy.',
}, },
php: { php: {
short_open_tag: 'Suporte para short tags', short_open_tag: 'Suporte para short tags',

View File

@ -1925,7 +1925,6 @@ const message = {
SSLList: 'Список сертификатов', SSLList: 'Список сертификатов',
createDnsAccount: 'DNS аккаунт', createDnsAccount: 'DNS аккаунт',
aliyun: 'Aliyun', aliyun: 'Aliyun',
volcengine: 'Volcengine',
manual: 'Ручная настройка', manual: 'Ручная настройка',
key: 'Ключ', key: 'Ключ',
check: 'Просмотр', check: 'Просмотр',
@ -2204,6 +2203,8 @@ const message = {
'Переключение на другую базу данных может сделать предыдущие резервные копии невосстановимыми.', 'Переключение на другую базу данных может сделать предыдущие резервные копии невосстановимыми.',
saveCustom: 'Сохранить как Шаблон', saveCustom: 'Сохранить как Шаблон',
rainyun: 'Rainyun', rainyun: 'Rainyun',
volcengine: 'Volcengine',
runtimePortHelper: 'O ambiente de runtime atual possui várias portas. Por favor, selecione uma porta de proxy.',
}, },
php: { php: {
short_open_tag: 'Поддержка коротких тегов', short_open_tag: 'Поддержка коротких тегов',

View File

@ -2132,6 +2132,8 @@ const message = {
changeDatabaseHelper2: '切換其他資料庫會導致以前的備份無法恢復', changeDatabaseHelper2: '切換其他資料庫會導致以前的備份無法恢復',
saveCustom: '另存为模版', saveCustom: '另存为模版',
rainyun: '雨雲', rainyun: '雨雲',
volcengine: 'Volcengine',
runtimePortHelper: '當前運行環境存在多個端口請選擇一個代理端口',
}, },
php: { php: {
short_open_tag: '短標簽支持', short_open_tag: '短標簽支持',

View File

@ -2114,6 +2114,7 @@ const message = {
saveCustom: '另存为模版', saveCustom: '另存为模版',
rainyun: '雨云', rainyun: '雨云',
volcengine: '火山引擎', volcengine: '火山引擎',
runtimePortHelper: '当前运行环境存在多个端口请选择一个代理端口',
}, },
php: { php: {
short_open_tag: '短标签支持', short_open_tag: '短标签支持',

View File

@ -685,3 +685,13 @@ export const escapeProxyURL = (url: string): string => {
return url.replace(/[\/:?#[\]@!$&'()*+,;=%~]/g, (match) => encodeMap[match] || match); return url.replace(/[\/:?#[\]@!$&'()*+,;=%~]/g, (match) => encodeMap[match] || match);
}; };
export function getRuntimeLabel(type: string) {
if (type == 'appstore') {
return i18n.global.t('menu.apps');
}
if (type == 'local') {
return i18n.global.t('commons.table.local');
}
return '';
}

View File

@ -208,7 +208,7 @@
<el-option <el-option
v-for="run in runtimes" v-for="run in runtimes"
:key="run.name" :key="run.name"
:label="run.name + ' [' + $t('runtime.' + run.resource) + ']'" :label="run.name + ' [' + getRuntimeLabel(run.resource) + ']'"
:value="run.id" :value="run.id"
> >
<el-row> <el-row>
@ -218,7 +218,7 @@
</span> </span>
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
{{ ' [' + $t('runtime.' + run.resource) + ']' }} {{ ' [' + getRuntimeLabel(run.resource) + ']' }}
</el-col> </el-col>
</el-row> </el-row>
</el-option> </el-option>
@ -237,6 +237,21 @@
<el-input v-model.number="website.port"></el-input> <el-input v-model.number="website.port"></el-input>
</el-form-item> </el-form-item>
</div> </div>
<el-form-item
:label="$t('setting.proxyPort')"
prop="port"
v-if="website.runtimeType !== 'php' && runtimePorts.length > 0"
>
<el-select v-model="website.port">
<el-option
v-for="(port, index) in runtimePorts"
:key="index"
:label="port"
:value="port"
></el-option>
</el-select>
<span class="input-help">{{ $t('website.runtimePortHelper') }}</span>
</el-form-item>
</div> </div>
<el-form-item prop="advanced" v-if="website.type === 'deployment' && website.appType === 'new'"> <el-form-item prop="advanced" v-if="website.type === 'deployment' && website.appType === 'new'">
<el-checkbox v-model="website.appinstall.advanced" :label="$t('app.advanced')" size="large" /> <el-checkbox v-model="website.appinstall.advanced" :label="$t('app.advanced')" size="large" />
@ -495,12 +510,10 @@
</el-form> </el-form>
</div> </div>
<template #footer> <template #footer>
<span> <el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button> <el-button type="primary" @click="submit(websiteForm)" :disabled="loading">
<el-button type="primary" @click="submit(websiteForm)" :disabled="loading"> {{ $t('commons.button.confirm') }}
{{ $t('commons.button.confirm') }} </el-button>
</el-button>
</span>
</template> </template>
<Check ref="preCheckRef"></Check> <Check ref="preCheckRef"></Check>
<el-card width="30%" v-if="!versionExist" class="mask-prompt"> <el-card width="30%" v-if="!versionExist" class="mask-prompt">
@ -514,7 +527,7 @@
<script lang="ts" setup name="CreateWebSite"> <script lang="ts" setup name="CreateWebSite">
import { App } from '@/api/interface/app'; import { App } from '@/api/interface/app';
import { getAppByKey, getAppDetail, searchApp, getAppInstalled, getAppDetailByID } from '@/api/modules/app'; import { getAppByKey, getAppDetail, searchApp, getAppInstalled } from '@/api/modules/app';
import { import {
createWebsite, createWebsite,
getWebsiteOptions, getWebsiteOptions,
@ -534,7 +547,7 @@ import { getGroupList } from '@/api/modules/group';
import { Group } from '@/api/interface/group'; import { Group } from '@/api/interface/group';
import { SearchRuntimes } from '@/api/modules/runtime'; import { SearchRuntimes } from '@/api/modules/runtime';
import { Runtime } from '@/api/interface/runtime'; import { Runtime } from '@/api/interface/runtime';
import { getRandomStr } from '@/utils/util'; import { getRandomStr, getRuntimeLabel } from '@/utils/util';
import TaskLog from '@/components/task-log/index.vue'; import TaskLog from '@/components/task-log/index.vue';
import { getAppService } from '@/api/modules/app'; import { getAppService } from '@/api/modules/app';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
@ -575,7 +588,7 @@ const initData = () => ({
ftpUser: '', ftpUser: '',
ftpPassword: '', ftpPassword: '',
proxyType: 'tcp', proxyType: 'tcp',
port: 9000, port: 0,
proxyProtocol: 'http://', proxyProtocol: 'http://',
proxyAddress: '', proxyAddress: '',
runtimeType: 'php', runtimeType: 'php',
@ -644,12 +657,13 @@ const paramKey = ref(1);
const preCheckRef = ref(); const preCheckRef = ref();
const staticPath = ref(''); const staticPath = ref('');
const runtimeResource = ref('appstore'); const runtimeResource = ref('appstore');
const runtimeReq = ref<Runtime.RuntimeReq>({ const initRuntimeReq = () => ({
page: 1, page: 1,
pageSize: 100, pageSize: 100,
status: 'running', status: 'running',
type: 'php', type: 'php',
}); });
const runtimeReq = ref<Runtime.RuntimeReq>(initRuntimeReq());
const runtimes = ref<Runtime.RuntimeDTO[]>([]); const runtimes = ref<Runtime.RuntimeDTO[]>([]);
const versionExist = ref(true); const versionExist = ref(true);
const em = defineEmits(['close']); const em = defineEmits(['close']);
@ -659,6 +673,7 @@ const ssls = ref();
const websiteSSL = ref(); const websiteSSL = ref();
const parentWebsites = ref(); const parentWebsites = ref();
const dirs = ref([]); const dirs = ref([]);
const runtimePorts = ref([]);
const handleClose = () => { const handleClose = () => {
open.value = false; open.value = false;
@ -763,15 +778,6 @@ const getDetail = (version: string) => {
}); });
}; };
const getDetailByID = (id: number) => {
getAppDetailByID(id).then((res) => {
website.value.appinstall.appDetailId = res.data.id;
appDetail.value = res.data;
appParams.value = res.data.params;
paramKey.value++;
});
};
const changeRuntimeType = () => { const changeRuntimeType = () => {
runtimeReq.value.type = website.value.runtimeType; runtimeReq.value.type = website.value.runtimeType;
website.value.appinstall.advanced = false; website.value.appinstall.advanced = false;
@ -783,8 +789,11 @@ const changeRuntime = (runID: number) => {
runtimes.value.forEach((item) => { runtimes.value.forEach((item) => {
if (item.id === runID) { if (item.id === runID) {
runtimeResource.value = item.resource; runtimeResource.value = item.resource;
if (item.resource === 'appstore') { runtimePorts.value = item.port.split(',').map((port: string) => parseInt(port.trim(), 10));
getDetailByID(item.appDetailID); if (runtimePorts.value.length > 1) {
website.value.port = runtimePorts.value[0];
} else {
website.value.port = 0;
} }
} }
}); });
@ -792,15 +801,18 @@ const changeRuntime = (runID: number) => {
const getRuntimes = async () => { const getRuntimes = async () => {
try { try {
console.log(runtimeReq.value);
const res = await SearchRuntimes(runtimeReq.value); const res = await SearchRuntimes(runtimeReq.value);
runtimes.value = res.data.items || []; runtimes.value = res.data.items || [];
if (runtimes.value.length > 0) { if (runtimes.value.length > 0) {
const first = runtimes.value[0]; const first = runtimes.value[0];
website.value.runtimeID = first.id; website.value.runtimeID = first.id;
console.log('runtimeID', first.id);
runtimeResource.value = first.resource; runtimeResource.value = first.resource;
if (first.resource === 'appstore') { runtimePorts.value = first.port.split(',').map((port: string) => parseInt(port.trim(), 10));
getDetailByID(first.appDetailID); if (runtimePorts.value.length > 1) {
website.value.port = runtimePorts.value[0];
} else {
website.value.port = 0;
} }
} }
} catch (error) {} } catch (error) {}
@ -818,11 +830,14 @@ const acceptParams = async (installPath: string) => {
website.value.webSiteGroupId = res.data[0].id; website.value.webSiteGroupId = res.data[0].id;
website.value.type = 'deployment'; website.value.type = 'deployment';
runtimeResource.value = 'appstore'; runtimeResource.value = 'appstore';
runtimeReq.value = initRuntimeReq();
searchAppInstalled('website'); searchAppInstalled('website');
listAcmeAccount(); listAcmeAccount();
open.value = true; open.value = true;
console.log('runtimeID', website.value.runtimeID);
}; };
const changeAppType = (type: string) => { const changeAppType = (type: string) => {

View File

@ -84,7 +84,7 @@
{{ row.primaryDomain }} {{ row.primaryDomain }}
</el-text> </el-text>
<el-popover <el-popover
placement="left" placement="right"
trigger="hover" trigger="hover"
:width="300" :width="300"
@before-enter="searchDomains(row.id)" @before-enter="searchDomains(row.id)"
@ -548,11 +548,8 @@ const getUrl = (domain: Website.Domain, website: Website.Website): string => {
return url; return url;
}; };
onBeforeMount(() => { onMounted(() => {
console.log('1111'); search();
}), listGroup();
onMounted(() => { });
search();
listGroup();
});
</script> </script>