Merge pull request #977 from 0xJacky/feat/docker-ui-only

feat: manage nginx in another docker container
This commit is contained in:
Jacky 2025-04-21 15:38:08 +08:00 committed by GitHub
commit ea90da43f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
90 changed files with 2364 additions and 573 deletions

View file

@ -7,6 +7,7 @@ services:
- ../..:/workspaces:cached
- ./go-path:/root/go
- ./data/nginx:/etc/nginx
- /var/run/docker.sock:/var/run/docker.sock
command: sleep infinity
environment:
- NGINX_UI_CERT_CA_DIR=https://pebble:14000/dir
@ -25,6 +26,28 @@ services:
- nginx-ui
networks:
nginxui:
nginx-ui-3:
image: nginx-ui-dev
container_name: nginx-ui-3
volumes:
- ../..:/workspaces:cached
- ./data/nginx-ui-3/nginx:/etc/nginx
- ./data/nginx-ui-3/nginx-ui:/etc/nginx-ui
- /var/run/docker.sock:/var/run/docker.sock
working_dir: /workspaces/nginx-ui
command: ./.devcontainer/node-supervisor.sh
depends_on:
- nginx-ui
networks:
nginxui:
nginx:
image: nginx-ui-dev
container_name: nginx
volumes:
- ./data/nginx-ui-3/nginx:/etc/nginx
command: sleep infinity
networks:
nginxui:
pebble:
image: ghcr.io/letsencrypt/pebble:latest
volumes:

View file

@ -6,4 +6,4 @@ if [ "$(ls -A /etc/nginx)" = "" ]; then
fi
# start nginx
nginx -g "daemon off;"
nginx

View file

@ -3,7 +3,7 @@
# install air
go install github.com/air-verse/air@latest
# install zsh-autosuggestions
install zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
if ! grep -q "zsh-autosuggestions" ~/.zshrc; then

View file

@ -74,7 +74,12 @@ func AddConfig(c *gin.Context) {
return
}
output := nginx.Reload()
output, err := nginx.Reload()
if err != nil {
cosy.ErrHandler(c, err)
return
}
if nginx.GetLogLevel(output) >= nginx.Warn {
cosy.ErrHandler(c, cosy.WrapErrorWithParams(config.ErrNginxReloadFailed, output))
return

View file

@ -5,24 +5,36 @@ import (
"github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy"
)
// Reload reloads the nginx
func Reload(c *gin.Context) {
output := nginx.Reload()
output, err := nginx.Reload()
if err != nil {
cosy.ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, gin.H{
"message": output,
"level": nginx.GetLogLevel(output),
})
}
func Test(c *gin.Context) {
output := nginx.TestConf()
// TestConfig tests the nginx config
func TestConfig(c *gin.Context) {
output, err := nginx.TestConfig()
if err != nil {
cosy.ErrHandler(c, err)
return
}
c.JSON(http.StatusOK, gin.H{
"message": output,
"level": nginx.GetLogLevel(output),
})
}
// Restart restarts the nginx
func Restart(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "ok",
@ -30,8 +42,13 @@ func Restart(c *gin.Context) {
go nginx.Restart()
}
// Status returns the status of the nginx
func Status(c *gin.Context) {
lastOutput := nginx.GetLastOutput()
lastOutput, err := nginx.GetLastOutput()
if err != nil {
cosy.ErrHandler(c, err)
return
}
running := nginx.IsNginxRunning()

View file

@ -11,7 +11,7 @@ func InitRouter(r *gin.RouterGroup) {
r.POST("ngx/format_code", FormatNginxConfig)
r.POST("nginx/reload", Reload)
r.POST("nginx/restart", Restart)
r.POST("nginx/test", Test)
r.POST("nginx/test", TestConfig)
r.GET("nginx/status", Status)
// Get detailed Nginx status information, including connection count, process information, etc. (Issue #850)
r.GET("nginx/detail_status", GetDetailStatus)

View file

@ -4,7 +4,6 @@
package nginx
import (
"errors"
"net/http"
"strings"
"time"
@ -119,10 +118,14 @@ func ToggleStubStatus(c *gin.Context) {
}
// Reload Nginx configuration
reloadOutput := nginx.Reload()
reloadOutput, err := nginx.Reload()
if err != nil {
cosy.ErrHandler(c, err)
return
}
if len(reloadOutput) > 0 && (strings.Contains(strings.ToLower(reloadOutput), "error") ||
strings.Contains(strings.ToLower(reloadOutput), "failed")) {
cosy.ErrHandler(c, errors.New("Reload Nginx failed"))
cosy.ErrHandler(c, cosy.WrapErrorWithParams(nginx.ErrReloadFailed, reloadOutput))
return
}

View file

@ -25,6 +25,7 @@ func GetSettings(c *gin.Context) {
settings.NginxSettings.ErrorLogPath = nginx.GetErrorLogPath()
settings.NginxSettings.ConfigDir = nginx.GetConfPath()
settings.NginxSettings.PIDPath = nginx.GetPIDPath()
settings.NginxSettings.StubStatusPort = settings.NginxSettings.GetStubStatusPort()
if settings.NginxSettings.ReloadCmd == "" {
settings.NginxSettings.ReloadCmd = "nginx -s reload"

View file

@ -64,6 +64,7 @@ export interface NginxSettings {
reload_cmd: string
restart_cmd: string
stub_status_port: number
container_name: string
}
export interface NodeSettings {

View file

@ -0,0 +1,3 @@
import Breadcrumb from './Breadcrumb.vue'
export default Breadcrumb

View file

@ -12,12 +12,39 @@ function debug(...args: any[]) {
}
}
// Config file patterns and extensions
const CONFIG_FILE_EXTENSIONS = ['.conf', '.config']
const SENSITIVE_CONTENT_PATTERNS = [
/-----BEGIN [A-Z ]+ PRIVATE KEY-----/,
/-----BEGIN CERTIFICATE-----/,
/apiKey\s*[:=]\s*["'][a-zA-Z0-9]+["']/,
/password\s*[:=]\s*["'][^"']+["']/,
/secret\s*[:=]\s*["'][^"']+["']/,
]
function useCodeCompletion() {
const editorRef = ref<Editor>()
const currentGhostText = ref<string>('')
const isConfigFile = ref<boolean>(false)
const ws = openai.code_completion()
// Check if the current file is a configuration file
function checkIfConfigFile(filename: string, content: string): boolean {
// Check file extension
const hasConfigExtension = CONFIG_FILE_EXTENSIONS.some(ext => filename.toLowerCase().endsWith(ext))
// Check if it's an Nginx configuration file based on common patterns
const hasNginxPatterns = /server\s*\{|location\s*\/|http\s*\{|upstream\s*[\w-]+\s*\{/.test(content)
return hasConfigExtension || hasNginxPatterns
}
// Check if content contains sensitive information that shouldn't be sent
function containsSensitiveContent(content: string): boolean {
return SENSITIVE_CONTENT_PATTERNS.some(pattern => pattern.test(content))
}
function getAISuggestions(code: string, context: string, position: Point, callback: (suggestion: string) => void, language: string = 'nginx', suffix: string = '', requestId: string) {
if (!ws || ws.readyState !== WebSocket.OPEN) {
debug('WebSocket is not open')
@ -29,6 +56,17 @@ function useCodeCompletion() {
return
}
// Skip if not a config file or contains sensitive content
if (!isConfigFile.value) {
debug('Skipping AI suggestions for non-config file')
return
}
if (containsSensitiveContent(context)) {
debug('Skipping AI suggestions due to sensitive content')
return
}
const message = {
context,
code,
@ -57,8 +95,20 @@ function useCodeCompletion() {
return
}
if (!isConfigFile.value) {
debug('Skipping ghost text for non-config file')
return
}
try {
const currentText = editorRef.value.getValue()
// Skip if content contains sensitive information
if (containsSensitiveContent(currentText)) {
debug('Skipping ghost text due to sensitive content')
return
}
const cursorPosition = editorRef.value.getCursorPosition()
// Get all text before the current cursor position as the code part for the request
@ -175,7 +225,7 @@ function useCodeCompletion() {
debug('Editor initialized')
async function init(editor: Editor) {
async function init(editor: Editor, filename: string = '') {
const { enabled } = await openai.get_code_completion_enabled_status()
if (!enabled) {
debug('Code completion is not enabled')
@ -184,6 +234,11 @@ function useCodeCompletion() {
editorRef.value = editor
// Determine if the current file is a configuration file
const content = editor.getValue()
isConfigFile.value = checkIfConfigFile(filename, content)
debug(`File type check: isConfigFile=${isConfigFile.value}, filename=${filename}`)
// Set up Tab key handler
setupTabHandler(editor)
@ -195,7 +250,9 @@ function useCodeCompletion() {
if (e.action === 'insert' || e.action === 'remove') {
// Clear current ghost text
debouncedApplyGhostText()
if (isConfigFile.value) {
debouncedApplyGhostText()
}
}
})
@ -203,7 +260,9 @@ function useCodeCompletion() {
editor.selection.on('changeCursor', () => {
debug('Cursor changed')
clearGhostText()
debouncedApplyGhostText()
if (isConfigFile.value) {
debouncedApplyGhostText()
}
})
}, 2000)
}

View file

@ -0,0 +1,3 @@
import EnvGroupTabs from './EnvGroupTabs.vue'
export default EnvGroupTabs

View file

@ -0,0 +1,3 @@
import EnvIndicator from './EnvIndicator.vue'
export default EnvIndicator

View file

@ -0,0 +1,3 @@
import ICP from './ICP.vue'
export default ICP

View file

@ -0,0 +1,3 @@
import Logo from './Logo.vue'
export default Logo

View file

@ -0,0 +1,3 @@
import NginxControl from './NginxControl.vue'
export default NginxControl

View file

@ -0,0 +1,3 @@
import NodeSelector from './NodeSelector.vue'
export default NodeSelector

View file

@ -0,0 +1,3 @@
import Notification from './Notification.vue'
export default Notification

View file

@ -0,0 +1,3 @@
import OTPInput from './OTPInput.vue'
export default OTPInput

View file

@ -0,0 +1,3 @@
import PageHeader from './PageHeader.vue'
export default PageHeader

View file

@ -0,0 +1,3 @@
import ReactiveFromNow from './ReactiveFromNow.vue'
export default ReactiveFromNow

View file

@ -0,0 +1,3 @@
import SensitiveString from './SensitiveString.vue'
export default SensitiveString

View file

@ -0,0 +1,3 @@
import SetLanguage from './SetLanguage.vue'
export default SetLanguage

View file

@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { Ref } from 'vue'
import VPSwitch from '@/components/VPSwitch/VPSwitch.vue'
import VPSwitch from '@/components/VPSwitch'
import { useSettingsStore } from '@/pinia'
import VPIconMoon from './icons/VPIconMoon.vue'
import VPIconSun from './icons/VPIconSun.vue'

View file

@ -0,0 +1,3 @@
import SwitchAppearance from './SwitchAppearance.vue'
export default SwitchAppearance

View file

@ -0,0 +1,3 @@
import SystemRestoreContainer from './SystemRestoreContent.vue'
export default SystemRestoreContainer

View file

@ -0,0 +1,8 @@
import Authorization from './Authorization.vue'
import use2FAModal from './use2FAModal'
export default Authorization
export {
use2FAModal,
}

View file

@ -0,0 +1,3 @@
import VPSwitch from './VPSwitch.vue'
export default VPSwitch

View file

@ -0,0 +1,15 @@
export default {
500001: () => $gettext('Docker client not initialized'),
500002: () => $gettext('Failed to exec command: {0}'),
500003: () => $gettext('Failed to attach to exec instance: {0}'),
500004: () => $gettext('Failed to read output: {0}'),
500005: () => $gettext('Command exited with unexpected exit code: {0}, error: {1}'),
500006: () => $gettext('Container status unknown'),
500007: () => $gettext('Failed to inspect container: {0}'),
500008: () => $gettext('Nginx is not running in another container'),
500009: () => $gettext('Failed to get hostname: {0}'),
500010: () => $gettext('Failed to pull image: {0}'),
500011: () => $gettext('Failed to inspect current container: {0}'),
500012: () => $gettext('Failed to create temp container: {0}'),
500013: () => $gettext('Failed to start temp container: {0}'),
}

View file

@ -1,3 +1,4 @@
export default {
50001: () => $gettext('Block is nil'),
50002: () => $gettext('Reload nginx failed: {0}'),
}

View file

@ -80,7 +80,7 @@ msgid "Add a passkey"
msgstr "أضف مفتاح مرور"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "إضافة تكوين"
@ -301,7 +301,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -355,7 +355,7 @@ msgstr ""
msgid "Base information"
msgstr "المعلومات الأساسية"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -594,7 +594,7 @@ msgstr[3] "الشهادات المعدلة"
msgstr[4] "الشهادات المعدلة"
msgstr[5] "الشهادات المعدلة"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr "المسار المتغير"
@ -707,6 +707,10 @@ msgstr ""
msgid "Command"
msgstr "أمر"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -787,6 +791,10 @@ msgstr "تم فقدان الاتصال، يرجى تحديث الصفحة."
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1018,7 +1026,7 @@ msgstr "تم الحذف بنجاح"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "نشر"
@ -1218,6 +1226,10 @@ msgstr "هل تريد إزالة هذا الخادم؟"
msgid "Do you want to remove this upstream?"
msgstr "هل تريد إزالة هذا المصدر؟"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1281,7 +1293,7 @@ msgstr "تعديل %{n}"
msgid "Edit %{n}"
msgstr "تعديل %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "تعديل التكوين"
@ -1495,6 +1507,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "فشل في الحصول على الشهادة"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/backup.ts:5
#, fuzzy
msgid "Failed to backup Nginx config files: {0}"
@ -1582,6 +1599,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1680,6 +1702,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1699,6 +1726,11 @@ msgstr "فشل في الحصول على معلومات الشهادة"
msgid "Failed to get certificate information"
msgstr "فشل في الحصول على معلومات الشهادة"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1709,6 +1741,16 @@ msgstr "فشل في الحصول على معلومات الشهادة"
msgid "Failed to get performance data"
msgstr "فشل في الحصول على معلومات الشهادة"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1733,6 +1775,11 @@ msgstr "فشل في التفعيل %{msg}"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/backup.ts:53
#, fuzzy
msgid "Failed to read encrypted file: {0}"
@ -1753,6 +1800,11 @@ msgstr "فشل في التفعيل %{msg}"
msgid "Failed to read nginx.conf"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1777,6 +1829,11 @@ msgstr "فشل في الحصول على الشهادة"
msgid "Failed to save Nginx performance settings"
msgstr "فشل في الحصول على معلومات الشهادة"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1838,14 +1895,10 @@ msgstr "للمستخدمين الصين: /https://mirror.ghproxy.com"
msgid "Form parse failed"
msgstr "فشل التكرار"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "تنسيق الكود"
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr "خطأ في التنسيق %{msg}"
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr "تم التنسيق بنجاح"
@ -1920,7 +1973,7 @@ msgstr "إخفاء"
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2101,7 +2154,7 @@ msgid "Invalid file path: {0}"
msgstr "رمز 2FA أو الاسترداد غير صالح"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr "اسم ملف غير صالح"
@ -2525,7 +2578,7 @@ msgstr "توجيه متعدد الأسطر"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2568,7 +2621,7 @@ msgstr "تثبيت"
msgid "New name"
msgstr "اسم جديد"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "New Path"
msgstr "مسار جديد"
@ -2669,6 +2722,11 @@ msgstr "مسار سجل أخطاء Nginx"
msgid "Nginx is not running"
msgstr "Nginx لا يعمل"
#: src/constants/errors/docker.ts:9
#, fuzzy
msgid "Nginx is not running in another container"
msgstr "Nginx لا يعمل"
#: src/views/dashboard/NginxDashBoard.vue:112
#, fuzzy
msgid "Nginx is running"
@ -2999,11 +3057,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr "استخدم رمز الاسترداد"
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "الكتابة فوق"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "الكتابة فوق الملف الموجود"
@ -3054,7 +3112,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "مسار"
@ -3150,7 +3208,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr "يرجى إدخال اسم الملف"
@ -3386,6 +3444,11 @@ msgstr "إعادة تحميل"
msgid "Reload Nginx"
msgstr "إعادة تحميل nginx"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "فشل في التفعيل %{msg}"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3675,7 +3738,7 @@ msgstr "يعمل"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4519,7 +4582,7 @@ msgstr "تم التحديث بنجاح"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4816,6 +4879,9 @@ msgstr ""
msgid "Your passkeys"
msgstr "مفاتيح المرور الخاصة بك"
#~ msgid "Format error %{msg}"
#~ msgstr "خطأ في التنسيق %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr "فشل في الحفظ، تم اكتشاف خطأ(أخطاء) في بناء الجملة في التكوين."

View file

@ -77,7 +77,7 @@ msgid "Add a passkey"
msgstr "Passkey hinzufügen"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
#, fuzzy
msgid "Add Configuration"
msgstr "Konfiguration bearbeiten"
@ -315,7 +315,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -370,7 +370,7 @@ msgstr ""
msgid "Base information"
msgstr "Basisinformationen"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
#, fuzzy
@ -610,7 +610,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "Zertifikat ist gültig"
msgstr[1] "Zertifikat ist gültig"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "Changed Path"
msgstr "Zertifikat ist gültig"
@ -726,6 +726,10 @@ msgstr ""
msgid "Command"
msgstr "Kommando"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -806,6 +810,10 @@ msgstr "Ver"
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1045,7 +1053,7 @@ msgstr "Erfolgreich deaktiviert"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "Ausführen"
@ -1255,6 +1263,10 @@ msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
msgid "Do you want to remove this upstream?"
msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1318,7 +1330,7 @@ msgstr "Bearbeiten %{n}"
msgid "Edit %{n}"
msgstr "Bearbeiten %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "Konfiguration bearbeiten"
@ -1542,6 +1554,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "Zertifikat ist gültig"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1628,6 +1645,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1726,6 +1748,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1745,6 +1772,11 @@ msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
msgid "Failed to get certificate information"
msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1755,6 +1787,16 @@ msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
msgid "Failed to get performance data"
msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1779,6 +1821,11 @@ msgstr "Aktiviern von %{msg} fehlgeschlagen"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1796,6 +1843,11 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1819,6 +1871,11 @@ msgstr "Zertifikat ist gültig"
msgid "Failed to save Nginx performance settings"
msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1882,15 +1939,10 @@ msgstr "Für chinesische Benutzer: https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "Anlegen fehlgeschlagen"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "Formatcode"
#: src/views/config/ConfigEditor.vue:218
#, fuzzy
msgid "Format error %{msg}"
msgstr "Fehler beim Speichern %{msg}"
#: src/views/config/ConfigEditor.vue:216
#, fuzzy
msgid "Format successfully"
@ -1968,7 +2020,7 @@ msgstr "Verstecken"
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
msgid "History"
@ -2150,7 +2202,7 @@ msgid "Invalid file path: {0}"
msgstr "Ungültige E-Mail!"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
#, fuzzy
msgid "Invalid filename"
msgstr "Ungültige E-Mail!"
@ -2595,7 +2647,7 @@ msgstr "Einzelne Anweisung"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2639,7 +2691,7 @@ msgstr "Installieren"
msgid "New name"
msgstr "Benutzername"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "New Path"
msgstr "Pfad"
@ -2743,6 +2795,11 @@ msgstr "Nginx Fehlerlog-Pfad"
msgid "Nginx is not running"
msgstr "Nginx läuft nicht"
#: src/constants/errors/docker.ts:9
#, fuzzy
msgid "Nginx is not running in another container"
msgstr "Nginx läuft nicht"
#: src/views/dashboard/NginxDashBoard.vue:112
#, fuzzy
msgid "Nginx is running"
@ -3082,11 +3139,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr "Benuzte Wiederherstellungscode"
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "Überschreiben"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "Zu überschreibende Datei existiert"
@ -3137,7 +3194,7 @@ msgstr "Passwort darf nicht länger als 20 Zeichen sein"
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "Pfad"
@ -3237,7 +3294,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
#, fuzzy
msgid "Please input a filename"
msgstr "Bitte Benutzernamen eingeben!"
@ -3488,6 +3545,11 @@ msgstr "Neu laden"
msgid "Reload Nginx"
msgstr "Lade Nginx neu"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "Aktiviern von %{msg} fehlgeschlagen"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3792,7 +3854,7 @@ msgstr "Arbeite"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4653,7 +4715,7 @@ msgstr "Speichern erfolgreich"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4961,6 +5023,10 @@ msgstr ""
msgid "Your passkeys"
msgstr "Deine Passkeys"
#, fuzzy
#~ msgid "Format error %{msg}"
#~ msgstr "Fehler beim Speichern %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr ""
#~ "Fehler beim Speichern, Syntaxfehler wurden in der Konfiguration erkannt."

View file

@ -78,7 +78,7 @@ msgid "Add a passkey"
msgstr ""
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
#, fuzzy
msgid "Add Configuration"
msgstr "Edit Configuration"
@ -312,7 +312,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -367,7 +367,7 @@ msgstr ""
msgid "Base information"
msgstr "Base information"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
#, fuzzy
@ -603,7 +603,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "Certificate is valid"
msgstr[1] "Certificate is valid"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "Changed Path"
msgstr "Certificate is valid"
@ -718,6 +718,10 @@ msgstr ""
msgid "Command"
msgstr "Comments"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -798,6 +802,10 @@ msgstr ""
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1034,7 +1042,7 @@ msgstr "Disabled successfully"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr ""
@ -1243,6 +1251,10 @@ msgstr "Are you sure you want to remove this directive?"
msgid "Do you want to remove this upstream?"
msgstr "Are you sure you want to remove this directive?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1302,7 +1314,7 @@ msgstr "Edit %{n}"
msgid "Edit %{n}"
msgstr "Edit %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "Edit Configuration"
@ -1525,6 +1537,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "Certificate is valid"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/backup.ts:5
#, fuzzy
msgid "Failed to backup Nginx config files: {0}"
@ -1612,6 +1629,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1710,6 +1732,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1730,6 +1757,11 @@ msgstr "Certificate is valid"
msgid "Failed to get certificate information"
msgstr "Certificate is valid"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "Failed to enable %{msg}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1740,6 +1772,16 @@ msgstr "Certificate is valid"
msgid "Failed to get performance data"
msgstr "Certificate is valid"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "Failed to enable %{msg}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1764,6 +1806,11 @@ msgstr "Failed to enable %{msg}"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/backup.ts:53
#, fuzzy
msgid "Failed to read encrypted file: {0}"
@ -1784,6 +1831,11 @@ msgstr "Failed to enable %{msg}"
msgid "Failed to read nginx.conf"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1808,6 +1860,11 @@ msgstr "Certificate is valid"
msgid "Failed to save Nginx performance settings"
msgstr "Certificate is valid"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "Failed to enable %{msg}"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1869,15 +1926,10 @@ msgstr ""
msgid "Form parse failed"
msgstr "Enable failed"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr ""
#: src/views/config/ConfigEditor.vue:218
#, fuzzy
msgid "Format error %{msg}"
msgstr "Save error %{msg}"
#: src/views/config/ConfigEditor.vue:216
#, fuzzy
msgid "Format successfully"
@ -1954,7 +2006,7 @@ msgstr ""
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2129,7 +2181,7 @@ msgid "Invalid file path: {0}"
msgstr "Invalid E-mail!"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
#, fuzzy
msgid "Invalid filename"
msgstr "Invalid E-mail!"
@ -2567,7 +2619,7 @@ msgstr "Single Directive"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2611,7 +2663,7 @@ msgstr "Install"
msgid "New name"
msgstr "Username"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "New Path"
msgstr "Path"
@ -2714,6 +2766,10 @@ msgstr ""
msgid "Nginx is not running"
msgstr ""
#: src/constants/errors/docker.ts:9
msgid "Nginx is not running in another container"
msgstr ""
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr ""
@ -3045,11 +3101,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr ""
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr ""
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr ""
@ -3097,7 +3153,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "Path"
@ -3189,7 +3245,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
#, fuzzy
msgid "Please input a filename"
msgstr "Please input your username!"
@ -3431,6 +3487,11 @@ msgstr ""
msgid "Reload Nginx"
msgstr ""
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "Failed to enable %{msg}"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3734,7 +3795,7 @@ msgstr ""
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4573,7 +4634,7 @@ msgstr "Saved successfully"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4871,6 +4932,10 @@ msgstr ""
msgid "Your passkeys"
msgstr ""
#, fuzzy
#~ msgid "Format error %{msg}"
#~ msgstr "Save error %{msg}"
#, fuzzy
#~ msgid "Access Token"
#~ msgstr "Sites List"

View file

@ -83,7 +83,7 @@ msgid "Add a passkey"
msgstr "Agregar una llave de acceso"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "Agregar configuración"
@ -306,7 +306,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -360,7 +360,7 @@ msgstr ""
msgid "Base information"
msgstr "Información general"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -593,7 +593,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "Cambiar Certificado"
msgstr[1] "Cambiar Certificados"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr "Ruta cambiada"
@ -706,6 +706,10 @@ msgstr ""
msgid "Command"
msgstr "Comando"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -786,6 +790,10 @@ msgstr "Conexión perdida, por favor actualice la página."
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1019,7 +1027,7 @@ msgstr "Borrado exitoso"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "Desplegar"
@ -1219,6 +1227,10 @@ msgstr "¿Quieres eliminar este servidor?"
msgid "Do you want to remove this upstream?"
msgstr "¿Quieres eliminar esta transmisión?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1281,7 +1293,7 @@ msgstr "Editar %{n}"
msgid "Edit %{n}"
msgstr "Editar %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "Editar Configuración"
@ -1498,6 +1510,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "Falla al obtener el certificado"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1584,6 +1601,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1682,6 +1704,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1701,6 +1728,11 @@ msgstr "No se pudo obtener la información del certificado"
msgid "Failed to get certificate information"
msgstr "No se pudo obtener la información del certificado"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "Error al habilitar %{msg}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1711,6 +1743,16 @@ msgstr "No se pudo obtener la información del certificado"
msgid "Failed to get performance data"
msgstr "No se pudo obtener la información del certificado"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "Error al habilitar %{msg}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1735,6 +1777,11 @@ msgstr "Error al habilitar %{msg}"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1752,6 +1799,11 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1775,6 +1827,11 @@ msgstr "Falla al obtener el certificado"
msgid "Failed to save Nginx performance settings"
msgstr "No se pudo obtener la información del certificado"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "Error al habilitar %{msg}"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1838,14 +1895,10 @@ msgstr "Para usuario chino: https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "Duplicado fallido"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "Código de formato"
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr "Error de formato %{msg}"
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr "Formateado correctamente"
@ -1920,7 +1973,7 @@ msgstr "Ocultar"
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2101,7 +2154,7 @@ msgid "Invalid file path: {0}"
msgstr "Nombre de archivo inválido"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr "Nombre de archivo inválido"
@ -2527,7 +2580,7 @@ msgstr "Directiva multilínea"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2570,7 +2623,7 @@ msgstr "Instalar"
msgid "New name"
msgstr "Nuevo nombre"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "New Path"
msgstr "Nueva ruta"
@ -2672,6 +2725,11 @@ msgstr "Ruta de registro de errores de Nginx"
msgid "Nginx is not running"
msgstr "Nginx no se está ejecutando"
#: src/constants/errors/docker.ts:9
#, fuzzy
msgid "Nginx is not running in another container"
msgstr "Nginx no se está ejecutando"
#: src/views/dashboard/NginxDashBoard.vue:112
#, fuzzy
msgid "Nginx is running"
@ -3006,11 +3064,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr "Usar código de recuperación"
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "Sobrescribir"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "Sobrescribir archivo existente"
@ -3062,7 +3120,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "Ruta"
@ -3163,7 +3221,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr "Por favor, ingrese un nombre de archivo"
@ -3410,6 +3468,11 @@ msgstr "Recargar"
msgid "Reload Nginx"
msgstr "Recargando Nginx"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "Error al habilitar %{msg}"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3702,7 +3765,7 @@ msgstr "Corriendo"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4560,7 +4623,7 @@ msgstr "Actualización exitosa"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4862,6 +4925,9 @@ msgstr ""
msgid "Your passkeys"
msgstr "Sus llaves de acceso"
#~ msgid "Format error %{msg}"
#~ msgstr "Error de formato %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr ""
#~ "No se pudo guardar, se detectó un error(es) de sintaxis en la "

View file

@ -82,7 +82,7 @@ msgid "Add a passkey"
msgstr "Ajouter une clé d'accès"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
#, fuzzy
msgid "Add Configuration"
msgstr "Modifier la configuration"
@ -319,7 +319,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -373,7 +373,7 @@ msgstr ""
msgid "Base information"
msgstr "Information générale"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -612,7 +612,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "Changer de certificat"
msgstr[1] "Changer de certificat"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "Changed Path"
msgstr "Changer de certificat"
@ -733,6 +733,10 @@ msgstr ""
msgid "Command"
msgstr "Commentaires"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -813,6 +817,10 @@ msgstr "Connexion perdue, merci de recharger la page."
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1053,7 +1061,7 @@ msgstr "Désactivé avec succès"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "Déployer"
@ -1262,6 +1270,10 @@ msgstr "Voulez-vous supprimer ce serveur ?"
msgid "Do you want to remove this upstream?"
msgstr "Voulez-vous supprimer ce serveur ?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1327,7 +1339,7 @@ msgstr "Modifier %{n}"
msgid "Edit %{n}"
msgstr "Modifier %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "Modifier la configuration"
@ -1552,6 +1564,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "Obtenir un certificat"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/backup.ts:5
#, fuzzy
msgid "Failed to backup Nginx config files: {0}"
@ -1639,6 +1656,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1737,6 +1759,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1756,6 +1783,11 @@ msgstr "Échec de l'obtention des informations sur le certificat"
msgid "Failed to get certificate information"
msgstr "Échec de l'obtention des informations sur le certificat"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1766,6 +1798,16 @@ msgstr "Échec de l'obtention des informations sur le certificat"
msgid "Failed to get performance data"
msgstr "Échec de l'obtention des informations sur le certificat"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1791,6 +1833,11 @@ msgstr "Impossible d'activer %{msg}"
msgid "Failed to parse nginx.conf"
msgstr "Erreur lecture nginx.conf"
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/backup.ts:53
#, fuzzy
msgid "Failed to read encrypted file: {0}"
@ -1811,6 +1858,11 @@ msgstr "Impossible d'activer %{msg}"
msgid "Failed to read nginx.conf"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1836,6 +1888,11 @@ msgstr "Obtenir un certificat"
msgid "Failed to save Nginx performance settings"
msgstr "Échec de l'obtention des informations sur le certificat"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1901,14 +1958,10 @@ msgstr "Utilisateur chinois : https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "Dupliquer"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "Code de formatage"
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr "Erreur de format %{msg}"
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr "Formaté avec succès"
@ -1982,7 +2035,7 @@ msgstr "Cacher"
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2170,7 +2223,7 @@ msgid "Invalid file path: {0}"
msgstr "Format de la requête invalide"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr "Nom de fichier invalide"
@ -2608,7 +2661,7 @@ msgstr "Directive multiligne"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2652,7 +2705,7 @@ msgstr "Installer"
msgid "New name"
msgstr "Nom d'utilisateur"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "New Path"
msgstr "Chemin"
@ -2756,6 +2809,10 @@ msgstr "Chemin du journal des erreurs Nginx"
msgid "Nginx is not running"
msgstr ""
#: src/constants/errors/docker.ts:9
msgid "Nginx is not running in another container"
msgstr ""
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr ""
@ -3086,11 +3143,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr ""
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr ""
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr ""
@ -3138,7 +3195,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "Chemin"
@ -3234,7 +3291,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr "Veuillez renseigner un nom de fichier"
@ -3482,6 +3539,11 @@ msgstr "Recharger"
msgid "Reload Nginx"
msgstr "Rechargement de nginx"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "Impossible d'activer %{msg}"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3786,7 +3848,7 @@ msgstr "En cours d'éxécution"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4632,7 +4694,7 @@ msgstr "Mis à jour avec succés"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4927,6 +4989,9 @@ msgstr ""
msgid "Your passkeys"
msgstr ""
#~ msgid "Format error %{msg}"
#~ msgstr "Erreur de format %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr ""
#~ "Échec de l'enregistrement, une ou plusieurs erreurs de syntaxe ont été "

View file

@ -81,7 +81,7 @@ msgid "Add a passkey"
msgstr ""
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "구성 추가"
@ -296,7 +296,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr "사이트 및 스트림 구성에서 자동으로 색인됩니다."
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -350,7 +350,7 @@ msgstr ""
msgid "Base information"
msgstr "기본 정보"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -582,7 +582,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "인증서 변경"
msgstr[1] "인증서 변경"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "Changed Path"
msgstr "인증서 변경"
@ -695,6 +695,10 @@ msgstr ""
msgid "Command"
msgstr "명령어"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -775,6 +779,10 @@ msgstr "연결이 끊어졌습니다. 페이지를 새로 고침하세요."
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1009,7 +1017,7 @@ msgstr "성공적으로 삭제됨"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "배포"
@ -1211,6 +1219,10 @@ msgstr "이 서버를 제거하시겠습니까?"
msgid "Do you want to remove this upstream?"
msgstr "이 업스트림을 제거하시겠습니까?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1269,7 +1281,7 @@ msgstr "%{n} 편집"
msgid "Edit %{n}"
msgstr "%{n} 편집"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "구성 편집"
@ -1491,6 +1503,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "인증서 획득 실패"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1577,6 +1594,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1675,6 +1697,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1694,6 +1721,11 @@ msgstr "인증서 정보 가져오기 실패"
msgid "Failed to get certificate information"
msgstr "인증서 정보 가져오기 실패"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "%{msg} 활성화 실패"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1704,6 +1736,16 @@ msgstr "인증서 정보 가져오기 실패"
msgid "Failed to get performance data"
msgstr "인증서 정보 가져오기 실패"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "%{msg} 활성화 실패"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1728,6 +1770,11 @@ msgstr "%{msg} 활성화 실패"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1745,6 +1792,11 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1768,6 +1820,11 @@ msgstr "인증서 획득 실패"
msgid "Failed to save Nginx performance settings"
msgstr "인증서 정보 가져오기 실패"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "%{msg} 활성화 실패"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1829,15 +1886,10 @@ msgstr "중국 사용자를 위해: https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "복제 실패"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "코드 형식"
#: src/views/config/ConfigEditor.vue:218
#, fuzzy
msgid "Format error %{msg}"
msgstr "형식 오류 %{msg}"
#: src/views/config/ConfigEditor.vue:216
#, fuzzy
msgid "Format successfully"
@ -1913,7 +1965,7 @@ msgstr ""
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2088,7 +2140,7 @@ msgid "Invalid file path: {0}"
msgstr "Invalid E-mail!"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
#, fuzzy
msgid "Invalid filename"
msgstr "Invalid E-mail!"
@ -2528,7 +2580,7 @@ msgstr "단일 지시문"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2572,7 +2624,7 @@ msgstr "설치"
msgid "New name"
msgstr "이름 변경"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "New Path"
msgstr "경로"
@ -2676,6 +2728,10 @@ msgstr "Nginx 오류 로그 경로"
msgid "Nginx is not running"
msgstr ""
#: src/constants/errors/docker.ts:9
msgid "Nginx is not running in another container"
msgstr ""
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr ""
@ -3008,11 +3064,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr ""
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "덮어쓰기"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "기존 파일 덮어쓰기"
@ -3060,7 +3116,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "경로"
@ -3153,7 +3209,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
#, fuzzy
msgid "Please input a filename"
msgstr "사용자 이름을 입력해주세요!"
@ -3402,6 +3458,11 @@ msgstr "리로드"
msgid "Reload Nginx"
msgstr "Nginx 리로딩 중"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "%{msg} 활성화 실패"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3707,7 +3768,7 @@ msgstr "실행 중"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4544,7 +4605,7 @@ msgstr "성공적으로 저장되었습니다"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4844,6 +4905,10 @@ msgstr ""
msgid "Your passkeys"
msgstr ""
#, fuzzy
#~ msgid "Format error %{msg}"
#~ msgstr "형식 오류 %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr "저장 실패, 구성에서 구문 오류가 감지되었습니다."

View file

@ -71,7 +71,7 @@ msgstr ""
#: src/routes/modules/config.ts:20
#: src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr ""
@ -285,7 +285,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268
#: src/views/config/ConfigEditor.vue:266
#: src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195
#: src/views/nginx_log/NginxLog.vue:173
@ -338,7 +338,7 @@ msgstr ""
msgid "Base information"
msgstr ""
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -553,7 +553,7 @@ msgid_plural "Changed Certificates"
msgstr[0] ""
msgstr[1] ""
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr ""
@ -659,6 +659,10 @@ msgstr ""
msgid "Command"
msgstr ""
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -734,6 +738,10 @@ msgstr ""
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -953,7 +961,7 @@ msgstr ""
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr ""
@ -1144,6 +1152,10 @@ msgstr ""
msgid "Do you want to remove this upstream?"
msgstr ""
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
msgid "Document"
@ -1198,7 +1210,7 @@ msgid "Edit %{n}"
msgstr ""
#: src/routes/modules/config.ts:30
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr ""
@ -1403,6 +1415,10 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr ""
#: src/constants/errors/docker.ts:4
msgid "Failed to attach to exec instance: {0}"
msgstr ""
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1479,6 +1495,10 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr ""
#: src/constants/errors/docker.ts:13
msgid "Failed to create temp container: {0}"
msgstr ""
#: src/constants/errors/backup.ts:2
msgid "Failed to create temporary directory"
msgstr ""
@ -1563,6 +1583,10 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr ""
#: src/constants/errors/docker.ts:3
msgid "Failed to exec command: {0}"
msgstr ""
#: src/constants/errors/backup.ts:35
msgid "Failed to extract archive: {0}"
msgstr ""
@ -1579,6 +1603,10 @@ msgstr ""
msgid "Failed to get certificate information"
msgstr ""
#: src/constants/errors/docker.ts:10
msgid "Failed to get hostname: {0}"
msgstr ""
#: src/views/dashboard/components/ParamsOptimization.vue:61
msgid "Failed to get Nginx performance settings"
msgstr ""
@ -1587,6 +1615,14 @@ msgstr ""
msgid "Failed to get performance data"
msgstr ""
#: src/constants/errors/docker.ts:8
msgid "Failed to inspect container: {0}"
msgstr ""
#: src/constants/errors/docker.ts:12
msgid "Failed to inspect current container: {0}"
msgstr ""
#: src/components/ConfigHistory/ConfigHistory.vue:77
msgid "Failed to load history records"
msgstr ""
@ -1607,6 +1643,10 @@ msgstr ""
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
msgid "Failed to pull image: {0}"
msgstr ""
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1623,6 +1663,10 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
msgid "Failed to read output: {0}"
msgstr ""
#: src/constants/errors/backup.ts:21
msgid "Failed to read symlink: {0}"
msgstr ""
@ -1643,6 +1687,10 @@ msgstr ""
msgid "Failed to save Nginx performance settings"
msgstr ""
#: src/constants/errors/docker.ts:14
msgid "Failed to start temp container: {0}"
msgstr ""
#: src/constants/errors/backup.ts:38
msgid "Failed to verify hashes: {0}"
msgstr ""
@ -1701,14 +1749,10 @@ msgstr ""
msgid "Form parse failed"
msgstr ""
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr ""
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr ""
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr ""
@ -1779,7 +1823,7 @@ msgstr ""
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
msgid "History"
@ -1938,7 +1982,7 @@ msgid "Invalid file path: {0}"
msgstr ""
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr ""
@ -2336,7 +2380,7 @@ msgstr ""
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7
#: src/views/config/ConfigEditor.vue:311
#: src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2379,7 +2423,7 @@ msgstr ""
msgid "New name"
msgstr ""
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "New Path"
msgstr ""
@ -2476,6 +2520,10 @@ msgstr ""
msgid "Nginx is not running"
msgstr ""
#: src/constants/errors/docker.ts:9
msgid "Nginx is not running in another container"
msgstr ""
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr ""
@ -2785,11 +2833,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr ""
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr ""
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr ""
@ -2833,7 +2881,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr ""
@ -2914,7 +2962,7 @@ msgid "Please generate new recovery codes in the preferences immediately to prev
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr ""
@ -3137,6 +3185,10 @@ msgstr ""
msgid "Reload Nginx"
msgstr ""
#: src/constants/errors/nginx.ts:3
msgid "Reload nginx failed: {0}"
msgstr ""
#: src/components/Notification/notifications.ts:10
msgid "Reload Nginx on %{node} failed, response: %{resp}"
msgstr ""
@ -3400,7 +3452,7 @@ msgstr ""
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4127,7 +4179,7 @@ msgstr ""
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36
#: src/views/config/ConfigEditor.vue:331
#: src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38

View file

@ -83,7 +83,7 @@ msgid "Add a passkey"
msgstr "Добавить ключ доступа"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "Добавить конфигурацию"
@ -300,7 +300,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -354,7 +354,7 @@ msgstr ""
msgid "Base information"
msgstr "Основная информация"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -581,7 +581,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "Сертификат изменен"
msgstr[1] "Сертификаты изменены"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr "Путь изменён"
@ -694,6 +694,10 @@ msgstr ""
msgid "Command"
msgstr "Команда"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -774,6 +778,10 @@ msgstr "Соединение потеряно, пожалуйста, обнов
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1004,7 +1012,7 @@ msgstr "Удалено успешно"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "Развернуть"
@ -1207,6 +1215,10 @@ msgstr "Хотите удалить этот сервер?"
msgid "Do you want to remove this upstream?"
msgstr "Хотите удалить этот сервер?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1268,7 +1280,7 @@ msgstr "Редактировать %{n}"
msgid "Edit %{n}"
msgstr "Редактировать %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "Редактировать Конфигурацию"
@ -1482,6 +1494,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "Не удалось получить сертификат"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1568,6 +1585,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1666,6 +1688,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1685,6 +1712,11 @@ msgstr "Не удалось получить информацию о серти
msgid "Failed to get certificate information"
msgstr "Не удалось получить информацию о сертификате"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "Не удалось включить %{msg}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1695,6 +1727,16 @@ msgstr "Не удалось получить информацию о серти
msgid "Failed to get performance data"
msgstr "Не удалось получить информацию о сертификате"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "Не удалось включить %{msg}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1719,6 +1761,11 @@ msgstr "Не удалось включить %{msg}"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1736,6 +1783,11 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1759,6 +1811,11 @@ msgstr "Не удалось получить сертификат"
msgid "Failed to save Nginx performance settings"
msgstr "Не удалось получить информацию о сертификате"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "Не удалось включить %{msg}"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1822,14 +1879,10 @@ msgstr "Для китайских пользователей: https://mirror.ghp
msgid "Form parse failed"
msgstr "Дублирование не удалось"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "Форматировать код"
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr "Ошибка формата %{msg}"
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr "Форматирование успешно"
@ -1904,7 +1957,7 @@ msgstr "Скрыть"
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2085,7 +2138,7 @@ msgid "Invalid file path: {0}"
msgstr "Неверное имя файла"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr "Неверное имя файла"
@ -2508,7 +2561,7 @@ msgstr "Многострочная директива"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2551,7 +2604,7 @@ msgstr "Установить"
msgid "New name"
msgstr "Новое имя"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "New Path"
msgstr "Новый путь"
@ -2653,6 +2706,11 @@ msgstr "Путь для Nginx Error Log"
msgid "Nginx is not running"
msgstr "Nginx не работает"
#: src/constants/errors/docker.ts:9
#, fuzzy
msgid "Nginx is not running in another container"
msgstr "Nginx не работает"
#: src/views/dashboard/NginxDashBoard.vue:112
#, fuzzy
msgid "Nginx is running"
@ -2983,11 +3041,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr "Код OTP или восстановления пуст"
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "Перезаписать"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "Перезаписать существующий файл"
@ -3035,7 +3093,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "Путь"
@ -3134,7 +3192,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr "Пожалуйста, введите имя файла"
@ -3380,6 +3438,11 @@ msgstr "Перегрузить"
msgid "Reload Nginx"
msgstr "Перезагружается nginx"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "Не удалось включить %{msg}"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3670,7 +3733,7 @@ msgstr "Выполняется"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4517,7 +4580,7 @@ msgstr "Успешно обновлено"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4811,6 +4874,9 @@ msgstr "Ваши старые коды больше не будут работа
msgid "Your passkeys"
msgstr ""
#~ msgid "Format error %{msg}"
#~ msgstr "Ошибка формата %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr ""
#~ "Не удалось сохранить, обнаружены синтаксические ошибки в конфигурации."

View file

@ -80,7 +80,7 @@ msgid "Add a passkey"
msgstr "Geçiş anahtarı ekleme"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "Yapılandırma Ekle"
@ -297,7 +297,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -351,7 +351,7 @@ msgstr ""
msgid "Base information"
msgstr "Temel bilgiler"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -582,7 +582,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "Değişen Sertifika"
msgstr[1] "Değişen Sertifikalar"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr "Değişen Dosya Yolu"
@ -695,6 +695,10 @@ msgstr ""
msgid "Command"
msgstr "Komut"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -775,6 +779,10 @@ msgstr "Bağlantı kesildi, lütfen sayfayı yenileyin."
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1011,7 +1019,7 @@ msgstr "Başarıyla silindi"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "Yayınla"
@ -1225,6 +1233,10 @@ msgstr "Bu sunucuyu kaldırmak istiyor musunuz?"
msgid "Do you want to remove this upstream?"
msgstr "Bu upstream'i kaldırmak istiyor musunuz?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1287,7 +1299,7 @@ msgstr "Düzenle %{n}"
msgid "Edit %{n}"
msgstr "Düzenle %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "Yapılandırmayı Düzenle"
@ -1515,6 +1527,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "Sertifika alınamadı"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1601,6 +1618,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1699,6 +1721,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1718,6 +1745,11 @@ msgstr "Sertifika bilgileri alınamadı"
msgid "Failed to get certificate information"
msgstr "Sertifika bilgileri alınamadı"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1728,6 +1760,16 @@ msgstr "Sertifika bilgileri alınamadı"
msgid "Failed to get performance data"
msgstr "Sertifika bilgileri alınamadı"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1752,6 +1794,11 @@ msgstr "Etkinleştirilemedi %{msg}"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1769,6 +1816,11 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1792,6 +1844,11 @@ msgstr "Sertifika alınamadı"
msgid "Failed to save Nginx performance settings"
msgstr "Sertifika bilgileri alınamadı"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1855,14 +1912,10 @@ msgstr "Çinli kullanıcılar için: https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "Kopyalama başarısız oldu"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "Kodu Biçimlendir"
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr "Biçimlendirme hatası %{msg}"
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr "Başarıyla biçimlendirildi"
@ -1937,7 +1990,7 @@ msgstr "Gizle"
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2119,7 +2172,7 @@ msgid "Invalid file path: {0}"
msgstr "Geçersiz dosya adı"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr "Geçersiz dosya adı"
@ -2559,7 +2612,7 @@ msgstr "Çok Hatlı Direktif"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2608,7 +2661,7 @@ msgstr "Yükle"
msgid "New name"
msgstr "Yeni Ad"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "New Path"
msgstr "Yeni Yol"
@ -2719,6 +2772,11 @@ msgstr "Nginx Hata Günlüğü Yolu"
msgid "Nginx is not running"
msgstr "Nginx çalışmıyor"
#: src/constants/errors/docker.ts:9
#, fuzzy
msgid "Nginx is not running in another container"
msgstr "Nginx çalışmıyor"
#: src/views/dashboard/NginxDashBoard.vue:112
#, fuzzy
msgid "Nginx is running"
@ -3074,12 +3132,12 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr "Kurtarma kodunu kullanın"
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
#, fuzzy
msgid "Overwrite"
msgstr "Üzerine yaz"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
#, fuzzy
msgid "Overwrite exist file"
msgstr "Mevcut dosyanın üzerine yaz"
@ -3136,7 +3194,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
#, fuzzy
msgid "Path"
@ -3245,7 +3303,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
#, fuzzy
msgid "Please input a filename"
msgstr "Lütfen bir dosya adı girin"
@ -3522,6 +3580,11 @@ msgstr "Tekrar yükle"
msgid "Reload Nginx"
msgstr "Nginx'i yeniden yükleme"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "Etkinleştirilemedi %{msg}"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3843,7 +3906,7 @@ msgstr "Çalışıyor"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4768,7 +4831,7 @@ msgstr "Güncellendi"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -5098,6 +5161,9 @@ msgstr ""
msgid "Your passkeys"
msgstr "Geçiş anahtarlarınız"
#~ msgid "Format error %{msg}"
#~ msgstr "Biçimlendirme hatası %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr "Kaydedilemedi, yapılandırmada sözdizimi hatası(ları) tespit edildi."

View file

@ -80,7 +80,7 @@ msgid "Add a passkey"
msgstr ""
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "Додати конфігурацію"
@ -296,7 +296,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -347,7 +347,7 @@ msgstr ""
msgid "Base information"
msgstr ""
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -566,7 +566,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr ""
@ -678,6 +678,10 @@ msgstr ""
msgid "Command"
msgstr ""
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -753,6 +757,10 @@ msgstr ""
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -971,7 +979,7 @@ msgstr ""
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr ""
@ -1158,6 +1166,10 @@ msgstr ""
msgid "Do you want to remove this upstream?"
msgstr ""
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
msgid "Document"
@ -1214,7 +1226,7 @@ msgstr ""
msgid "Edit %{n}"
msgstr ""
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr ""
@ -1415,6 +1427,10 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr ""
#: src/constants/errors/docker.ts:4
msgid "Failed to attach to exec instance: {0}"
msgstr ""
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1491,6 +1507,10 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr ""
#: src/constants/errors/docker.ts:13
msgid "Failed to create temp container: {0}"
msgstr ""
#: src/constants/errors/backup.ts:2
msgid "Failed to create temporary directory"
msgstr ""
@ -1575,6 +1595,10 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr ""
#: src/constants/errors/docker.ts:3
msgid "Failed to exec command: {0}"
msgstr ""
#: src/constants/errors/backup.ts:35
msgid "Failed to extract archive: {0}"
msgstr ""
@ -1591,6 +1615,10 @@ msgstr ""
msgid "Failed to get certificate information"
msgstr ""
#: src/constants/errors/docker.ts:10
msgid "Failed to get hostname: {0}"
msgstr ""
#: src/views/dashboard/components/ParamsOptimization.vue:61
msgid "Failed to get Nginx performance settings"
msgstr ""
@ -1599,6 +1627,14 @@ msgstr ""
msgid "Failed to get performance data"
msgstr ""
#: src/constants/errors/docker.ts:8
msgid "Failed to inspect container: {0}"
msgstr ""
#: src/constants/errors/docker.ts:12
msgid "Failed to inspect current container: {0}"
msgstr ""
#: src/components/ConfigHistory/ConfigHistory.vue:77
msgid "Failed to load history records"
msgstr ""
@ -1619,6 +1655,10 @@ msgstr ""
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
msgid "Failed to pull image: {0}"
msgstr ""
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1635,6 +1675,10 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
msgid "Failed to read output: {0}"
msgstr ""
#: src/constants/errors/backup.ts:21
msgid "Failed to read symlink: {0}"
msgstr ""
@ -1655,6 +1699,10 @@ msgstr ""
msgid "Failed to save Nginx performance settings"
msgstr ""
#: src/constants/errors/docker.ts:14
msgid "Failed to start temp container: {0}"
msgstr ""
#: src/constants/errors/backup.ts:38
msgid "Failed to verify hashes: {0}"
msgstr ""
@ -1714,14 +1762,10 @@ msgstr ""
msgid "Form parse failed"
msgstr ""
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr ""
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr ""
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr ""
@ -1792,7 +1836,7 @@ msgstr ""
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
msgid "History"
@ -1959,7 +2003,7 @@ msgid "Invalid file path: {0}"
msgstr ""
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr ""
@ -2358,7 +2402,7 @@ msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2400,7 +2444,7 @@ msgstr ""
msgid "New name"
msgstr ""
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "New Path"
msgstr ""
@ -2496,6 +2540,10 @@ msgstr ""
msgid "Nginx is not running"
msgstr ""
#: src/constants/errors/docker.ts:9
msgid "Nginx is not running in another container"
msgstr ""
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr ""
@ -2807,11 +2855,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr ""
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr ""
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr ""
@ -2857,7 +2905,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr ""
@ -2947,7 +2995,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr ""
@ -3175,6 +3223,10 @@ msgstr ""
msgid "Reload Nginx"
msgstr ""
#: src/constants/errors/nginx.ts:3
msgid "Reload nginx failed: {0}"
msgstr ""
#: src/components/Notification/notifications.ts:10
msgid "Reload Nginx on %{node} failed, response: %{resp}"
msgstr ""
@ -3441,7 +3493,7 @@ msgstr ""
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4216,7 +4268,7 @@ msgstr ""
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38

View file

@ -77,7 +77,7 @@ msgid "Add a passkey"
msgstr ""
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
#, fuzzy
msgid "Add Configuration"
msgstr "Sửa cấu hình"
@ -312,7 +312,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr ""
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -367,7 +367,7 @@ msgstr ""
msgid "Base information"
msgstr "Thông tin"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
#, fuzzy
@ -606,7 +606,7 @@ msgid_plural "Changed Certificates"
msgstr[0] "Thay đổi chứng chỉ"
msgstr[1] "Thay đổi chứng chỉ"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "Changed Path"
msgstr "Thay đổi chứng chỉ"
@ -721,6 +721,10 @@ msgstr ""
msgid "Command"
msgstr "Bình luận"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -801,6 +805,10 @@ msgstr ""
msgid "Connection timeout period"
msgstr ""
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -1038,7 +1046,7 @@ msgstr "Đã xoá thành công"
msgid "Demo"
msgstr ""
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "Triển khai"
@ -1246,6 +1254,10 @@ msgstr "Bạn muốn xóa máy chủ này ?"
msgid "Do you want to remove this upstream?"
msgstr "Bạn muốn xóa máy chủ này ?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
#, fuzzy
@ -1306,7 +1318,7 @@ msgstr "Sửa %{n}"
msgid "Edit %{n}"
msgstr "Sửa %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "Sửa cấu hình"
@ -1531,6 +1543,11 @@ msgstr ""
msgid "Fail to obtain certificate"
msgstr "Nhận chứng chỉ"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr ""
@ -1617,6 +1634,11 @@ msgstr ""
msgid "Failed to create symbolic link: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/backup.ts:2
#, fuzzy
msgid "Failed to create temporary directory"
@ -1715,6 +1737,11 @@ msgstr ""
msgid "Failed to evaluate symbolic links: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/backup.ts:35
#, fuzzy
msgid "Failed to extract archive: {0}"
@ -1734,6 +1761,11 @@ msgstr "Không thể truy xuất thông tin chứng chỉ"
msgid "Failed to get certificate information"
msgstr "Không thể truy xuất thông tin chứng chỉ"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "Không thể bật %{msg}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
#, fuzzy
msgid "Failed to get Nginx performance settings"
@ -1744,6 +1776,16 @@ msgstr "Không thể truy xuất thông tin chứng chỉ"
msgid "Failed to get performance data"
msgstr "Không thể truy xuất thông tin chứng chỉ"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "Không thể bật %{msg}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
#, fuzzy
msgid "Failed to load history records"
@ -1768,6 +1810,11 @@ msgstr "Không thể bật %{msg}"
msgid "Failed to parse nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr ""
@ -1785,6 +1832,11 @@ msgstr ""
msgid "Failed to read nginx.conf"
msgstr ""
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/backup.ts:21
#, fuzzy
msgid "Failed to read symlink: {0}"
@ -1808,6 +1860,11 @@ msgstr "Nhận chứng chỉ"
msgid "Failed to save Nginx performance settings"
msgstr "Không thể truy xuất thông tin chứng chỉ"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "Không thể bật %{msg}"
#: src/constants/errors/backup.ts:38
#, fuzzy
msgid "Failed to verify hashes: {0}"
@ -1870,15 +1927,10 @@ msgstr "Người dùng Trung Quốc: https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "Nhân bản thất bại"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "Định dạng code"
#: src/views/config/ConfigEditor.vue:218
#, fuzzy
msgid "Format error %{msg}"
msgstr "Lưu lỗi %{msg}"
#: src/views/config/ConfigEditor.vue:216
#, fuzzy
msgid "Format successfully"
@ -1954,7 +2006,7 @@ msgstr ""
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
#, fuzzy
@ -2128,7 +2180,7 @@ msgid "Invalid file path: {0}"
msgstr "E-mail không chính xác!"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
#, fuzzy
msgid "Invalid filename"
msgstr "E-mail không chính xác!"
@ -2562,7 +2614,7 @@ msgstr "Single Directive"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2606,7 +2658,7 @@ msgstr "Cài đặt"
msgid "New name"
msgstr "Username"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
#, fuzzy
msgid "New Path"
msgstr "Đường dẫn"
@ -2709,6 +2761,10 @@ msgstr "Vị trí lưu log lỗi (Error log) của Nginx"
msgid "Nginx is not running"
msgstr ""
#: src/constants/errors/docker.ts:9
msgid "Nginx is not running in another container"
msgstr ""
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr ""
@ -3039,11 +3095,11 @@ msgstr ""
msgid "Otp or recovery code empty"
msgstr ""
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "Ghi đè"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "Ghi đè tập tin đã tồn tại"
@ -3091,7 +3147,7 @@ msgstr ""
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "Đường dẫn"
@ -3185,7 +3241,7 @@ msgid ""
msgstr ""
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
#, fuzzy
msgid "Please input a filename"
msgstr "Vui lòng nhập username!"
@ -3431,6 +3487,11 @@ msgstr "Tải lại"
msgid "Reload Nginx"
msgstr "Tải lại nginx"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "Không thể bật %{msg}"
#: src/components/Notification/notifications.ts:10
#, fuzzy
msgid "Reload Nginx on %{node} failed, response: %{resp}"
@ -3736,7 +3797,7 @@ msgstr "Running"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4566,7 +4627,7 @@ msgstr "Cập nhật thành công"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4866,6 +4927,10 @@ msgstr ""
msgid "Your passkeys"
msgstr ""
#, fuzzy
#~ msgid "Format error %{msg}"
#~ msgstr "Lưu lỗi %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr "Không lưu được, đã phát hiện thấy (các) lỗi cú pháp trong cấu hình."

View file

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2025-04-19 14:14+0800\n"
"PO-Revision-Date: 2025-04-21 14:19+0800\n"
"Last-Translator: 0xJacky <me@jackyu.cn>\n"
"Language-Team: Chinese (Simplified Han script) <https://weblate.nginxui.com/"
"projects/nginx-ui/frontend/zh_Hans/>\n"
@ -81,7 +81,7 @@ msgid "Add a passkey"
msgstr "添加 Passkey"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "添加配置"
@ -294,7 +294,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr "自动索引站点和 Stream 的配置文件。"
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -345,7 +345,7 @@ msgstr "Bark"
msgid "Base information"
msgstr "基本信息"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -562,7 +562,7 @@ msgid "Changed Certificate"
msgid_plural "Changed Certificates"
msgstr[0] "变更证书"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr "变更后的路径"
@ -677,6 +677,10 @@ msgstr "代码补全模型"
msgid "Command"
msgstr "命令"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr "命令以意外退出代码退出:{0},错误:{1}"
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -752,6 +756,10 @@ msgstr "连接中断,请刷新页面。"
msgid "Connection timeout period"
msgstr "连接超时时间"
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr "未知容器状态"
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -971,7 +979,7 @@ msgstr "删除成功"
msgid "Demo"
msgstr "Demo"
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "部署"
@ -1158,6 +1166,10 @@ msgstr "你想删除这个服务器吗?"
msgid "Do you want to remove this upstream?"
msgstr "你想删除这个 Upstream 吗?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr "Docker 客户端未初始化"
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
msgid "Document"
@ -1214,7 +1226,7 @@ msgstr "编辑"
msgid "Edit %{n}"
msgstr "编辑 %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "编辑配置"
@ -1415,6 +1427,10 @@ msgstr "外部通知"
msgid "Fail to obtain certificate"
msgstr "获取证书失败"
#: src/constants/errors/docker.ts:4
msgid "Failed to attach to exec instance: {0}"
msgstr "连接执行实例失败:{0}"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr "备份 Nginx 配置文件失败:{0}"
@ -1491,6 +1507,10 @@ msgstr "创建还原目录失败:{0}"
msgid "Failed to create symbolic link: {0}"
msgstr "创建符号链接失败:{0}"
#: src/constants/errors/docker.ts:13
msgid "Failed to create temp container: {0}"
msgstr "创建临时容器失败:{0}"
#: src/constants/errors/backup.ts:2
msgid "Failed to create temporary directory"
msgstr "创建临时目录失败"
@ -1575,6 +1595,10 @@ msgstr "加密 Nginx UI 目录失败:{0}"
msgid "Failed to evaluate symbolic links: {0}"
msgstr "符号链接解析失败:{0}"
#: src/constants/errors/docker.ts:3
msgid "Failed to exec command: {0}"
msgstr "执行命令失败:{0}"
#: src/constants/errors/backup.ts:35
msgid "Failed to extract archive: {0}"
msgstr "解压缩失败:{0}"
@ -1591,6 +1615,10 @@ msgstr "生成初始化向量失败:{0}"
msgid "Failed to get certificate information"
msgstr "获取证书信息失败"
#: src/constants/errors/docker.ts:10
msgid "Failed to get hostname: {0}"
msgstr "获取主机名失败: {0}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
msgid "Failed to get Nginx performance settings"
msgstr "获取 Nginx 性能参数失败"
@ -1599,6 +1627,14 @@ msgstr "获取 Nginx 性能参数失败"
msgid "Failed to get performance data"
msgstr "获取性能数据失败"
#: src/constants/errors/docker.ts:8
msgid "Failed to inspect container: {0}"
msgstr "检查容器失败:{0}"
#: src/constants/errors/docker.ts:12
msgid "Failed to inspect current container: {0}"
msgstr "检查当前容器失败:{0}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
msgid "Failed to load history records"
msgstr "加载历史记录失败"
@ -1619,6 +1655,10 @@ msgstr "打开压缩文件失败:{0}"
msgid "Failed to parse nginx.conf"
msgstr "解析 nginx.conf 失败"
#: src/constants/errors/docker.ts:11
msgid "Failed to pull image: {0}"
msgstr "拉取镜像失败:{0}"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr "读取加密文件失败:{0}"
@ -1635,6 +1675,10 @@ msgstr "读取哈希信息文件失败:{0}"
msgid "Failed to read nginx.conf"
msgstr "读取 nginx.conf 失败"
#: src/constants/errors/docker.ts:5
msgid "Failed to read output: {0}"
msgstr "读取输出失败:{0}"
#: src/constants/errors/backup.ts:21
msgid "Failed to read symlink: {0}"
msgstr "读取符号链接失败:{0}"
@ -1655,6 +1699,10 @@ msgstr "证书撤销失败"
msgid "Failed to save Nginx performance settings"
msgstr "保存 Nginx 性能参数失败"
#: src/constants/errors/docker.ts:14
msgid "Failed to start temp container: {0}"
msgstr "启动临时容器失败:{0}"
#: src/constants/errors/backup.ts:38
msgid "Failed to verify hashes: {0}"
msgstr "验证哈希值失败:{0}"
@ -1714,14 +1762,10 @@ msgstr "中国用户https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "表单解析失败"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "代码格式化"
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr "保存错误 %{msg}"
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr "格式化成功"
@ -1792,7 +1836,7 @@ msgstr "隐藏"
msgid "Higher value means better connection reuse"
msgstr "更高的值意味着更好的连接再利用"
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
msgid "History"
@ -1962,7 +2006,7 @@ msgid "Invalid file path: {0}"
msgstr "文件路径无效:{0}"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr "文件名无效"
@ -2368,7 +2412,7 @@ msgstr "多行指令"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2410,7 +2454,7 @@ msgstr "新安装"
msgid "New name"
msgstr "新名称"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "New Path"
msgstr "新路径"
@ -2506,6 +2550,10 @@ msgstr "Nginx 错误日志路径"
msgid "Nginx is not running"
msgstr "Nginx 未启动"
#: src/constants/errors/docker.ts:9
msgid "Nginx is not running in another container"
msgstr "Nginx 未在另一个容器中运行"
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr "Nginx 正在运行"
@ -2817,11 +2865,11 @@ msgstr "其他"
msgid "Otp or recovery code empty"
msgstr "OTP 或恢复代码为空"
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "覆盖"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "覆盖现有文件"
@ -2869,7 +2917,7 @@ msgstr "密码长度不能超过 20 个字符"
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "路径"
@ -2961,7 +3009,7 @@ msgid ""
msgstr "请立即在偏好设置中生成新的恢复码,以防止无法访问您的账户。"
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr "请输入文件名"
@ -3191,6 +3239,10 @@ msgstr "重载"
msgid "Reload Nginx"
msgstr "重载 Nginx"
#: src/constants/errors/nginx.ts:3
msgid "Reload nginx failed: {0}"
msgstr "重载 Nginx 失败: {0}"
#: src/components/Notification/notifications.ts:10
msgid "Reload Nginx on %{node} failed, response: %{resp}"
msgstr "在 %{node} 上重载 Nginx 失败,响应:%{resp}"
@ -3459,7 +3511,7 @@ msgstr "运行中"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -3615,19 +3667,19 @@ msgstr "使用 HTTP01 challenge provider"
#: src/constants/errors/nginx_log.ts:8
msgid ""
"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://nginxui."
"com/guide/config-nginx.html for more information"
"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://"
"nginxui.com/guide/config-nginx.html for more information"
msgstr ""
"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://nginxui."
"com/guide/config-nginx.html"
"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://"
"nginxui.com/guide/config-nginx.html"
#: src/constants/errors/nginx_log.ts:7
msgid ""
"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://nginxui."
"com/guide/config-nginx.html for more information"
"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://"
"nginxui.com/guide/config-nginx.html for more information"
msgstr ""
"Settings.NginxLogSettings.ErrorLogPath为空更多信息请参阅 https://nginxui."
"com/guide/config-nginx.html"
"Settings.NginxLogSettings.ErrorLogPath为空更多信息请参阅 https://"
"nginxui.com/guide/config-nginx.html"
#: src/views/dashboard/components/ParamsOpt/ProxyCacheConfig.vue:147
msgid "Shared Memory Zone"
@ -4252,7 +4304,7 @@ msgstr "更新成功"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4545,6 +4597,9 @@ msgstr "您的旧代码将不再有效。"
msgid "Your passkeys"
msgstr "你的 Passkeys"
#~ msgid "Format error %{msg}"
#~ msgstr "保存错误 %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr "保存失败,在配置中检测到语法错误。"
@ -4641,8 +4696,8 @@ msgstr "你的 Passkeys"
#~ msgstr "请将远程 Nginx UI 升级到最新版本"
#~ msgid ""
#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
#~ "%{resp}"
#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %"
#~ "{resp}"
#~ msgstr ""
#~ "将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path} 失败,响应:%{resp}"

View file

@ -85,7 +85,7 @@ msgid "Add a passkey"
msgstr "新增通行金鑰"
#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:171
#: src/views/config/ConfigEditor.vue:246
#: src/views/config/ConfigEditor.vue:244
msgid "Add Configuration"
msgstr "新增設定"
@ -298,7 +298,7 @@ msgid "Automatically indexed from site and stream configurations."
msgstr "自動從網站和串流設定中索引。"
#: src/views/certificate/components/CertificateEditor.vue:259
#: src/views/config/ConfigEditor.vue:268 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigEditor.vue:266 src/views/config/ConfigList.vue:112
#: src/views/config/ConfigList.vue:195 src/views/nginx_log/NginxLog.vue:173
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:150
#: src/views/stream/components/StreamEditor.vue:106
@ -349,7 +349,7 @@ msgstr "Bark"
msgid "Base information"
msgstr "基本資訊"
#: src/views/config/ConfigEditor.vue:296
#: src/views/config/ConfigEditor.vue:294
#: src/views/site/site_edit/components/RightPanel/RightPanel.vue:30
#: src/views/stream/components/RightPanel/RightPanel.vue:19
msgid "Basic"
@ -566,7 +566,7 @@ msgid "Changed Certificate"
msgid_plural "Changed Certificates"
msgstr[0] "變更後憑證"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "Changed Path"
msgstr "變更後路徑"
@ -685,6 +685,10 @@ msgstr ""
msgid "Command"
msgstr "命令"
#: src/constants/errors/docker.ts:6
msgid "Command exited with unexpected exit code: {0}, error: {1}"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:115
#: src/components/NgxConfigEditor/LocationEditor.vue:104
#: src/components/NgxConfigEditor/LocationEditor.vue:135
@ -761,6 +765,10 @@ msgstr "連線中斷,請重新整理此頁面。"
msgid "Connection timeout period"
msgstr "連線逾時時間"
#: src/constants/errors/docker.ts:7
msgid "Container status unknown"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:120
#: src/components/NgxConfigEditor/LocationEditor.vue:116
#: src/components/NgxConfigEditor/LocationEditor.vue:144
@ -980,7 +988,7 @@ msgstr "刪除成功"
msgid "Demo"
msgstr "演示"
#: src/views/config/ConfigEditor.vue:340
#: src/views/config/ConfigEditor.vue:338
msgid "Deploy"
msgstr "部署"
@ -1168,6 +1176,10 @@ msgstr "您要移除此伺服器嗎?"
msgid "Do you want to remove this upstream?"
msgstr "您要移除這個 Upstream 嗎?"
#: src/constants/errors/docker.ts:2
msgid "Docker client not initialized"
msgstr ""
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:88
#: src/components/NgxConfigEditor/directive/DirectiveDocuments.vue:16
msgid "Document"
@ -1224,7 +1236,7 @@ msgstr "編輯"
msgid "Edit %{n}"
msgstr "編輯 %{n}"
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:246
#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:244
msgid "Edit Configuration"
msgstr "編輯設定"
@ -1425,6 +1437,11 @@ msgstr "外部通知"
msgid "Fail to obtain certificate"
msgstr "取得憑證失敗"
#: src/constants/errors/docker.ts:4
#, fuzzy
msgid "Failed to attach to exec instance: {0}"
msgstr "無法提取存檔:{0}"
#: src/constants/errors/backup.ts:5
msgid "Failed to backup Nginx config files: {0}"
msgstr "備份 Nginx 設定檔案失敗:{0}"
@ -1501,6 +1518,11 @@ msgstr "無法建立還原目錄:{0}"
msgid "Failed to create symbolic link: {0}"
msgstr "建立符號連結失敗:{0}"
#: src/constants/errors/docker.ts:13
#, fuzzy
msgid "Failed to create temp container: {0}"
msgstr "無法建立壓縮項目:{0}"
#: src/constants/errors/backup.ts:2
msgid "Failed to create temporary directory"
msgstr "無法建立臨時目錄"
@ -1585,6 +1607,11 @@ msgstr "加密 Nginx UI 目錄失敗:{0}"
msgid "Failed to evaluate symbolic links: {0}"
msgstr "無法評估符號連結:{0}"
#: src/constants/errors/docker.ts:3
#, fuzzy
msgid "Failed to exec command: {0}"
msgstr "讀取檔案失敗:{0}"
#: src/constants/errors/backup.ts:35
msgid "Failed to extract archive: {0}"
msgstr "無法提取存檔:{0}"
@ -1601,6 +1628,11 @@ msgstr "無法生成初始化向量:{0}"
msgid "Failed to get certificate information"
msgstr "取得憑證資訊失敗"
#: src/constants/errors/docker.ts:10
#, fuzzy
msgid "Failed to get hostname: {0}"
msgstr "複製檔案內容失敗:{0}"
#: src/views/dashboard/components/ParamsOptimization.vue:61
msgid "Failed to get Nginx performance settings"
msgstr "無法取得 Nginx 效能設定"
@ -1609,6 +1641,16 @@ msgstr "無法取得 Nginx 效能設定"
msgid "Failed to get performance data"
msgstr "無法取得效能資料"
#: src/constants/errors/docker.ts:8
#, fuzzy
msgid "Failed to inspect container: {0}"
msgstr "複製檔案內容失敗:{0}"
#: src/constants/errors/docker.ts:12
#, fuzzy
msgid "Failed to inspect current container: {0}"
msgstr "複製檔案內容失敗:{0}"
#: src/components/ConfigHistory/ConfigHistory.vue:77
msgid "Failed to load history records"
msgstr "無法載入歷史記錄"
@ -1629,6 +1671,11 @@ msgstr "無法開啟壓縮檔:{0}"
msgid "Failed to parse nginx.conf"
msgstr "解析 nginx.conf 失敗"
#: src/constants/errors/docker.ts:11
#, fuzzy
msgid "Failed to pull image: {0}"
msgstr "讀取檔案失敗:{0}"
#: src/constants/errors/backup.ts:53
msgid "Failed to read encrypted file: {0}"
msgstr "無法讀取加密檔案:{0}"
@ -1645,6 +1692,11 @@ msgstr "無法讀取雜湊資訊檔案:{0}"
msgid "Failed to read nginx.conf"
msgstr "讀取 nginx.conf 失敗"
#: src/constants/errors/docker.ts:5
#, fuzzy
msgid "Failed to read output: {0}"
msgstr "讀取檔案失敗:{0}"
#: src/constants/errors/backup.ts:21
msgid "Failed to read symlink: {0}"
msgstr "讀取符號連結失敗:{0}"
@ -1665,6 +1717,11 @@ msgstr "撤銷憑證失敗"
msgid "Failed to save Nginx performance settings"
msgstr "儲存 Nginx 效能設定失敗"
#: src/constants/errors/docker.ts:14
#, fuzzy
msgid "Failed to start temp container: {0}"
msgstr "複製檔案內容失敗:{0}"
#: src/constants/errors/backup.ts:38
msgid "Failed to verify hashes: {0}"
msgstr "無法驗證雜湊值:{0}"
@ -1724,14 +1781,10 @@ msgstr "中國使用者https://mirror.ghproxy.com/"
msgid "Form parse failed"
msgstr "表單解析失敗"
#: src/views/config/ConfigEditor.vue:271
#: src/views/config/ConfigEditor.vue:269
msgid "Format Code"
msgstr "格式化代碼"
#: src/views/config/ConfigEditor.vue:218
msgid "Format error %{msg}"
msgstr "格式錯誤 %{msg}"
#: src/views/config/ConfigEditor.vue:216
msgid "Format successfully"
msgstr "成功格式化"
@ -1802,7 +1855,7 @@ msgstr "隱藏"
msgid "Higher value means better connection reuse"
msgstr ""
#: src/views/config/ConfigEditor.vue:256
#: src/views/config/ConfigEditor.vue:254
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:81
#: src/views/stream/components/StreamEditor.vue:43
msgid "History"
@ -1972,7 +2025,7 @@ msgid "Invalid file path: {0}"
msgstr "無效的檔案路徑:{0}"
#: src/views/config/components/Rename.vue:66
#: src/views/config/ConfigEditor.vue:305
#: src/views/config/ConfigEditor.vue:303
msgid "Invalid filename"
msgstr "無效的檔案名"
@ -2379,7 +2432,7 @@ msgstr "多行指令"
#: src/views/certificate/components/CertificateEditor.vue:162
#: src/views/certificate/DNSCredential.vue:11
#: src/views/config/components/Mkdir.vue:64
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:311
#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:309
#: src/views/environments/group/columns.ts:8
#: src/views/environments/list/envColumns.tsx:9
#: src/views/nginx_log/NginxLogList.vue:33
@ -2421,7 +2474,7 @@ msgstr "新安裝"
msgid "New name"
msgstr "新名稱"
#: src/views/config/ConfigEditor.vue:324
#: src/views/config/ConfigEditor.vue:322
msgid "New Path"
msgstr "新路徑"
@ -2519,6 +2572,11 @@ msgstr "Nginx 錯誤日誌路徑"
msgid "Nginx is not running"
msgstr "Nginx 未執行"
#: src/constants/errors/docker.ts:9
#, fuzzy
msgid "Nginx is not running in another container"
msgstr "Nginx 未執行"
#: src/views/dashboard/NginxDashBoard.vue:112
msgid "Nginx is running"
msgstr "Nginx 執行中"
@ -2832,11 +2890,11 @@ msgstr "其他"
msgid "Otp or recovery code empty"
msgstr "OTP 或復原碼為空"
#: src/views/config/ConfigEditor.vue:349
#: src/views/config/ConfigEditor.vue:347
msgid "Overwrite"
msgstr "覆寫"
#: src/views/config/ConfigEditor.vue:353
#: src/views/config/ConfigEditor.vue:351
msgid "Overwrite exist file"
msgstr "覆寫現有檔案"
@ -2884,7 +2942,7 @@ msgstr "密碼長度不能超過 20 個字元"
#: src/components/NgxConfigEditor/LocationEditor.vue:110
#: src/components/NgxConfigEditor/LocationEditor.vue:138
#: src/views/config/ConfigEditor.vue:318
#: src/views/config/ConfigEditor.vue:316
#: src/views/nginx_log/NginxLogList.vue:41
msgid "Path"
msgstr "路徑"
@ -2976,7 +3034,7 @@ msgid ""
msgstr "請立即在偏好設定中產生新的恢復碼,以免無法存取您的賬戶。"
#: src/views/config/components/Rename.vue:65
#: src/views/config/ConfigEditor.vue:304
#: src/views/config/ConfigEditor.vue:302
msgid "Please input a filename"
msgstr "請輸入檔案名稱"
@ -3205,6 +3263,11 @@ msgstr "重新載入"
msgid "Reload Nginx"
msgstr "重新載入 Nginx"
#: src/constants/errors/nginx.ts:3
#, fuzzy
msgid "Reload nginx failed: {0}"
msgstr "讀取檔案失敗:{0}"
#: src/components/Notification/notifications.ts:10
msgid "Reload Nginx on %{node} failed, response: %{resp}"
msgstr "在節點 %{node} 上重新載入 Nginx 失敗,回應:%{resp}"
@ -3473,7 +3536,7 @@ msgstr "執行中"
#: src/components/StdDesign/StdDetail/StdDetail.vue:93
#: src/views/certificate/components/CertificateEditor.vue:266
#: src/views/config/components/ConfigName.vue:59
#: src/views/config/ConfigEditor.vue:277
#: src/views/config/ConfigEditor.vue:275
#: src/views/preference/components/Passkey.vue:130
#: src/views/preference/Preference.vue:231
#: src/views/site/site_edit/components/ConfigName/ConfigName.vue:52
@ -4266,7 +4329,7 @@ msgstr "更新成功"
#: src/views/certificate/ACMEUser.vue:88
#: src/views/certificate/DNSCredential.vue:27
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:331
#: src/views/config/configColumns.tsx:36 src/views/config/ConfigEditor.vue:329
#: src/views/environments/group/columns.ts:37
#: src/views/environments/list/envColumns.tsx:90
#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
@ -4562,6 +4625,9 @@ msgstr "您的舊代碼將不再有效。"
msgid "Your passkeys"
msgstr "您的通行金鑰"
#~ msgid "Format error %{msg}"
#~ msgstr "格式錯誤 %{msg}"
#~ msgid "Failed to save, syntax error(s) was detected in the configuration."
#~ msgstr "儲存失敗,在設定中偵測到語法錯誤。"

View file

@ -1,137 +1,23 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import settings from '@/api/settings'
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
import use2FAModal from '@/components/TwoFA/use2FAModal'
import { useSettingsStore } from '@/pinia'
import AppSettings from '@/views/preference/AppSettings.vue'
import AuthSettings from '@/views/preference/AuthSettings.vue'
import CertSettings from '@/views/preference/CertSettings.vue'
import ExternalNotify from '@/views/preference/ExternalNotify.vue'
import HTTPSettings from '@/views/preference/HTTPSettings.vue'
import LogrotateSettings from '@/views/preference/LogrotateSettings.vue'
import NginxSettings from '@/views/preference/NginxSettings.vue'
import NodeSettings from '@/views/preference/NodeSettings.vue'
import OpenAISettings from '@/views/preference/OpenAISettings.vue'
import ServerSettings from '@/views/preference/ServerSettings.vue'
import TerminalSettings from '@/views/preference/TerminalSettings.vue'
import { message } from 'ant-design-vue'
import { storeToRefs } from 'pinia'
import FooterToolBar from '@/components/FooterToolbar'
import {
AppSettings,
AuthSettings,
CertSettings,
ExternalNotify,
HTTPSettings,
LogrotateSettings,
NginxSettings,
NodeSettings,
OpenAISettings,
ServerSettings,
TerminalSettings,
} from '@/views/preference/tabs'
import useSystemSettingsStore from './store'
const data = ref<Settings>({
app: {
page_size: 10,
jwt_secret: '',
},
server: {
host: '0.0.0.0',
port: 9000,
run_mode: 'debug',
enable_https: false,
ssl_cert: '',
ssl_key: '',
},
database: {
name: '',
},
auth: {
ip_white_list: [],
ban_threshold_minutes: 10,
max_attempts: 10,
},
casdoor: {
endpoint: '',
client_id: '',
client_secret: '',
certificate_path: '',
organization: '',
application: '',
redirect_uri: '',
},
cert: {
email: '',
ca_dir: '',
renewal_interval: 7,
recursive_nameservers: [],
http_challenge_port: '9180',
},
http: {
github_proxy: '',
insecure_skip_verify: false,
},
logrotate: {
enabled: false,
cmd: '',
interval: 1440,
},
nginx: {
access_log_path: '',
error_log_path: '',
config_dir: '',
config_path: '',
log_dir_white_list: [],
pid_path: '',
test_config_cmd: '',
reload_cmd: '',
restart_cmd: '',
stub_status_port: 51820,
},
node: {
name: '',
secret: '',
skip_installation: false,
demo: false,
icp_number: '',
public_security_number: '',
},
openai: {
model: '',
base_url: '',
proxy: '',
token: '',
api_type: 'OPEN_AI',
enable_code_completion: false,
code_completion_model: '',
},
terminal: {
start_cmd: '',
},
webauthn: {
rp_display_name: '',
rpid: '',
rp_origins: [],
},
})
const systemSettingsStore = useSystemSettingsStore()
settings.get().then(r => {
data.value = r
})
const settingsStore = useSettingsStore()
const { server_name } = storeToRefs(settingsStore)
const errors = ref<Record<string, Record<string, string>>>({})
const refAuthSettings = useTemplateRef('refAuthSettings')
async function save() {
// fix type
data.value.cert.http_challenge_port = data.value.cert.http_challenge_port.toString()
const otpModal = use2FAModal()
otpModal.open().then(() => {
settings.save(data.value).then(r => {
if (!settingsStore.is_remote)
server_name.value = r?.server?.name ?? ''
data.value = r
refAuthSettings.value?.getBannedIPs?.()
message.success($gettext('Save successfully'))
errors.value = {}
})
})
}
provide('data', data)
provide('errors', errors)
systemSettingsStore.getSettings()
const router = useRouter()
const route = useRoute()
@ -195,7 +81,7 @@ onMounted(() => {
key="auth"
:tab="$gettext('Auth')"
>
<AuthSettings ref="refAuthSettings" />
<AuthSettings />
</ATabPane>
<ATabPane
key="cert"
@ -226,7 +112,7 @@ onMounted(() => {
<FooterToolBar v-if="activeKey !== 'external_notify'">
<AButton
type="primary"
@click="save"
@click="systemSettingsStore.save"
>
{{ $gettext('Save') }}
</AButton>

View file

@ -1,14 +1,14 @@
<script setup lang="ts">
import type { Passkey } from '@/api/passkey'
import passkey from '@/api/passkey'
import ReactiveFromNow from '@/components/ReactiveFromNow/ReactiveFromNow.vue'
import ReactiveFromNow from '@/components/ReactiveFromNow'
import { formatDateTime } from '@/lib/helper'
import { useUserStore } from '@/pinia'
import AddPasskey from '@/views/preference/components/AddPasskey.vue'
import { DeleteOutlined, EditOutlined, KeyOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import AddPasskey from './AddPasskey.vue'
dayjs.extend(relativeTime)

View file

@ -2,7 +2,7 @@
import type { TwoFAStatus } from '@/api/2fa'
import type { RecoveryCode } from '@/api/recovery'
import recovery from '@/api/recovery'
import use2FAModal from '@/components/TwoFA/use2FAModal'
import { use2FAModal } from '@/components/TwoFA'
import { CopyOutlined, WarningOutlined } from '@ant-design/icons-vue'
import { UseClipboard } from '@vueuse/components'
import { message } from 'ant-design-vue'

View file

@ -1,8 +1,8 @@
<script setup lang="ts">
import type { RecoveryCode } from '@/api/recovery'
import otp from '@/api/otp'
import OTPInput from '@/components/OTPInput/OTPInput.vue'
import use2FAModal from '@/components/TwoFA/use2FAModal'
import OTPInput from '@/components/OTPInput'
import { use2FAModal } from '@/components/TwoFA'
import { CheckCircleOutlined } from '@ant-design/icons-vue'
import { UseClipboard } from '@vueuse/components'
import { message } from 'ant-design-vue'

View file

@ -0,0 +1,11 @@
import AddPasskey from './AddPasskey.vue'
import Passkey from './Passkey.vue'
import RecoveryCodes from './RecoveryCodes.vue'
import TOTP from './TOTP.vue'
export {
AddPasskey,
Passkey,
RecoveryCodes,
TOTP,
}

View file

@ -0,0 +1,127 @@
import type { Settings } from '@/api/settings'
import settings from '@/api/settings'
import { use2FAModal } from '@/components/TwoFA'
import { useSettingsStore } from '@/pinia'
import { message } from 'ant-design-vue'
import { defineStore } from 'pinia'
const useSystemSettingsStore = defineStore('systemSettings', () => {
const data = ref<Settings>({
app: {
page_size: 10,
jwt_secret: '',
},
server: {
host: '0.0.0.0',
port: 9000,
run_mode: 'debug',
enable_https: false,
ssl_cert: '',
ssl_key: '',
},
database: {
name: '',
},
auth: {
ip_white_list: [],
ban_threshold_minutes: 10,
max_attempts: 10,
},
casdoor: {
endpoint: '',
client_id: '',
client_secret: '',
certificate_path: '',
organization: '',
application: '',
redirect_uri: '',
},
cert: {
email: '',
ca_dir: '',
renewal_interval: 7,
recursive_nameservers: [],
http_challenge_port: '9180',
},
http: {
github_proxy: '',
insecure_skip_verify: false,
},
logrotate: {
enabled: false,
cmd: '',
interval: 1440,
},
nginx: {
access_log_path: '',
error_log_path: '',
config_dir: '',
config_path: '',
log_dir_white_list: [],
pid_path: '',
test_config_cmd: '',
reload_cmd: '',
restart_cmd: '',
stub_status_port: 51820,
container_name: '',
},
node: {
name: '',
secret: '',
skip_installation: false,
demo: false,
icp_number: '',
public_security_number: '',
},
openai: {
model: '',
base_url: '',
proxy: '',
token: '',
api_type: 'OPEN_AI',
enable_code_completion: false,
code_completion_model: '',
},
terminal: {
start_cmd: '',
},
webauthn: {
rp_display_name: '',
rpid: '',
rp_origins: [],
},
})
const errors = ref<Record<string, Record<string, string>>>({})
function getSettings() {
settings.get().then(r => {
data.value = r
})
}
async function save() {
if (!data.value)
return
// fix type
data.value.cert.http_challenge_port = data.value.cert.http_challenge_port.toString()
const otpModal = use2FAModal()
otpModal.open().then(() => {
settings.save(data.value!).then(r => {
const settingsStore = useSettingsStore()
const { server_name } = storeToRefs(settingsStore)
if (!settingsStore.is_remote)
server_name.value = r?.server?.name ?? ''
data.value = r
message.success($gettext('Save successfully'))
errors.value = {}
})
})
}
return { data, errors, getSettings, save }
})
export default useSystemSettingsStore

View file

@ -1,8 +1,9 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import SensitiveString from '@/components/SensitiveString/SensitiveString.vue'
import SensitiveString from '@/components/SensitiveString'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const systemSettingsStore = useSystemSettingsStore()
const { data } = storeToRefs(systemSettingsStore)
</script>
<template>

View file

@ -1,18 +1,18 @@
<script setup lang="tsx">
import type { TwoFAStatus } from '@/api/2fa'
import type { RecoveryCode } from '@/api/recovery'
import type { BannedIP, Settings } from '@/api/settings'
import type { BannedIP } from '@/api/settings'
import type { CustomRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
import type { Ref } from 'vue'
import twoFA from '@/api/2fa'
import setting from '@/api/settings'
import RecoveryCodes from '@/views/preference/components/RecoveryCodes.vue'
import TOTP from '@/views/preference/components/TOTP.vue'
import { message } from 'ant-design-vue'
import dayjs from 'dayjs'
import PasskeyRegistration from './components/Passkey.vue'
import { Passkey, RecoveryCodes, TOTP } from '../components/AuthSettings'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const systemSettingsStore = useSystemSettingsStore()
const { data } = storeToRefs(systemSettingsStore)
const bannedIPColumns = [{
title: $gettext('IP'),
@ -68,7 +68,7 @@ get2FAStatus()
<div class="flex justify-center">
<div>
<h2>{{ $gettext('2FA Settings') }}</h2>
<PasskeyRegistration class="mb-4" />
<Passkey class="mb-4" />
<TOTP
v-model:recovery-codes="recoveryCodes"

View file

@ -1,10 +1,10 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
import Draggable from 'vuedraggable'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
const systemSettingsStore = useSystemSettingsStore()
const { data, errors } = storeToRefs(systemSettingsStore)
</script>
<template>

View file

@ -1,8 +1,8 @@
<script setup lang="ts">
import externalNotify from '@/api/external_notify'
import { StdCurd } from '@/components/StdDesign/StdDataDisplay'
import columns from './components/ExternalNotify/columns'
import ExternalNotifyEditor from './components/ExternalNotify/ExternalNotifyEditor.vue'
import ExternalNotifyEditor from '../components/ExternalNotify'
import columns from '../components/ExternalNotify/columns'
</script>
<template>

View file

@ -1,8 +1,8 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
const systemSettingsStore = useSystemSettingsStore()
const { data, errors } = storeToRefs(systemSettingsStore)
</script>
<template>

View file

@ -1,7 +1,8 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const systemSettingsStore = useSystemSettingsStore()
const { data } = storeToRefs(systemSettingsStore)
</script>
<template>

View file

@ -1,7 +1,8 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const systemSettingsStore = useSystemSettingsStore()
const { data } = storeToRefs(systemSettingsStore)
</script>
<template>
@ -42,6 +43,19 @@ const data: Ref<Settings> = inject('data') as Ref<Settings>
<AFormItem :label="$gettext('Nginx Restart Command')">
{{ data.nginx.restart_cmd }}
</AFormItem>
<AFormItem :label="$gettext('Nginx Control Mode')">
<div v-if="data.nginx.container_name">
<ATag color="blue" tag>
{{ $gettext('External Docker Container') }}
</ATag>
{{ data.nginx.container_name }}
</div>
<div v-else>
<ATag color="green" tag>
{{ $gettext('Local') }}
</ATag>
</div>
</AFormItem>
</AForm>
</template>

View file

@ -1,9 +1,9 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import SensitiveString from '@/components/SensitiveString/SensitiveString.vue'
import SensitiveString from '@/components/SensitiveString'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
const systemSettingsStore = useSystemSettingsStore()
const { data, errors } = storeToRefs(systemSettingsStore)
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import { LLM_MODELS, LLM_PROVIDERS } from '@/constants/llm'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
const systemSettingsStore = useSystemSettingsStore()
const { data, errors } = storeToRefs(systemSettingsStore)
const models = LLM_MODELS.map(model => ({
value: model,

View file

@ -1,9 +1,10 @@
<script setup lang="ts">
import type { Cert } from '@/api/cert'
import type { Settings } from '@/api/settings'
import ChangeCert from '@/views/site/site_edit/components/Cert/ChangeCert.vue'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const systemSettingsStore = useSystemSettingsStore()
const { data } = storeToRefs(systemSettingsStore)
function handleCertChange(certs: Cert[]) {
if (certs.length > 0 && data.value?.server) {

View file

@ -1,7 +1,8 @@
<script setup lang="ts">
import type { Settings } from '@/api/settings'
import useSystemSettingsStore from '../store'
const data: Ref<Settings> = inject('data') as Ref<Settings>
const systemSettingsStore = useSystemSettingsStore()
const { data } = storeToRefs(systemSettingsStore)
</script>
<template>

View file

@ -0,0 +1,11 @@
export { default as AppSettings } from './AppSettings.vue'
export { default as AuthSettings } from './AuthSettings.vue'
export { default as CertSettings } from './CertSettings.vue'
export { default as ExternalNotify } from './ExternalNotify.vue'
export { default as HTTPSettings } from './HTTPSettings.vue'
export { default as LogrotateSettings } from './LogrotateSettings.vue'
export { default as NginxSettings } from './NginxSettings.vue'
export { default as NodeSettings } from './NodeSettings.vue'
export { default as OpenAISettings } from './OpenAISettings.vue'
export { default as ServerSettings } from './ServerSettings.vue'
export { default as TerminalSettings } from './TerminalSettings.vue'

View file

@ -101,18 +101,12 @@ If the `--sbin-path` path cannot be obtained from `nginx -V`, Nginx UI will use
nginx
```
If the `--sbin-path` path can be obtained, Nginx UI will use the following command to start the Nginx service:
```bash
start-stop-daemon --start --quiet --pidfile $PID --exec $SBIN_PATH
```
## Stub Status
In this section, we will introduce configuration options in Nginx UI for the Nginx stub status module.
### StubStatusPort
- Type: `uint`
- Default: `51820`
@ -123,3 +117,23 @@ This option is used to set the port for the Nginx stub status module. The stub s
::: tip Tip
Make sure the port you set is not being used by other services.
:::
## Container Control
In this section, we will introduce configuration options in Nginx UI for controlling Nginx services running in another Docker container.
### ContainerName
- Type: `string`
- Version: `>= v2.0.0-rc.6`
This option is used to specify the name of the Docker container where Nginx is running.
If this option is empty, Nginx UI will control the Nginx service on the local machine or within the current container.
If this option is not empty, Nginx UI will control the Nginx service running in the specified container.
::: tip Tip
If you are using the official Nginx UI container and want to control Nginx in another container, you must map the host's docker.sock to the Nginx UI container.
For example: `-v /var/run/docker.sock:/var/run/docker.sock`
:::

View file

@ -108,10 +108,6 @@ nginx
start-stop-daemon --start --quiet --pidfile $PID --exec $SBIN_PATH
```
## Stub Status
在本节中,我们将会介绍 Nginx UI 中关于 Nginx stub status 模块的配置选项。
### StubStatusPort
- 类型:`uint`
- 默认值:`51820`
@ -123,4 +119,22 @@ start-stop-daemon --start --quiet --pidfile $PID --exec $SBIN_PATH
请确保您设置的端口未被其他服务占用。
:::
## 容器控制
在本节中,我们将会介绍 Nginx UI 中关于控制运行在另一个 Docker 容器中的 Nginx 服务的配置选项。
### ContainerName
- 类型:`string`
- 版本:`>= v2.0.0-rc.6`
此选项用于指定运行 Nginx 的 Docker 容器名称。
如果此选项为空Nginx UI 将控制本机或当前容器内的 Nginx 服务。
如果此选项不为空Nginx UI 将控制运行在指定容器中的 Nginx 服务。
::: tip 提示
如果使用 Nginx UI 官方容器,想要控制另外一个容器里的 Nginx务必将宿主机内的 docker.sock 映射到 Nginx UI 官方容器中。
例如:`-v /var/run/docker.sock:/var/run/docker.sock`
:::

View file

@ -101,10 +101,6 @@ start-stop-daemon --stop --quiet --oknodo --retry=TERM/30/KILL/5 --pidfile $PID
start-stop-daemon --start --quiet --pidfile $PID --exec $SBIN_PATH
```
## Stub Status
在本節中,我們將會介紹 Nginx UI 中關於 Nginx stub status 模組的設定選項。
### StubStatusPort
- 類型:`uint`
- 預設值:`51820`
@ -115,3 +111,23 @@ start-stop-daemon --start --quiet --pidfile $PID --exec $SBIN_PATH
::: tip 提示
請確保您設定的連接埠未被其他服務佔用。
:::
## 容器控制
在本節中,我們將會介紹 Nginx UI 中關於控制運行在另一個 Docker 容器中的 Nginx 服務的設定選項。
### ContainerName
- 類型:`string`
- 版本:`>= v2.0.0-rc.6`
此選項用於指定執行 Nginx 的 Docker 容器名稱。
如果此選項為空Nginx UI 將控制本機或當前容器內的 Nginx 服務。
如果此選項不為空Nginx UI 將控制執行在指定容器中的 Nginx 服務。
::: tip 提示
如果使用 Nginx UI 官方容器,想要控制另外一個容器裡的 Nginx務必將宿主機內的 docker.sock 映射到 Nginx UI 官方容器中。
例如:`-v /var/run/docker.sock:/var/run/docker.sock`
:::

13
go.mod
View file

@ -9,6 +9,7 @@ require (
github.com/casdoor/casdoor-go-sdk v1.5.0
github.com/creack/pty v1.1.24
github.com/dgraph-io/ristretto/v2 v2.2.0
github.com/docker/docker v28.1.1+incompatible
github.com/dustin/go-humanize v1.0.1
github.com/elliotchance/orderedmap/v3 v3.1.0
github.com/fsnotify/fsnotify v1.9.0
@ -75,6 +76,7 @@ require (
github.com/Azure/go-autorest/logger v0.2.2 // indirect
github.com/Azure/go-autorest/tracing v0.6.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
github.com/Microsoft/go-winio v0.4.14 // indirect
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
@ -106,10 +108,14 @@ require (
github.com/civo/civogo v0.3.98 // indirect
github.com/cloudflare/cloudflare-go v0.115.0 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/dnsimple/dnsimple-go v1.7.0 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/ebitengine/purego v0.8.2 // indirect
github.com/exoscale/egoscale/v3 v3.1.14 // indirect
github.com/fatih/color v1.18.0 // indirect
@ -184,8 +190,12 @@ require (
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
github.com/nrdcg/auroradns v1.1.0 // indirect
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea // indirect
@ -199,6 +209,8 @@ require (
github.com/nrdcg/nodion v0.1.0 // indirect
github.com/nrdcg/porkbun v0.4.0 // indirect
github.com/nzdjb/go-metaname v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/oracle/oci-go-sdk/v65 v65.89.1 // indirect
github.com/ovh/go-ovh v1.7.0 // indirect
@ -257,6 +269,7 @@ require (
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.uber.org/atomic v1.11.0 // indirect

46
go.sum
View file

@ -632,6 +632,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourceg
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0/go.mod h1:wVEOJfGTj0oPAUGA1JuRAvz/lxXQsWW16axmHPP47Bk=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA=
@ -675,6 +677,8 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXY
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
@ -698,8 +702,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.105 h1:Bj8SsBTGElGniuL83+VqfHnxZIPc7n+rzpwDZIB4rZg=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.105/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.106 h1:+YPfQheppCKOPJxhWDmStF1UMJrxnA1iiwBH12t6Fa4=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.106/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
@ -790,7 +792,6 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -825,6 +826,8 @@ github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@ -853,8 +856,16 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dnsimple/dnsimple-go v1.7.0 h1:JKu9xJtZ3SqOC+BuYgAWeab7+EEx0sz422vu8j611ZY=
github.com/dnsimple/dnsimple-go v1.7.0/go.mod h1:EKpuihlWizqYafSnQHGCd/gyvy3HkEQJ7ODB4KdV8T8=
github.com/docker/docker v28.1.1+incompatible h1:49M11BFLsVO1gxY9UX9p/zwkE/rswggs8AdFmXQw51I=
github.com/docker/docker v28.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
@ -912,8 +923,6 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
@ -1168,9 +1177,12 @@ github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
github.com/guregu/null/v6 v6.0.0 h1:N14VRS+4di81i1PXRiprbQJ9EM9gqBa0+KVMeS/QSjQ=
github.com/guregu/null/v6 v6.0.0/go.mod h1:hrMIhIfrOZeLPZhROSn149tpw2gHkidAqxoXNyeX3iQ=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
@ -1478,6 +1490,14 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -1486,6 +1506,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g=
@ -1549,6 +1571,10 @@ github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5h
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
@ -1770,8 +1796,6 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1136/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1145 h1:DETyir/MtG+GLOD0OatzjrQTTXRguFSJo1ZtPXtbIQw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1145/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1146 h1:PMhgU4BETyTiikegps6gDtLamNWUiLMEx4fv16UWspY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1146/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1136 h1:kMIdSU5IvpOROh27ToVQ3hlm6ym3lCRs9tnGCOBoZqk=
@ -1817,8 +1841,6 @@ github.com/urfave/cli/v3 v3.1.1 h1:bNnl8pFI5dxPOjeONvFCDFoECLQsceDG4ejahs4Jtxk=
github.com/urfave/cli/v3 v3.1.1/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo=
github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ=
github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q=
github.com/volcengine/volc-sdk-golang v1.0.203 h1:y4zZEjKp6nz3UK8Tb/qdz9tvB915KLO6nc1WNME0Zb8=
github.com/volcengine/volc-sdk-golang v1.0.203/go.mod h1:stZX+EPgv1vF4nZwOlEe8iGcriUPRBKX8zA19gXycOQ=
github.com/volcengine/volc-sdk-golang v1.0.204 h1:Njid6coReHV2gWc3bsqWMQf+K8jveauzW8zEX08CTzI=
github.com/volcengine/volc-sdk-golang v1.0.204/go.mod h1:stZX+EPgv1vF4nZwOlEe8iGcriUPRBKX8zA19gXycOQ=
github.com/vultr/govultr/v3 v3.19.1 h1:31rOP5Tz40AOc8h6Ws4ryzqAniUBffgRhy9uMG/EFvs=
@ -1881,6 +1903,10 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRND
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
@ -1892,6 +1918,8 @@ go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=

View file

@ -26,10 +26,11 @@ func NewAppCmd() *cli.Command {
},
},
{
Name: "reset-password",
Usage: "Reset the initial user password",
Name: "reset-password",
Usage: "Reset the initial user password",
Action: user.ResetInitUserPassword,
},
UpgradeDockerStep2Command,
},
Flags: []cli.Flag{
&cli.StringFlag{

View file

@ -0,0 +1,23 @@
package cmd
import (
"context"
"github.com/0xJacky/Nginx-UI/internal/docker"
"github.com/uozi-tech/cosy/logger"
"github.com/urfave/cli/v3"
)
// Command to be executed in the temporary container
var UpgradeDockerStep2Command = &cli.Command{
Name: "upgrade-docker-step2",
Usage: "Execute the second step of Docker container upgrade (to be run inside the temp container)",
Action: UpgradeDockerStep2,
}
// UpgradeDockerStep2 executes the second step in the temporary container
func UpgradeDockerStep2(ctx context.Context, command *cli.Command) error {
logger.Info("Starting Docker OTA upgrade step 2 from CLI...")
return docker.UpgradeStepTwo(ctx)
}

View file

@ -45,7 +45,11 @@ func Save(absPath string, content string, cfg *model.Config) (err error) {
return
}
output := nginx.Reload()
output, err := nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) >= nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

22
internal/docker/docker.go Normal file
View file

@ -0,0 +1,22 @@
package docker
import (
"context"
"github.com/docker/docker/client"
)
// Initialize Docker client from environment variables
func initClient() (cli *client.Client, err error) {
cli, err = client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return
}
// Optionally ping the server to ensure the connection is valid
_, err = cli.Ping(context.Background())
if err != nil {
return
}
return
}

20
internal/docker/errors.go Normal file
View file

@ -0,0 +1,20 @@
package docker
import "github.com/uozi-tech/cosy"
var (
e = cosy.NewErrorScope("docker")
ErrClientNotInitialized = e.New(500001, "docker client not initialized")
ErrFailedToExec = e.New(500002, "failed to exec command: {0}")
ErrFailedToAttach = e.New(500003, "failed to attach to exec instance: {0}")
ErrReadOutput = e.New(500004, "failed to read output: {0}")
ErrExitUnexpected = e.New(500005, "command exited with unexpected exit code: {0}, error: {1}")
ErrContainerStatusUnknown = e.New(500006, "container status unknown")
ErrInspectContainer = e.New(500007, "failed to inspect container: {0}")
ErrNginxNotRunningInAnotherContainer = e.New(500008, "nginx is not running in another container")
ErrFailedToGetHostname = e.New(500009, "failed to get hostname: {0}")
ErrFailedToPullImage = e.New(500010, "failed to pull image: {0}")
ErrFailedToInspectCurrentContainer = e.New(500011, "failed to inspect current container: {0}")
ErrFailedToCreateTempContainer = e.New(500012, "failed to create temp container: {0}")
ErrFailedToStartTempContainer = e.New(500013, "failed to start temp container: {0}")
)

80
internal/docker/exec.go Normal file
View file

@ -0,0 +1,80 @@
package docker
import (
"bytes"
"context"
"io"
"strconv"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/stdcopy"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger"
)
// Exec executes a command in a specific container and returns the output.
func Exec(ctx context.Context, command []string) (string, error) {
if !settings.NginxSettings.RunningInAnotherContainer() {
return "", ErrNginxNotRunningInAnotherContainer
}
cli, err := initClient()
if err != nil {
return "", cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error())
}
defer cli.Close()
execConfig := container.ExecOptions{
AttachStdout: true,
AttachStderr: true, // Also attach stderr to capture errors from the command
Cmd: command,
}
// Create the exec instance
execCreateResp, err := cli.ContainerExecCreate(ctx, settings.NginxSettings.ContainerName, execConfig)
if err != nil {
return "", cosy.WrapErrorWithParams(ErrFailedToExec, err.Error())
}
execID := execCreateResp.ID
// Attach to the exec instance
hijackedResp, err := cli.ContainerExecAttach(ctx, execID, container.ExecAttachOptions{})
if err != nil {
return "", cosy.WrapErrorWithParams(ErrFailedToAttach, err.Error())
}
defer hijackedResp.Close()
// Read the output
var outBuf, errBuf bytes.Buffer
outputDone := make(chan error)
go func() {
// stdcopy.StdCopy demultiplexes the stream into two buffers
_, err = stdcopy.StdCopy(&outBuf, &errBuf, hijackedResp.Reader)
outputDone <- err
}()
select {
case err := <-outputDone:
if err != nil && err != io.EOF { // io.EOF is expected when the stream finishes
return "", cosy.WrapErrorWithParams(ErrReadOutput, err.Error())
}
case <-ctx.Done():
return "", cosy.WrapErrorWithParams(ErrReadOutput, ctx.Err().Error())
}
// Optionally inspect the exec process to check the exit code
execInspectResp, err := cli.ContainerExecInspect(ctx, execID)
logger.Debug("docker exec result", outBuf.String(), errBuf.String())
if err != nil {
return "", cosy.WrapErrorWithParams(ErrExitUnexpected, err.Error())
} else if execInspectResp.ExitCode != 0 {
// Command exited with a non-zero status code. Return stderr as part of the error.
return outBuf.String(), cosy.WrapErrorWithParams(ErrExitUnexpected, strconv.Itoa(execInspectResp.ExitCode), errBuf.String())
}
// Return stdout if successful
return outBuf.String(), nil
}

329
internal/docker/ota.go Normal file
View file

@ -0,0 +1,329 @@
package docker
import (
"context"
"fmt"
"io"
"os"
"strings"
"time"
"github.com/0xJacky/Nginx-UI/internal/upgrader"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger"
)
const (
ImageName = "uozi/nginx-ui"
TempPrefix = "nginx-ui-temp-"
OldSuffix = "_old"
)
// getTimestampedTempName returns a temporary container name with timestamp
func getTimestampedTempName() string {
return fmt.Sprintf("%s%d", TempPrefix, time.Now().Unix())
}
// removeAllTempContainers removes all containers with the TempPrefix
func removeAllTempContainers(ctx context.Context, cli *client.Client) (err error) {
containers, err := cli.ContainerList(ctx, container.ListOptions{All: true})
if err != nil {
return
}
for _, c := range containers {
for _, name := range c.Names {
processedName := strings.TrimPrefix(name, "/")
if strings.HasPrefix(processedName, TempPrefix) {
err = cli.ContainerRemove(ctx, c.ID, container.RemoveOptions{Force: true})
if err != nil {
logger.Error("Failed to remove temp container:", err)
} else {
logger.Info("Successfully removed temp container:", processedName)
}
break
}
}
}
return nil
}
// UpgradeStepOne Trigger in the OTA upgrade
func UpgradeStepOne(channel string) (err error) {
ctx := context.Background()
// 1. Get the tag of the latest release
release, err := upgrader.GetRelease(channel)
if err != nil {
return err
}
tag := release.TagName
// 2. Pull the image
cli, err := initClient()
if err != nil {
return cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error())
}
defer cli.Close()
// Pull the image with the specified tag
out, err := cli.ImagePull(ctx, fmt.Sprintf("%s:%s", ImageName, tag), image.PullOptions{})
if err != nil {
return cosy.WrapErrorWithParams(ErrFailedToPullImage, err.Error())
}
defer out.Close()
// Wait for pull to complete by reading the output
io.Copy(os.Stdout, out)
// 3. Create a temp container
// Clean up any existing temp containers
err = removeAllTempContainers(ctx, cli)
if err != nil {
logger.Error("Failed to clean up existing temp containers:", err)
// Continue execution despite cleanup errors
}
// Generate timestamped temp container name
tempContainerName := getTimestampedTempName()
// Get current container name
hostname, err := os.Hostname()
if err != nil {
return cosy.WrapErrorWithParams(ErrFailedToGetHostname, err.Error())
}
containerInfo, err := cli.ContainerInspect(ctx, hostname)
if err != nil {
return cosy.WrapErrorWithParams(ErrFailedToInspectCurrentContainer, err.Error())
}
currentContainerName := strings.TrimPrefix(containerInfo.Name, "/")
// Set up the command for the temp container to execute step 2
upgradeCmd := []string{"./nginx-ui", "upgrade-docker-step2"}
// Add old container name as environment variable
containerEnv := containerInfo.Config.Env
containerEnv = append(containerEnv, fmt.Sprintf("NGINX_UI_CONTAINER_NAME=%s", currentContainerName))
// Create temp container using new image
_, err = cli.ContainerCreate(
ctx,
&container.Config{
Image: fmt.Sprintf("%s:%s", ImageName, tag),
Cmd: upgradeCmd, // Use upgrade command instead of original command
Env: containerEnv,
},
&container.HostConfig{
Binds: containerInfo.HostConfig.Binds,
PortBindings: containerInfo.HostConfig.PortBindings,
RestartPolicy: containerInfo.HostConfig.RestartPolicy,
},
nil,
nil,
tempContainerName,
)
if err != nil {
return cosy.WrapErrorWithParams(ErrFailedToCreateTempContainer, err.Error())
}
// Start the temp container to execute step 2
err = cli.ContainerStart(ctx, tempContainerName, container.StartOptions{})
if err != nil {
return cosy.WrapErrorWithParams(ErrFailedToStartTempContainer, err.Error())
}
// Output status information
logger.Info("Docker OTA upgrade step 1 completed. Temp container started to execute step 2.")
return nil
}
// UpgradeStepTwo Trigger in the temp container
func UpgradeStepTwo(ctx context.Context) (err error) {
// 1. Copy the old config
cli, err := initClient()
if err != nil {
return
}
defer cli.Close()
// Get old container name from environment variable, fallback to settings if not available
currentContainerName := os.Getenv("NGINX_UI_CONTAINER_NAME")
if currentContainerName == "" {
return errors.New("could not find old container name")
}
// Get the current running temp container name
// Since we can't directly get our own container name from inside, we'll search all temp containers
containers, err := cli.ContainerList(ctx, container.ListOptions{All: true})
if err != nil {
return errors.Wrap(err, "failed to list containers")
}
// Find containers with the temp prefix
var tempContainerName string
for _, c := range containers {
for _, name := range c.Names {
processedName := strings.TrimPrefix(name, "/")
if strings.HasPrefix(processedName, TempPrefix) {
tempContainerName = processedName
break
}
}
if tempContainerName != "" {
break
}
}
if tempContainerName == "" {
return errors.New("could not find temp container")
}
// Get temp container info to get the new image
tempContainerInfo, err := cli.ContainerInspect(ctx, tempContainerName)
if err != nil {
return errors.Wrap(err, "failed to inspect temp container")
}
newImage := tempContainerInfo.Config.Image
// Get current container info
oldContainerInfo, err := cli.ContainerInspect(ctx, currentContainerName)
if err != nil {
return errors.Wrap(err, "failed to inspect current container")
}
// 2. Stop the old container and rename to _old
err = cli.ContainerStop(ctx, currentContainerName, container.StopOptions{})
if err != nil {
return errors.Wrap(err, "failed to stop current container")
}
// Rename the old container with _old suffix
err = cli.ContainerRename(ctx, currentContainerName, currentContainerName+OldSuffix)
if err != nil {
return errors.Wrap(err, "failed to rename old container")
}
// 3. Use the old config to create and start a new container with the updated image
// Create new container with original config but using the new image
newContainerEnv := oldContainerInfo.Config.Env
// Pass the old container name to the new container
newContainerEnv = append(newContainerEnv, fmt.Sprintf("NGINX_UI_CONTAINER_NAME=%s", currentContainerName))
_, err = cli.ContainerCreate(
ctx,
&container.Config{
Image: newImage,
Cmd: oldContainerInfo.Config.Cmd,
Env: newContainerEnv,
Entrypoint: oldContainerInfo.Config.Entrypoint,
Labels: oldContainerInfo.Config.Labels,
ExposedPorts: oldContainerInfo.Config.ExposedPorts,
Volumes: oldContainerInfo.Config.Volumes,
WorkingDir: oldContainerInfo.Config.WorkingDir,
},
&container.HostConfig{
Binds: oldContainerInfo.HostConfig.Binds,
PortBindings: oldContainerInfo.HostConfig.PortBindings,
RestartPolicy: oldContainerInfo.HostConfig.RestartPolicy,
NetworkMode: oldContainerInfo.HostConfig.NetworkMode,
Mounts: oldContainerInfo.HostConfig.Mounts,
Privileged: oldContainerInfo.HostConfig.Privileged,
},
nil,
nil,
currentContainerName,
)
if err != nil {
// If creation fails, try to recover
recoverErr := cli.ContainerRename(ctx, currentContainerName+OldSuffix, currentContainerName)
if recoverErr == nil {
// Start old container
recoverErr = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{})
if recoverErr == nil {
return errors.Wrap(err, "failed to create new container, recovered to old container")
}
}
return errors.Wrap(err, "failed to create new container and failed to recover")
}
// Start the new container
err = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{})
if err != nil {
// If startup fails, try to recover
// First remove the failed new container
removeErr := cli.ContainerRemove(ctx, currentContainerName, container.RemoveOptions{Force: true})
if removeErr != nil {
logger.Error("Failed to remove failed new container:", removeErr)
}
// Rename the old container back to original
recoverErr := cli.ContainerRename(ctx, currentContainerName+OldSuffix, currentContainerName)
if recoverErr == nil {
// Start old container
recoverErr = cli.ContainerStart(ctx, currentContainerName, container.StartOptions{})
if recoverErr == nil {
return errors.Wrap(err, "failed to start new container, recovered to old container")
}
}
return errors.Wrap(err, "failed to start new container and failed to recover")
}
logger.Info("Docker OTA upgrade step 2 completed successfully. New container is running.")
return nil
}
// UpgradeStepThree Trigger in the new container
func UpgradeStepThree() error {
ctx := context.Background()
// Remove the old container
cli, err := initClient()
if err != nil {
return cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error())
}
defer cli.Close()
// Get old container name from environment variable, fallback to settings if not available
currentContainerName := os.Getenv("NGINX_UI_CONTAINER_NAME")
if currentContainerName == "" {
logger.Warn("Old container name not found in environment, skipping cleanup")
return nil
}
oldContainerName := currentContainerName + OldSuffix
// Check if old container exists and remove it if it does
containers, err := cli.ContainerList(ctx, container.ListOptions{All: true})
if err != nil {
return errors.Wrap(err, "failed to list containers")
}
for _, c := range containers {
for _, name := range c.Names {
processedName := strings.TrimPrefix(name, "/")
// Remove old container
if processedName == oldContainerName {
err = cli.ContainerRemove(ctx, c.ID, container.RemoveOptions{Force: true})
if err != nil {
logger.Error("Failed to remove old container:", err)
// Continue execution, don't interrupt because of failure to remove old container
} else {
logger.Info("Successfully removed old container:", oldContainerName)
}
break
}
}
}
// Clean up all temp containers
err = removeAllTempContainers(ctx, cli)
if err != nil {
logger.Error("Failed to clean up temp containers:", err)
// Continue execution despite cleanup errors
}
return nil
}

View file

@ -0,0 +1,29 @@
package docker
import (
"context"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/uozi-tech/cosy/logger"
)
// StatPath checks if a path exists in the container
func StatPath(path string) bool {
if !settings.NginxSettings.RunningInAnotherContainer() {
return false
}
cli, err := initClient()
if err != nil {
return false
}
defer cli.Close()
_, err = cli.ContainerStatPath(context.Background(), settings.NginxSettings.ContainerName, path)
if err != nil {
logger.Error("Failed to stat path", "error", err)
return false
}
return true
}

58
internal/docker/status.go Normal file
View file

@ -0,0 +1,58 @@
package docker
import (
"context"
"github.com/docker/docker/client"
"github.com/uozi-tech/cosy"
)
type ContainerStatus int
const (
ContainerStatusCreated ContainerStatus = iota
ContainerStatusRunning
ContainerStatusPaused
ContainerStatusRestarting
ContainerStatusRemoving
ContainerStatusExited
ContainerStatusDead
ContainerStatusUnknown
ContainerStatusNotFound
)
var (
containerStatusMap = map[string]ContainerStatus{
"created": ContainerStatusCreated,
"running": ContainerStatusRunning,
"paused": ContainerStatusPaused,
"restarting": ContainerStatusRestarting,
"removing": ContainerStatusRemoving,
"exited": ContainerStatusExited,
"dead": ContainerStatusDead,
}
)
// GetContainerStatus checks the status of a given container.
func GetContainerStatus(ctx context.Context, containerID string) (ContainerStatus, error) {
cli, err := initClient()
if err != nil {
return ContainerStatusUnknown, cosy.WrapErrorWithParams(ErrClientNotInitialized, err.Error())
}
defer cli.Close()
containerJSON, err := cli.ContainerInspect(ctx, containerID)
if err != nil {
if client.IsErrNotFound(err) {
return ContainerStatusNotFound, nil // Container doesn't exist
}
return ContainerStatusUnknown, cosy.WrapErrorWithParams(ErrInspectContainer, err.Error())
}
// Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead"
status, ok := containerStatusMap[containerJSON.State.Status]
if !ok {
return ContainerStatusUnknown, ErrContainerStatusUnknown
}
return status, nil
}

View file

@ -12,6 +12,7 @@ import (
"github.com/0xJacky/Nginx-UI/internal/cert"
"github.com/0xJacky/Nginx-UI/internal/cluster"
"github.com/0xJacky/Nginx-UI/internal/cron"
"github.com/0xJacky/Nginx-UI/internal/docker"
"github.com/0xJacky/Nginx-UI/internal/passkey"
"github.com/0xJacky/Nginx-UI/internal/validation"
"github.com/0xJacky/Nginx-UI/model"
@ -35,6 +36,7 @@ func Boot() {
InitCryptoSecret,
validation.Init,
cache.Init,
CheckAndCleanupOTAContainers,
}
syncs := []func(){
@ -129,3 +131,14 @@ func InitJsExtensionType() {
// See https://github.com/golang/go/issues/32350
_ = mime.AddExtensionType(".js", "text/javascript; charset=utf-8")
}
// CheckAndCleanupOTAContainers Check and cleanup OTA update temporary containers
func CheckAndCleanupOTAContainers() {
// Execute the third step cleanup operation at startup
err := docker.UpgradeStepThree()
if err != nil {
logger.Error("Failed to cleanup OTA containers:", err)
} else {
logger.Info("OTA container cleanup completed successfully")
}
}

View file

@ -5,4 +5,5 @@ import "github.com/uozi-tech/cosy"
var (
e = cosy.NewErrorScope("nginx")
ErrBlockIsNil = e.New(50001, "block is nil")
ErrReloadFailed = e.New(50002, "reload nginx failed: {0}")
)

28
internal/nginx/exec.go Normal file
View file

@ -0,0 +1,28 @@
package nginx
import (
"context"
"os/exec"
"github.com/0xJacky/Nginx-UI/internal/docker"
"github.com/0xJacky/Nginx-UI/settings"
)
func execShell(cmd string) (stdOut string, stdErr error) {
return execCommand("/bin/sh", "-c", cmd)
}
func execCommand(name string, cmd ...string) (stdOut string, stdErr error) {
switch settings.NginxSettings.RunningInAnotherContainer() {
case true:
cmd = append([]string{name}, cmd...)
stdOut, stdErr = docker.Exec(context.Background(), cmd)
case false:
bytes, err := exec.Command(name, cmd...).CombinedOutput()
stdOut = string(bytes)
if err != nil {
stdErr = err
}
}
return
}

View file

@ -2,46 +2,41 @@ package nginx
import (
"os"
"os/exec"
"strings"
"sync"
"time"
"github.com/0xJacky/Nginx-UI/internal/docker"
"github.com/0xJacky/Nginx-UI/settings"
)
var (
mutex sync.Mutex
lastOutput string
lastStdOut string
lastStdErr error
)
func TestConf() (out string) {
// TestConfig tests the nginx config
func TestConfig() (stdOut string, stdErr error) {
mutex.Lock()
defer mutex.Unlock()
if settings.NginxSettings.TestConfigCmd != "" {
out = execShell(settings.NginxSettings.TestConfigCmd)
return
return execShell(settings.NginxSettings.TestConfigCmd)
}
out = execCommand("nginx", "-t")
return
return execCommand("nginx", "-t")
}
func Reload() (out string) {
// Reload reloads the nginx
func Reload() (stdOut string, stdErr error) {
mutex.Lock()
defer mutex.Unlock()
if settings.NginxSettings.ReloadCmd != "" {
out = execShell(settings.NginxSettings.ReloadCmd)
return
return execShell(settings.NginxSettings.ReloadCmd)
}
out = execCommand("nginx", "-s", "reload")
return
return execCommand("nginx", "-s", "reload")
}
// Restart restarts the nginx
func Restart() {
mutex.Lock()
defer mutex.Unlock()
@ -50,41 +45,45 @@ func Restart() {
time.Sleep(500 * time.Millisecond)
if settings.NginxSettings.RestartCmd != "" {
lastOutput = execShell(settings.NginxSettings.RestartCmd)
lastStdOut, lastStdErr = execShell(settings.NginxSettings.RestartCmd)
return
}
pidPath := GetPIDPath()
daemon := GetSbinPath()
lastOutput = execCommand("start-stop-daemon", "--stop", "--quiet", "--oknodo", "--retry=TERM/30/KILL/5", "--pidfile", pidPath)
if daemon == "" {
lastOutput += execCommand("nginx")
lastStdOut, lastStdErr = execCommand("start-stop-daemon", "--stop", "--quiet", "--oknodo", "--retry=TERM/30/KILL/5", "--pidfile", pidPath)
if lastStdErr != nil {
return
}
lastOutput += execCommand("start-stop-daemon", "--start", "--quiet", "--pidfile", pidPath, "--exec", daemon)
if daemon == "" {
lastStdOut, lastStdErr = execCommand("nginx")
return
}
lastStdOut, lastStdErr = execCommand("start-stop-daemon", "--start", "--quiet", "--pidfile", pidPath, "--exec", daemon)
return
}
func GetLastOutput() string {
// GetLastOutput returns the last output of the nginx command
func GetLastOutput() (stdOut string, stdErr error) {
mutex.Lock()
defer mutex.Unlock()
return lastOutput
return lastStdOut, lastStdErr
}
// GetModulesPath returns the nginx modules path
func GetModulesPath() string {
// First try to get from nginx -V output
output := execCommand("nginx", "-V")
if output != "" {
stdOut, stdErr := execCommand("nginx", "-V")
if stdErr != nil {
return ""
}
if stdOut != "" {
// Look for --modules-path in the output
if strings.Contains(output, "--modules-path=") {
parts := strings.Split(output, "--modules-path=")
if strings.Contains(stdOut, "--modules-path=") {
parts := strings.Split(stdOut, "--modules-path=")
if len(parts) > 1 {
// Extract the path
path := strings.Split(parts[1], " ")[0]
@ -99,28 +98,16 @@ func GetModulesPath() string {
return "/usr/lib/nginx/modules"
}
func execShell(cmd string) (out string) {
bytes, err := exec.Command("/bin/sh", "-c", cmd).CombinedOutput()
out = string(bytes)
if err != nil {
out += " " + err.Error()
}
return
}
func execCommand(name string, cmd ...string) (out string) {
bytes, err := exec.Command(name, cmd...).CombinedOutput()
out = string(bytes)
if err != nil {
out += " " + err.Error()
}
return
}
func IsNginxRunning() bool {
pidPath := GetPIDPath()
if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 {
return false
switch settings.NginxSettings.RunningInAnotherContainer() {
case true:
return docker.StatPath(pidPath)
case false:
if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 {
return false
}
return true
}
return true
return false
}

View file

@ -35,7 +35,10 @@ func Disable(name string) (err error) {
return
}
output := nginx.Reload()
output, err := nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

View file

@ -35,13 +35,19 @@ func Enable(name string) (err error) {
}
// Test nginx config, if not pass, then disable the site.
output := nginx.TestConf()
output, err := nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
_ = os.Remove(enabledConfigFilePath)
return cosy.WrapErrorWithParams(ErrNginxTestFailed, output)
}
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

View file

@ -76,7 +76,10 @@ func EnableMaintenance(name string) (err error) {
}
// Test nginx config, if not pass, then restore original configuration
output := nginx.TestConf()
output, err := nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
// Configuration error, cleanup and revert
_ = os.Remove(maintenanceConfigPath)
@ -87,7 +90,10 @@ func EnableMaintenance(name string) (err error) {
}
// Reload nginx
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}
@ -132,7 +138,10 @@ func DisableMaintenance(name string) (err error) {
}
// Test nginx config, if not pass, then revert
output := nginx.TestConf()
output, err := nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
// Configuration error, cleanup and revert
_ = os.Remove(enabledConfigFilePath)
@ -141,7 +150,10 @@ func DisableMaintenance(name string) (err error) {
}
// Reload nginx
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return fmt.Errorf("%s", output)
}

View file

@ -2,16 +2,17 @@ package site
import (
"fmt"
"net/http"
"os"
"runtime"
"sync"
"github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/internal/notification"
"github.com/0xJacky/Nginx-UI/query"
"github.com/go-resty/resty/v2"
"github.com/uozi-tech/cosy/logger"
"net/http"
"os"
"runtime"
"sync"
)
func Rename(oldName string, newName string) (err error) {
@ -47,13 +48,19 @@ func Rename(oldName string, newName string) (err error) {
}
// test nginx configuration
output := nginx.TestConf()
output, err := nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return fmt.Errorf("%s", output)
}
// reload nginx
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return fmt.Errorf("%s", output)
}

View file

@ -38,14 +38,21 @@ func Save(name string, content string, overwrite bool, envGroupId uint64, syncNo
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", name)
if helper.FileExists(enabledConfigFilePath) {
// Test nginx configuration
output := nginx.TestConf()
var output string
output, err = nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxTestFailed, output)
}
if postAction == model.PostSyncActionReloadNginx {
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

View file

@ -35,7 +35,10 @@ func Disable(name string) (err error) {
return
}
output := nginx.Reload()
output, err := nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

View file

@ -35,13 +35,19 @@ func Enable(name string) (err error) {
}
// Test nginx config, if not pass, then disable the site.
output := nginx.TestConf()
output, err := nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
_ = os.Remove(enabledConfigFilePath)
return cosy.WrapErrorWithParams(ErrNginxTestFailed, output)
}
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

View file

@ -49,13 +49,19 @@ func Rename(oldName string, newName string) (err error) {
}
// test nginx configuration
output := nginx.TestConf()
output, err := nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxTestFailed, output)
}
// reload nginx
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

View file

@ -37,15 +37,22 @@ func Save(name string, content string, overwrite bool, syncNodeIds []uint64, pos
enabledConfigFilePath := nginx.GetConfPath("streams-enabled", name)
if helper.FileExists(enabledConfigFilePath) {
var output string
// Test nginx configuration
output := nginx.TestConf()
output, err = nginx.TestConfig()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxTestFailed, output)
}
if postAction == model.PostSyncActionReloadNginx {
output = nginx.Reload()
output, err = nginx.Reload()
if err != nil {
return
}
if nginx.GetLogLevel(output) > nginx.Warn {
return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
}

View file

@ -11,6 +11,7 @@ type Nginx struct {
ReloadCmd string `json:"reload_cmd" protected:"true"`
RestartCmd string `json:"restart_cmd" protected:"true"`
StubStatusPort uint `json:"stub_status_port" binding:"omitempty,min=1,max=65535"`
ContainerName string `json:"container_name" protected:"true"`
}
var NginxSettings = &Nginx{}
@ -21,3 +22,7 @@ func (n *Nginx) GetStubStatusPort() uint {
}
return n.StubStatusPort
}
func (n *Nginx) RunningInAnotherContainer() bool {
return n.ContainerName != ""
}