## File: app/src/components/DevDebugPanel/README.md

# DevDebugPanel Component

A development-only debug panel component that provides a floating debug interface for troubleshooting and development purposes.

## Features

- **Development Only**: Automatically disabled in production builds
- **Floating Panel**: Positioned as a fixed overlay with toggle functionality
- **Customizable Content**: Uses slots for flexible debug information display
- **Modern Styling**: Dark theme with backdrop blur and professional appearance

## Usage

```vue
<script setup lang="ts">
import { DevDebugPanel } from '@/components/DevDebugPanel'

const debugData = computed(() => ({
  status: 'active',
  // ... other debug properties
}))
</script>

<template>
  <div>
    <!-- Your main content -->

    <!-- Debug Panel (only renders in development) -->
    <DevDebugPanel :debug-data="debugData">
      <template #default="{ debugData: slotDebugData }">
        <div class="debug-item">
          <span class="debug-label">Status:</span>
          <span class="debug-value">{{ (slotDebugData as any).status }}</span>
        </div>
        <div class="debug-item">
          <span class="debug-label">Quick Actions:</span>
          <div class="mt-2">
            <AButton size="small" @click="someAction">
              Action
            </AButton>
          </div>
        </div>
      </template>
    </DevDebugPanel>
  </div>
</template>
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | `string` | `'Debug Panel'` | Panel title (currently not used in display) |
| `initialVisible` | `boolean` | `false` | Whether the panel starts visible |
| `debugData` | `Record<string, unknown>` | `{}` | Debug data passed to slot |

## Styling Classes

The component provides several CSS classes for styling debug content:

- `.debug-item` - Container for debug information rows
- `.debug-label` - Styling for debug labels
- `.debug-value` - Styling for debug values

## Security

- Component automatically detects and only renders in development environment
- Console warning is displayed if component is used in production
- No debug information is exposed in production builds

## Example Implementations

### Login Page Debug
Shows loading state, 2FA status, and route information with quick action buttons.

### Log List Debug
Displays indexing status, processing information, and table metadata with modal controls.

## Notes

- The component uses a fixed position overlay that appears in the top-right corner
- Toggle button allows showing/hiding the debug panel
- Uses Ant Design components for consistent styling
- Fully supports dark/light theme switching

---

## File: app/README.md

# Vue 3 + TypeScript + Vite

This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue
3 `<script setup>` SFCs, check out
the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.

## Recommended IDE Setup

- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)

## Type Support For `.vue` Imports in TS

Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type
by default. In most cases this is fine if you don't really care about component prop types outside of templates.
However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using
manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:

1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look
   for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default,
   Take Over mode will enable itself if the default TypeScript extension is disabled.
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.

You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).

## Project Setup

```sh
bun install
```

**Note:** The default target of the api proxy is `http://localhost:9000`,
if you need to change this, create the `.env` file in root directory and set your target in it.

```env
VITE_PROXY_TARGET=http://localhost:9001
```

### Compile and Hot-Reload for Development

```sh
bun run dev
```

**Note:** The default port of the dev server is `3002`,
if you need to change this, create the `.env` file in root directory and set your port in it.

```env
VITE_PORT=3456
```

### Code Style Check

```sh
bun run lint
```

### Type Check

```sh
bun run typecheck
```

### Compile and Minify for Production

```sh
bun run build
```

## DNS Record Matching

The site editor matches DNS records against the normalized full `server_name`.
Root (`@`), relative, wildcard, and provider-returned fully qualified record
names are normalized before exact comparison so unrelated records are not
selected automatically.

---

## File: docs/guide/about.md

<script setup>
import { VPTeamMembers } from 'vitepress/theme';

const blogIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" xml:space="preserve"><title>Blog</title></svg>';

const members = [
  {
    avatar: 'https://www.github.com/0xJacky.png',
    name: '0xJacky',
    title: 'Creator',
    links: [
      { icon: 'github', link: 'https://github.com/0xJacky' },
      { icon: { svg: blogIcon }, link: 'https://jackyu.cn' }
    ]
  },
{
    avatar: 'https://www.github.com/Hintay.png',
    name: 'Hintay',
    title: 'Developer',
    links: [
      { icon: 'github', link: 'https://github.com/Hintay' },
      { icon: { svg: blogIcon }, link: 'https://blog.kugeek.com' }
    ]
  },
{
    avatar: 'https://www.github.com/akinoccc.png',
    name: 'Akino',
    title: 'Developer',
    links: [
      { icon: 'github', link: 'https://github.com/akinoccc' },
      { icon: { svg: blogIcon }, link: 'https://akino.icu' }
    ]
  },
  {
    avatar: 'https://avatars.githubusercontent.com/u/126759922?s=200&v=4',
    name: 'Cursor',
    title: 'Developer',
    links: [
      { icon: 'github', link: "https://github.com/cursor/cursor" },
      { icon: { svg: blogIcon }, link: 'https://www.cursor.com/blog' }
    ]
  }
]
</script>

# What is Nginx UI?





Just want to try it out? Skip to the [Quickstart](./getting-started).



Nginx UI is a comprehensive web-based interface designed to simplify the management and configuration of Nginx single-node and cluster nodes.
It offers real-time server statistics, Nginx performance monitoring, AI-powered ChatGPT assistance,
the code editor that supports LLM Code Completion,
one-click deployment, automatic renewal of Let's Encrypt certificates, and user-friendly editing tools for website configurations. Additionally, Nginx UI provides
features such as online access to Nginx logs, automatic testing and reloading of configuration files, a web terminal,
dark mode, and responsive web design. Built with Go and Vue, Nginx UI ensures a seamless and efficient experience for
managing your Nginx server.

## Our Team

<VPTeamMembers size="small" :members="members" />

## Features

- Online statistics for server indicators such as CPU usage, memory usage, load average, and disk usage.
- Configurations are automatically backed up after modifications, allowing you to compare any versions or restore to any previous version.
- Support for mirroring operations to multiple cluster nodes, easily manage multi-server environments.
- Export encrypted Nginx / Nginx UI configurations for quick deployment and recovery to new environments.
- Enhanced Online ChatGPT Assistant with support for multiple models, including displaying Deepseek-R1's chain of thought to help you better understand and optimize configurations.
- One-click deployment and automatic renewal Let's Encrypt certificates.
- Online editing websites configurations with our self-designed **NgxConfigEditor** which is a user-friendly block
  editor for nginx configurations, or **Ace Code Editor** which supports **LLM Code Completion** and highlighting nginx configuration syntax.
- Online view Nginx logs.
- Written in Go and Vue, distribution is a single executable binary.
- Automatically test configuration file and reload nginx after saving configuration.
- Web Terminal.
- Dark Mode.
- Responsive Web Design.

## Available Platforms

Nginx UI is available on the following platforms:

- macOS 11 Big Sur and later (amd64 / arm64)
- Linux 2.6.23 and later (x86 / amd64 / arm64 / armv5 / armv6 / armv7)
    - Including but not limited to Debian 7 / 8, Ubuntu 12.04 / 14.04 and later, CentOS 6 / 7, Arch Linux
- FreeBSD
- OpenBSD
- Dragonfly BSD
- Openwrt

## Internationalization

We proudly offer official support for:

- English
- Simplified Chinese
- Traditional Chinese

As non-native English speakers, we strive for accuracy, but we know there's always room for improvement. If you spot any issues, we'd love your feedback!

Thanks to our amazing community, additional languages are also available! Explore and contribute to translations on [Weblate](https://weblate.nginxui.com).

---

## File: docs/guide/build.md

# Build

The build guide is intended for developers or advanced users only.
Regular users should follow the [quick start](./getting-started) guide.

## Prerequisites

- Make.
- Go version 1.27.2 or higher, as required by `go.mod`.
- Bun version 1.4.3, as pinned in `package.json`.
- Node.js version 21 or higher for the `npx browserslist` command below.

You should execute the following command to update browser list database before build project.
  ```shell
  npx browserslist@latest --update-db
  ```

## Build Frontend

Please execute the following command in `app` directory.

```shell
bun install
bun run build
```

## Build Backend

::: warning
Before building the backend, the app should be built first because the backend will embed the app distribution.
:::

Please execute the following command in the project root directory.

```shell
go generate
go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go
```

---

## File: docs/guide/config-app.md

# App

## PageSize

- Type: `int`
- Default: 10
- Version: `>=v2.0.0-beta.37`

This option is used to set the page size of list pagination in the Nginx UI. Adjusting the page size can help in
managing large amounts of data more effectively, but a too large number can increase the load on the server.

## JwtSecret
- Type: `string`
- Version: `>=v2.0.0-beta.37`

This option is used to configure the key used by the Nginx UI server to generate JWT.

JWT is a standard for verifying user identity. It can generate a token after the user logs in, and then use the token to verify the user's identity in subsequent requests.

If you use the one-click installation script to deploy Nginx UI, the script will generate a UUID value and set it as the value of this option.

---

## File: docs/guide/config-auth.md

# Auth
From v2.0.0-beta.26, you can authorization settings in the `auth` section of the configuration file.

## IPWhiteList
- Type: `string`
- Example: `10.0.0.1`

```ini
[auth]
IPWhiteList = 10.0.0.1
IPWhiteList = 10.0.0.2
IPWhiteList = 2001:0000:130F:0000:0000:09C0:876A:130B
```

By default, if you do not set the `IPWhiteList`, all IP addresses are allowed to access the Nginx UI.

Once you set the `IPWhiteList`, only the users from IP addresses in the list and `127.0.0.1` can access the Nginx UI,
others will receive a `403 Forbidden` error.

## TrustedProxies
- Type: `string`
- Example: `127.0.0.1`

```ini
[auth]
TrustedProxies = 127.0.0.1
TrustedProxies = ::1
TrustedProxies = 10.0.0.0/8
```

`TrustedProxies` controls which direct proxy IP addresses or CIDRs may supply
`X-Forwarded-For` and `X-Real-IP`. Leave it empty when Nginx UI is not behind a
reverse proxy. The official Docker image automatically trusts only its bundled
loopback Nginx proxy. Custom reverse proxies must be listed explicitly, and the
application must be restarted after changing this setting. Never use
`0.0.0.0/0` or `::/0`.

## BanThresholdMinutes
- Type: `int`
- Default: `10`

By default, if a user fails to log in 10 times within 10 minutes, the user will be banned for 10 minutes.

## MaxAttempts
- Type: `int`
- Default: `10`

By default, a user can try to log in 10 times within 10 minutes.

## SecureSessionTimeoutMinutes
- Type: `int`
- Default: `10`

Controls how many minutes a successful TOTP or passkey verification authorizes
protected operations. The setting does not change the normal login session
lifetime. Values must be positive; missing, zero, and negative values use the
10-minute default.

## MFARequired
- Type: `bool`
- Default: `false`

Requires TOTP or a usable passkey for every account at its next sign-in.
Existing sessions remain active. Individual account requirements remain in
effect when this global setting is disabled.

## MFARequiredForSSO
- Type: `bool`
- Default: `false`

When enabled, OIDC and Casdoor sign-ins also require local MFA verification
for enrolled accounts and enrollment for accounts with an effective MFA
requirement. See [MFA policy and recovery](./mfa).

---

## File: docs/guide/config-backup.md

# Backup Configuration

The backup section of the Nginx UI configuration controls the security and access permissions for backup operations. This section ensures that backup functionality operates within defined security boundaries while providing flexible storage options.

## Overview

Nginx UI provides comprehensive backup functionality that includes:

- **Manual Backup**: On-demand backup creation through the web interface
- **Automatic Backup**: Scheduled backup tasks with visual cron editor
- **Multiple Backup Types**: Support for Nginx configuration, Nginx UI configuration, or custom directory backups
- **Storage Options**: Local storage and S3-compatible object storage
- **Security**: Encrypted backups with AES encryption for configuration data

## GrantedAccessPath

- Type: `[]string`
- Default: `[]` (empty array)
- Version: `>= v2.0.0`

This is the most critical security setting for backup operations. It defines a list of directory paths that are allowed for backup operations, including both backup source paths and storage destination paths.

### Purpose

The `GrantedAccessPath` setting serves as a security boundary that:

- **Prevents Unauthorized Access**: Restricts backup operations to explicitly authorized directories
- **Protects System Files**: Prevents accidental backup or access to sensitive system directories
- **Enforces Access Control**: Ensures all backup paths are within administrator-defined boundaries
- **Prevents Path Traversal**: Blocks attempts to access directories outside the allowed scope

### Configuration Format

```ini
[backup]
GrantedAccessPath = /var/backups
GrantedAccessPath = /home/user/backups
```

### Path Validation Rules

1. **Prefix Matching**: Paths are validated using prefix matching with proper boundary checking
2. **Path Cleaning**: All paths are normalized to prevent directory traversal attacks (e.g., `../` sequences)
3. **Exact Boundaries**: `/tmp` allows `/tmp/backup` but not `/tmpfoo` to prevent confusion
4. **Empty Default**: By default, no custom directory backup operations are allowed for maximum security

### Security Considerations

- **Default Security**: The default empty configuration ensures no custom directory backup operations are allowed until explicitly configured
- **Explicit Configuration**: Administrators must consciously define allowed paths
- **Regular Review**: Periodically review and update allowed paths based on operational needs
- **Minimal Permissions**: Only grant access to directories that genuinely need backup functionality

## Backup Types

### Configuration Backups

When backing up Nginx or Nginx UI configurations:

- **Encryption**: All configuration backups are automatically encrypted using AES encryption
- **Key Management**: Encryption keys are generated automatically and saved alongside backup files
- **Integrity Verification**: SHA-256 hashes ensure backup integrity
- **Metadata**: Version information and timestamps are included for restoration context

### Login Sessions

New backups omit active login sessions from the application database. Accounts,
passwords, MFA configuration, and other persistent application data remain in the
backup. Sign in again after restoring a newly generated backup. Creating a backup
does not sign out current users or change the live database.

This also applies when a custom directory backup includes the live application
database. Previously created archives are not rewritten, and existing archives
inside a selected directory remain included under the normal backup rules.

### Restore Trust

Restoring a backup is a privileged full-recovery operation. Administrators may
restore a complete snapshot they trust, including Nginx configuration and modules.
Restored configuration can execute with the permissions of the Nginx process;
the individual configuration editor's restricted-directive policy is not a
sandbox for complete backup recovery.

Restore only archives from sources you trust. A portable archive's integrity
check does not establish a trusted origin or prove that its content is safe.
Authentication, applicable MFA verification, archive path and symlink checks,
and protected-setting rules continue to apply.

### Custom Directory Backups

For custom directory backups:

- **No Encryption**: Custom directory backups are stored as standard ZIP files without encryption
- **Path Validation**: Source directories must be within `GrantedAccessPath` boundaries
- **Flexible Content**: Can backup any directory structure within allowed paths
- **Output Exclusion**: If the destination is inside the source directory, the
  archive being created is excluded from its own contents. Existing backup files
  remain included; choose a separate storage directory to avoid archiving them.

## Storage Configuration

### Local Storage

- **Path Validation**: Storage paths must be within `GrantedAccessPath` boundaries
- **Directory Creation**: Storage directories are created automatically if they don't exist
- **Permissions**: Backup files are created with secure permissions (0600)

### S3 Storage

For S3-compatible object storage:

- **Required Fields**: Bucket name, access key ID, and secret access key are mandatory
- **Optional Fields**: Endpoint URL and region can be configured for custom S3 providers

## Automatic Backup Scheduling

### Visual Cron Editor

Automatic backups use a visual cron editor interface that allows you to:

- **Select Frequency**: Choose from daily, weekly, monthly, or custom schedules
- **Set Time**: Pick specific hours and minutes for backup execution
- **Preview Schedule**: View human-readable descriptions of the backup schedule

### Task Management

- **Status Tracking**: Each backup task tracks execution status (pending, success, failed)
- **Error Logging**: Failed backups include detailed error messages for troubleshooting

### Backup Retention

By default, every run of an automatic backup task adds a new backup file and old files are never deleted. Set **Backups to Keep** on a task to limit how many backups it retains:

- **Default**: `0` keeps all backups
- **Limit**: A positive number keeps only that many of the newest backups after each successful run and deletes the older ones. A backup that has an encryption key file is deleted together with its `.key` file
- **Storage**: Works for both local and S3 storage
- **Scope**: Only files that follow the task's naming scheme (`<name>_<timestamp>.zip`, or `custom_dir_<name>_<timestamp>.zip` for custom directory backups) directly inside the storage path are considered. Other files are left alone. Characters that are not allowed in file names are replaced with `_` in `<name>`
- **Shared names**: If another task writes backups with the same file names to the same storage path (for example `web prod` and `web/prod`, or a custom directory task `web` and a task named `custom_dir_web`), their backups cannot be told apart. The task then skips the cleanup and sends a warning notification until one of the tasks is renamed or moved to its own storage path
- **Renamed tasks**: Backups written before a task was renamed or moved to another storage path no longer match it and are not deleted. Remove them by hand if they are no longer needed
- **Versioned S3 buckets**: In a bucket with versioning enabled, deleting an old backup only adds a delete marker, so the storage is freed by the bucket's lifecycle rules rather than by the cleanup
- **Failures**: If an old backup cannot be deleted, a warning is logged and the backup task itself still succeeds

Review backup source and destination permissions as part of your administrator access policy.

---

## File: docs/guide/config-casdoor.md

# Casdoor
This section describes how to configure Casdoor as an authentication provider for Nginx UI, contributed by @Jraaay.

Casdoor is a powerful and comprehensive identity authentication solution that supports OAuth 2.0, SAML 2.0, LDAP, AD, and multiple social login methods.
By integrating Casdoor, Nginx UI can leverage these features to improve security and user experience.

## Endpoint
- Type: `string`

This is the Endpoint of the Casdoor server. You need to make sure that Nginx UI can access this URL.

## ExternalUrl
- Type: `string`
- Version: `>= v2.0.0-beta.42`

This is the external URL of the Casdoor server. It is used to generate the redirect URI.
If this option is not configured, the Endpoint will be used as the base URL for the redirect URI.

## ClientId
- Type: `string`

This is the Client ID generated by Casdoor for your application.
It is used to identify your application during the authentication process.

## ClientSecret
- Type: `string`

This is the Client Secret generated by Casdoor for your application.
It is necessary to keep your application secure.

## CertificatePath
- Type: `string`

This is the path of the certificate used during the authentication process.
Make sure it is valid and trusted.

## Organization
- Type: `string`

This is the organization name you set in Casdoor.
It will use this information to process authentication requests.

## Application
- Type: `string`

This is the application name you created in Casdoor.

## RedirectUri
- Type: `string`

This is the URI that users will be redirected to after successful login or authorization.
It should be consistent with the Redirect URI in the Casdoor application configuration.

---

## File: docs/guide/config-cert.md

# Cert

## CADir
- Type: `string`
- Version：`>= v2.0.0-beta.37`

When applying for a Let's Encrypt certificate, we use the default CA address of Let's Encrypt. If you need to debug or
obtain certificates from other providers, you can set CADir to their address.

::: tip
Please note that the address provided by
CADir needs to comply with the `RFC 8555` standard.
:::

## RecursiveNameservers

- Version：`>= v2.0.0-beta.37`
- Type: `[]string`
- Example: `8.8.8.8:53,1.1.1.1:53`

This option is used to set the recursive nameservers used by
Nginx UI in the DNS challenge step of applying for a certificate.
If this option is not configured, Nginx UI will use the nameservers settings of the operating system.


## CertRenewalInterval

- Version：`>= v2.0.0-beta.37`
- Type: `int`
- Default value: `30`
- Valid range: `1-90`

This option sets the certificate's remaining-validity threshold for automatic renewal. Nginx UI attempts renewal when
the remaining validity is less than or equal to the configured number of days. The certificate worker checks every
30 minutes, but a check does not issue a new certificate before the threshold is reached.

The `RenewalInterval` name is retained for configuration compatibility. Existing configured values are preserved and
are interpreted as days of remaining validity after upgrading.

For short-lived ACME certificates, Nginx UI uses the server-provided ACME Renewal Information (ARI) schedule when
available. If ARI is unavailable, or if the configured threshold is not shorter than the certificate lifetime, Nginx UI
uses the midpoint of the certificate lifetime to avoid an immediate renewal loop.

## HTTPChallengePort

- Version：`>= v2.0.0-beta.37`
- Type: `int`
- Default: `9180`

This option is used to set the port for backend listening in the HTTP01 challenge mode when obtaining Let's Encrypt
certificates. The HTTP01 challenge is a domain validation method used by Let's Encrypt to verify that you control the
domain for which you're requesting a certificate.

## Certificate Discovery

When importing deployed certificates, automatic discovery scans the configured Nginx `ssl` directory for directories
that contain separate certificate and private key files, such as `fullchain.pem` and `privkey.pem`.

Combined certificate and private key single-PEM files are not auto-detected. Split them into separate certificate and
key files before using discovery.

## DNS Domain Management

- Version：`>= v2.2.2`
- Supported providers: Alibaba Cloud DNS, Azure DNS, Cloudflare, Huawei Cloud DNS, Tencent Cloud DNS

You can now register DNS domains inside Nginx-UI (Certificates → DNS Domains) and bind them to an existing DNS Credential.
For every registered domain the UI exposes a full DNS record management experience (list, create, update, delete) that talks directly to the provider's API.
This allows you to verify domains for certificate issuance and perform day-to-day DNS maintenance without leaving the dashboard.

> Make sure the selected DNS Credential contains the API tokens and permissions required by the provider to edit DNS records.

---

## File: docs/guide/config-cluster.md

# Cluster
From v2.0.0-beta.23, you can define multiple environments in the `cluster` section of the configuration file.

## Node
- Type: `string`
- Structure：`Scheme://Host(:Port)?name=ENV_NAME&node_secret=NODE_SECRET&enabled=(true/false)`
- Example: `http://10.0.0.1:9000?name=node1&node_secret=my-node-secret&enabled=true`

If you have multiple environments to configure, please refer to the following configuration:
```ini
[cluster]
Node = http://10.0.0.1:9000?name=node1&node_secret=my-node-secret&enabled=true
Node = http://10.0.0.2:9000?name=node2&node_secret=my-node-secret&enabled=false
Node = http://10.0.0.3?name=node3&node_secret=my-node-secret&enabled=true
```

By default, Nginx UI will create the predefined environments during the bootstrapping stage.
You can also find the "Load from Config" button in the environment list in the WebUI to manually update the environments.

In order to avoid conflicts with the environemnts that already exist in the database,
Nginx UI will check if the `Scheme://Host(:Port)` part is unique.
If it does not exist, it will be created according to the configuration, otherwise no action will be taken.

Please note that if you delete a node from the configuration file, Nginx UI will not delete the record from the database.

---

## File: docs/guide/config-crypto.md

# Crypto

## Secret
- Type: `string`

If this value is empty, Nginx UI will generate a random secret key automatically.
This secret is used to encrypt the sensitive data stored in the database.