📝 docs: Add documentation

This commit is contained in:
web@ppanel
2025-12-11 03:29:07 +00:00
parent 50e695a1bb
commit 99e7f6062d
135 changed files with 79115 additions and 8 deletions
+387
View File
@@ -0,0 +1,387 @@
# Contributors
Thank you to all the developers who have contributed to the PPanel project!
## Project Contributors
PPanel is an open-source project, and we welcome and appreciate all forms of contributions, including but not limited to:
- 💻 Code contributions
- 📝 Documentation improvements
- 🐛 Bug reports
- 💡 Feature suggestions
- 🌍 Translation work
- ⭐ Stars and promotion
## Core Contributors
<script setup>
import { ref, onMounted } from 'vue'
const backendContributors = ref([])
const frontendContributors = ref([])
const backendLoading = ref(true)
const frontendLoading = ref(true)
onMounted(async () => {
// Fetch contributors from backend related repositories
try {
const repos = ['server', 'ppanel', 'ppanel-node']
const contributorsMap = new Map()
for (const repo of repos) {
const response = await fetch(`https://api.github.com/repos/perfect-panel/${repo}/contributors`)
if (response.ok) {
const contributors = await response.json()
contributors.forEach(contributor => {
if (!contributorsMap.has(contributor.login)) {
contributorsMap.set(contributor.login, {
login: contributor.login,
avatar_url: contributor.avatar_url,
html_url: contributor.html_url,
contributions: contributor.contributions
})
} else {
const existing = contributorsMap.get(contributor.login)
existing.contributions += contributor.contributions
}
})
}
}
backendContributors.value = Array.from(contributorsMap.values())
.sort((a, b) => b.contributions - a.contributions)
} catch (error) {
console.error('Failed to fetch backend contributors:', error)
} finally {
backendLoading.value = false
}
// Fetch contributors from frontend related repositories
try {
const repos = ['frontend', 'ppanel-web', 'ppanel-docs']
const contributorsMap = new Map()
for (const repo of repos) {
const response = await fetch(`https://api.github.com/repos/perfect-panel/${repo}/contributors`)
if (response.ok) {
const contributors = await response.json()
contributors.forEach(contributor => {
if (!contributorsMap.has(contributor.login)) {
contributorsMap.set(contributor.login, {
login: contributor.login,
avatar_url: contributor.avatar_url,
html_url: contributor.html_url,
contributions: contributor.contributions
})
} else {
const existing = contributorsMap.get(contributor.login)
existing.contributions += contributor.contributions
}
})
}
}
frontendContributors.value = Array.from(contributorsMap.values())
.sort((a, b) => b.contributions - a.contributions)
} catch (error) {
console.error('Failed to fetch frontend contributors:', error)
} finally {
frontendLoading.value = false
}
})
</script>
### Backend Repository Contributors
<div v-if="backendLoading" class="contributors-loading">
<div class="loading-spinner"></div>
<p>Loading contributors...</p>
</div>
<div v-else-if="backendContributors.length === 0" class="contributors-empty">
<p>No contributors data available</p>
</div>
<div v-else>
<div class="contributors-grid">
<a
v-for="contributor in backendContributors"
:key="contributor.login"
:href="contributor.html_url"
target="_blank"
rel="noopener noreferrer"
class="contributor-card"
>
<img
:src="contributor.avatar_url"
:alt="contributor.login"
class="contributor-avatar"
loading="lazy"
/>
<div class="contributor-info">
<div class="contributor-name" :title="contributor.login">{{ contributor.login }}</div>
<div class="contributor-contributions">
<svg class="contribution-icon" viewBox="0 0 16 16" width="12" height="12" fill="currentColor">
<path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
</svg>
{{ contributor.contributions }} contributions
</div>
</div>
</a>
</div>
</div>
### Frontend Repository Contributors
<div v-if="frontendLoading" class="contributors-loading">
<div class="loading-spinner"></div>
<p>Loading contributors...</p>
</div>
<div v-else-if="frontendContributors.length === 0" class="contributors-empty">
<p>No contributors data available</p>
</div>
<div v-else>
<div class="contributors-grid">
<a
v-for="contributor in frontendContributors"
:key="contributor.login"
:href="contributor.html_url"
target="_blank"
rel="noopener noreferrer"
class="contributor-card"
>
<img
:src="contributor.avatar_url"
:alt="contributor.login"
class="contributor-avatar"
loading="lazy"
/>
<div class="contributor-info">
<div class="contributor-name" :title="contributor.login">{{ contributor.login }}</div>
<div class="contributor-contributions">
<svg class="contribution-icon" viewBox="0 0 16 16" width="12" height="12" fill="currentColor">
<path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
</svg>
{{ contributor.contributions }} contributions
</div>
</div>
</a>
</div>
</div>
<style scoped>
.contributors-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3rem;
color: var(--vp-c-text-2);
}
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid var(--vp-c-divider);
border-top-color: var(--vp-c-brand);
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin-bottom: 1rem;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.contributors-empty {
text-align: center;
padding: 2rem;
color: var(--vp-c-text-3);
font-style: italic;
}
.contributors-stats {
display: flex;
gap: 1rem;
margin-bottom: 1.5rem;
flex-wrap: wrap;
}
.stat-badge {
display: inline-flex;
align-items: center;
padding: 0.5rem 1rem;
background: var(--vp-c-bg-soft);
border: 1px solid var(--vp-c-divider);
border-radius: 20px;
font-size: 13px;
font-weight: 500;
color: var(--vp-c-text-2);
}
.contributors-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 1rem;
margin: 1.5rem 0;
}
.contributor-card {
display: flex;
align-items: center;
padding: 1rem;
background: var(--vp-c-bg-soft);
border: 1px solid var(--vp-c-divider);
border-radius: 12px;
text-decoration: none;
color: var(--vp-c-text-1);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.contributor-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, var(--vp-c-brand), var(--vp-c-brand-light));
transform: scaleX(0);
transition: transform 0.3s ease;
}
.contributor-card:hover {
border-color: var(--vp-c-brand-light);
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.contributor-card:hover::before {
transform: scaleX(1);
}
.contributor-avatar {
width: 56px;
height: 56px;
border-radius: 50%;
margin-right: 1rem;
border: 2px solid var(--vp-c-divider);
transition: all 0.3s ease;
flex-shrink: 0;
}
.contributor-card:hover .contributor-avatar {
border-color: var(--vp-c-brand);
transform: scale(1.05);
}
.contributor-info {
flex: 1;
min-width: 0;
}
.contributor-name {
font-weight: 600;
font-size: 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-bottom: 0.25rem;
color: var(--vp-c-text-1);
}
.contributor-contributions {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 13px;
color: var(--vp-c-text-2);
}
.contribution-icon {
opacity: 0.6;
}
@media (max-width: 768px) {
.contributors-grid {
grid-template-columns: 1fr;
}
.contributors-stats {
flex-direction: column;
}
.stat-badge {
width: 100%;
justify-content: center;
}
}
@media (prefers-color-scheme: dark) {
.contributor-card:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
}
</style>
### Reporting Issues
If you find a bug or have a feature suggestion:
1. Search [GitHub Issues](https://github.com/perfect-panel/frontend/issues) to see if a similar issue exists
2. If not, create a new Issue
3. Provide detailed information:
- Problem description
- Steps to reproduce
- Expected behavior
- Actual behavior
- Environment info (browser, OS, etc.)
- Screenshots or error logs (if applicable)
### Documentation Contributions
Documentation is equally important! You can:
- Fix typos and grammar errors
- Improve clarity of existing documentation
- Add missing documentation
- Translate documentation to other languages
- Add usage examples and tutorials
Documentation source files are located in the `/docs` directory.
### Translation Contributions
We welcome translating PPanel into more languages:
1. Check if there's already a folder for the target language in `/docs`
2. If not, create a new language folder (e.g., `/docs/ja` for Japanese)
3. Copy the English or Chinese version as a base
4. Translate the content
5. Add new language configuration in `.vitepress/config.mts`
6. Submit a Pull Request
## Community
Join our community and connect with other developers:
- **GitHub Discussions**: [Discussion Forum](https://github.com/perfect-panel/frontend/discussions)
- **GitHub Issues**: [Issue Tracker](https://github.com/perfect-panel/frontend/issues)
- **Telegram**: [Join Group](https://t.me/PPanelChat)
## Code of Conduct
We are committed to providing a friendly, safe, and welcoming environment for everyone. Please read and follow our [Code of Conduct](https://github.com/perfect-panel/frontend/blob/main/CODE_OF_CONDUCT.md).
## Acknowledgments
Special thanks to all developers, testers, documentation writers, and community members who have contributed to the PPanel project. You make PPanel better!
## License
By contributing code, you agree that your contributions will be licensed under the project's [GNU License](https://github.com/perfect-panel/frontend/blob/main/LICENSE).
+507
View File
@@ -0,0 +1,507 @@
# Installation
This guide will help you deploy PPanel on your server using Docker.
## System Requirements
### Minimum Requirements
- **Operating System**: Linux (Ubuntu 20.04+, Debian 10+, CentOS 8+)
- **CPU**: 1 core
- **Memory**: 512MB RAM
- **Storage**: 1GB available disk space
- **Docker**: 20.10+
- **Docker Compose**: 2.0+ (optional but recommended)
### Recommended Requirements
- **CPU**: 2+ cores
- **Memory**: 2GB+ RAM
- **Storage**: 5GB+ available disk space
## Prerequisites
### Install Docker
If you haven't installed Docker yet, please follow the official installation guide:
**Ubuntu/Debian:**
```bash
# Update package index
sudo apt-get update
# Install required packages
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up the repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
```
**CentOS/RHEL:**
```bash
# Install yum-utils
sudo yum install -y yum-utils
# Add Docker repository
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Install Docker Engine
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker
```
### Verify Installation
```bash
# Check Docker version
docker --version
# Check Docker Compose version
docker compose version
# Test Docker installation
sudo docker run hello-world
```
## Quick Start
### Method 1: Using Docker Run
#### Step 1: Pull the Image
```bash
# Pull latest version
docker pull ppanel/ppanel:latest
# Or pull a specific version
docker pull ppanel/ppanel:v0.1.2
```
#### Step 2: Prepare Configuration
Create a configuration directory and prepare the configuration file:
```bash
# Create configuration directory
mkdir -p ppanel-config
# Create configuration file
cat > ppanel-config/ppanel.yaml <<EOF
# PPanel Configuration
server:
host: 0.0.0.0
port: 8080
database:
type: sqlite
path: /app/data/ppanel.db
# Add more configuration as needed
EOF
```
::: tip
For detailed configuration options, please refer to the [Configuration Guide](/guide/configuration).
:::
#### Step 3: Run Container
```bash
docker run -d \
--name ppanel \
-p 8080:8080 \
-v $(pwd)/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
--restart unless-stopped \
ppanel/ppanel:latest
```
**Parameter Explanation:**
- `-d`: Run container in detached mode (background)
- `--name ppanel`: Set container name
- `-p 8080:8080`: Map container port 8080 to host port 8080
- `-v $(pwd)/ppanel-config:/app/etc:ro`: Mount configuration directory (read-only)
- `-v ppanel-data:/app/data`: Create a volume for persistent data storage
- `--restart unless-stopped`: Auto-restart container unless manually stopped
#### Step 4: Verify Running Status
```bash
# Check container status
docker ps | grep ppanel
# View logs
docker logs -f ppanel
# Check if service is accessible
curl http://localhost:8080
```
### Method 2: Using Docker Compose (Recommended)
#### Step 1: Create docker-compose.yml
```yaml
version: '3.8'
services:
ppanel:
image: ppanel/ppanel:latest
container_name: ppanel
ports:
- "8080:8080"
volumes:
- ./ppanel-config:/app/etc:ro
- ppanel-data:/app/data
restart: unless-stopped
environment:
- TZ=UTC
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
ppanel-data:
driver: local
```
#### Step 2: Prepare Configuration
```bash
# Create configuration directory
mkdir -p ppanel-config
# Copy or create your configuration file
# See Configuration Guide for details
```
#### Step 3: Start Services
```bash
# Start in detached mode
docker compose up -d
# View logs
docker compose logs -f
# Check status
docker compose ps
```
## Post-Installation
### Access the Application
After successful installation, you can access:
- **User Panel**: `http://your-server-ip:8080`
- **Admin Panel**: `http://your-server-ip:8080/admin`
::: warning Default Credentials
Please change the default admin password immediately after first login for security.
:::
### Configure Reverse Proxy (Optional)
For production deployment, it's recommended to use Nginx or Caddy as a reverse proxy to enable HTTPS.
**Nginx Example:**
```nginx
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
**Caddy Example:**
```
your-domain.com {
reverse_proxy localhost:8080
}
```
## Container Management
### View Logs
```bash
# Docker Run
docker logs -f ppanel
# Docker Compose
docker compose logs -f
```
### Stop Container
```bash
# Docker Run
docker stop ppanel
# Docker Compose
docker compose stop
```
### Restart Container
```bash
# Docker Run
docker restart ppanel
# Docker Compose
docker compose restart
```
### Remove Container
```bash
# Docker Run
docker stop ppanel
docker rm ppanel
# Docker Compose
docker compose down
```
::: warning Data Persistence
Removing containers will not delete volumes. To remove volumes as well, use:
```bash
docker compose down -v
```
:::
## Upgrading
### Backup Configuration
Before upgrading, backup your configuration and data:
```bash
# Backup configuration
tar czf ppanel-config-backup-$(date +%Y%m%d).tar.gz ppanel-config/
# Backup data volume
docker run --rm \
-v ppanel-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/ppanel-data-backup-$(date +%Y%m%d).tar.gz /data
```
### Upgrade Steps
#### Using Docker Run
```bash
# Pull latest image
docker pull ppanel/ppanel:latest
# Stop and remove old container
docker stop ppanel
docker rm ppanel
# Start new container with same configuration
docker run -d \
--name ppanel \
-p 8080:8080 \
-v $(pwd)/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
--restart unless-stopped \
ppanel/ppanel:latest
```
#### Using Docker Compose
```bash
# Pull latest image
docker compose pull
# Recreate containers with new image
docker compose up -d
```
### Verify Upgrade
```bash
# Check container is running
docker ps | grep ppanel
# Check logs for any errors
docker logs ppanel
# Verify application is accessible
curl http://localhost:8080
```
## Troubleshooting
### Container Exits Immediately
**Check architecture compatibility:**
```bash
# Check host architecture
uname -m
# Check image architecture
docker image inspect ppanel/ppanel:latest --format '{{.Architecture}}'
```
**Check logs:**
```bash
docker logs ppanel
```
### Cannot Access Service
1. **Check if container is running:**
```bash
docker ps | grep ppanel
```
2. **Check port mapping:**
```bash
docker port ppanel
```
3. **Check firewall rules:**
```bash
# Ubuntu/Debian
sudo ufw status
sudo ufw allow 8080
# CentOS/RHEL
sudo firewall-cmd --list-ports
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
```
### Configuration Not Taking Effect
1. **Verify mount path:**
```bash
docker exec ppanel ls -la /app/etc
```
2. **Check configuration syntax:**
```bash
docker exec ppanel cat /app/etc/ppanel.yaml
```
3. **Restart container:**
```bash
docker restart ppanel
```
### Performance Issues
1. **Check resource usage:**
```bash
docker stats ppanel
```
2. **Increase container resources** (if using Docker Desktop):
- Open Docker Desktop Settings
- Go to Resources
- Increase CPU and Memory allocation
3. **Check disk space:**
```bash
df -h
docker system df
```
## Advanced Configuration
### Using Environment Variables
You can override configuration via environment variables:
```bash
docker run -d \
--name ppanel \
-p 8080:8080 \
-e SERVER_PORT=8080 \
-e DATABASE_TYPE=sqlite \
-v $(pwd)/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
--restart unless-stopped \
ppanel/ppanel:latest
```
### Running Multiple Instances
To run multiple instances, use different ports and container names:
```bash
# Instance 1
docker run -d \
--name ppanel-1 \
-p 8081:8080 \
-v $(pwd)/ppanel-config-1:/app/etc:ro \
-v ppanel-data-1:/app/data \
ppanel/ppanel:latest
# Instance 2
docker run -d \
--name ppanel-2 \
-p 8082:8080 \
-v $(pwd)/ppanel-config-2:/app/etc:ro \
-v ppanel-data-2:/app/data \
ppanel/ppanel:latest
```
### Custom Network
Create a custom Docker network for better isolation:
```bash
# Create network
docker network create ppanel-net
# Run container on custom network
docker run -d \
--name ppanel \
--network ppanel-net \
-p 8080:8080 \
-v $(pwd)/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
ppanel/ppanel:latest
```
## Next Steps
- [Configuration Guide](/guide/configuration) - Learn about detailed configuration options
- [Admin Dashboard](/admin/dashboard) - Start managing your panel
- [API Reference](/api/reference) - Integrate with PPanel API
## Need Help?
If you encounter any issues:
1. Check the [Troubleshooting](#troubleshooting) section above
2. Search [GitHub Issues](https://github.com/perfect-panel/ppanel/issues)
3. Join our community discussions
4. Create a new issue with detailed logs and system information
+585
View File
@@ -0,0 +1,585 @@
# Binary Deployment
This guide shows you how to deploy PPanel using pre-built binary executables. This method is suitable for users who prefer not to use Docker or need more control over the deployment.
## Prerequisites
- **Operating System**: Linux (Ubuntu 20.04+, Debian 10+, CentOS 8+)
- **Architecture**: amd64 (x86_64) or arm64
- **Permissions**: Root or sudo access
- **Dependencies**: None (binaries are statically compiled)
## Download Binary
### Step 1: Check System Architecture
```bash
# Check your system architecture
uname -m
# Output: x86_64 (amd64) or aarch64 (arm64)
```
### Step 2: Download Latest Release
Visit the [GitHub Releases](https://github.com/perfect-panel/ppanel/releases) page or download directly:
```bash
# Create installation directory
sudo mkdir -p /opt/ppanel
cd /opt/ppanel
# Download for Linux amd64
wget https://github.com/perfect-panel/ppanel/releases/latest/download/ppanel-linux-amd64.tar.gz
# Or for Linux arm64
# wget https://github.com/perfect-panel/ppanel/releases/latest/download/ppanel-linux-arm64.tar.gz
# Extract
tar -xzf ppanel-linux-amd64.tar.gz
# Verify extracted files
ls -la
```
Expected files:
```
/opt/ppanel/
├── ppanel-server # Main server binary
├── gateway # Gateway binary
└── etc/ # Configuration directory
└── ppanel.yaml # Configuration file
```
## Configuration
### Step 1: Prepare Configuration
```bash
# Copy sample configuration
sudo cp etc/ppanel.yaml etc/ppanel.yaml.backup
# Edit configuration
sudo nano etc/ppanel.yaml
```
**Basic Configuration Example:**
```yaml
server:
host: 0.0.0.0
port: 8080
mode: release # debug, release, or test
database:
type: sqlite
path: /opt/ppanel/data/ppanel.db
# For MySQL/PostgreSQL:
# type: mysql
# host: localhost
# port: 3306
# user: ppanel
# password: your_password
# database: ppanel
log:
level: info # debug, info, warn, error
path: /opt/ppanel/logs
gateway:
port: 8080
timeout: 30s
```
### Step 2: Create Required Directories
```bash
# Create data and log directories
sudo mkdir -p /opt/ppanel/data
sudo mkdir -p /opt/ppanel/logs
# Set proper permissions
sudo chmod 755 /opt/ppanel
sudo chmod 700 /opt/ppanel/data
sudo chmod 755 /opt/ppanel/logs
```
## Running the Service
### Method 1: Direct Execution (Testing)
For quick testing:
```bash
# Make binaries executable
sudo chmod +x /opt/ppanel/ppanel-server
sudo chmod +x /opt/ppanel/gateway
# Run server directly
cd /opt/ppanel
sudo ./ppanel-server
# In another terminal, run gateway (if separate)
# sudo ./gateway
```
Press `Ctrl+C` to stop.
### Method 2: Systemd Service (Recommended)
Create a systemd service for production deployment:
#### Step 1: Create Service File
```bash
sudo nano /etc/systemd/system/ppanel.service
```
**Service File Content:**
```ini
[Unit]
Description=PPanel Server
Documentation=https://github.com/perfect-panel/ppanel
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ppanel
ExecStart=/opt/ppanel/ppanel-server
Restart=always
RestartSec=10
# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/ppanel/data /opt/ppanel/logs
# Resource limits
LimitNOFILE=65535
LimitNPROC=4096
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=ppanel
[Install]
WantedBy=multi-user.target
```
#### Step 2: Enable and Start Service
```bash
# Reload systemd
sudo systemctl daemon-reload
# Enable service (start on boot)
sudo systemctl enable ppanel
# Start service
sudo systemctl start ppanel
# Check status
sudo systemctl status ppanel
```
## Service Management
### Check Status
```bash
# Check if service is running
sudo systemctl status ppanel
# View detailed status
sudo systemctl show ppanel
```
### View Logs
```bash
# View systemd logs
sudo journalctl -u ppanel -f
# View last 100 lines
sudo journalctl -u ppanel -n 100
# View application logs
sudo tail -f /opt/ppanel/logs/ppanel.log
```
### Start/Stop/Restart
```bash
# Start service
sudo systemctl start ppanel
# Stop service
sudo systemctl stop ppanel
# Restart service
sudo systemctl restart ppanel
# Reload configuration (if supported)
sudo systemctl reload ppanel
```
### Enable/Disable Auto-start
```bash
# Enable auto-start on boot
sudo systemctl enable ppanel
# Disable auto-start
sudo systemctl disable ppanel
# Check if enabled
sudo systemctl is-enabled ppanel
```
## Post-Installation
### Verify Installation
```bash
# Check if service is listening
sudo netstat -tlnp | grep 8080
# Or use ss
sudo ss -tlnp | grep 8080
# Test HTTP access
curl http://localhost:8080
# Check process
ps aux | grep ppanel
```
### Access the Application
- **User Panel**: `http://your-server-ip:8080`
- **Admin Panel**: `http://your-server-ip:8080/admin`
### Configure Firewall
```bash
# Ubuntu/Debian (UFW)
sudo ufw allow 8080/tcp
sudo ufw status
# CentOS/RHEL (firewalld)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
```
### Setup Reverse Proxy
For production, use Nginx or Caddy as reverse proxy:
**Nginx Configuration** (`/etc/nginx/sites-available/ppanel`):
```nginx
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
```
Enable the configuration:
```bash
sudo ln -s /etc/nginx/sites-available/ppanel /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```
## Upgrading
### Backup Before Upgrade
```bash
# Stop service
sudo systemctl stop ppanel
# Backup current version
sudo cp -r /opt/ppanel /opt/ppanel-backup-$(date +%Y%m%d)
# Backup database
sudo cp /opt/ppanel/data/ppanel.db /opt/ppanel/data/ppanel.db.backup-$(date +%Y%m%d)
# Backup configuration
sudo cp /opt/ppanel/etc/ppanel.yaml /opt/ppanel/etc/ppanel.yaml.backup-$(date +%Y%m%d)
```
### Download and Install New Version
```bash
# Download new version
cd /tmp
wget https://github.com/perfect-panel/ppanel/releases/latest/download/ppanel-linux-amd64.tar.gz
# Extract to temporary location
mkdir ppanel-new
tar -xzf ppanel-linux-amd64.tar.gz -C ppanel-new
# Backup old binaries
sudo mv /opt/ppanel/ppanel-server /opt/ppanel/ppanel-server.old
sudo mv /opt/ppanel/gateway /opt/ppanel/gateway.old
# Install new binaries
sudo cp ppanel-new/ppanel-server /opt/ppanel/
sudo cp ppanel-new/gateway /opt/ppanel/
# Set permissions
sudo chmod +x /opt/ppanel/ppanel-server
sudo chmod +x /opt/ppanel/gateway
# Start service
sudo systemctl start ppanel
# Check status
sudo systemctl status ppanel
```
### Rollback
If upgrade fails:
```bash
# Stop service
sudo systemctl stop ppanel
# Restore old binaries
sudo mv /opt/ppanel/ppanel-server.old /opt/ppanel/ppanel-server
sudo mv /opt/ppanel/gateway.old /opt/ppanel/gateway
# Restore database (if needed)
sudo cp /opt/ppanel/data/ppanel.db.backup-YYYYMMDD /opt/ppanel/data/ppanel.db
# Start service
sudo systemctl start ppanel
```
## Troubleshooting
### Service Fails to Start
```bash
# Check detailed logs
sudo journalctl -u ppanel -xe
# Check configuration syntax
/opt/ppanel/ppanel-server --check-config
# Verify permissions
ls -la /opt/ppanel
sudo chown -R root:root /opt/ppanel
```
### Port Already in Use
```bash
# Find what's using the port
sudo lsof -i :8080
sudo netstat -tlnp | grep 8080
# Change port in configuration
sudo nano /opt/ppanel/etc/ppanel.yaml
# Update server.port value
# Restart service
sudo systemctl restart ppanel
```
### Binary Won't Execute
```bash
# Check architecture compatibility
uname -m
file /opt/ppanel/ppanel-server
# Check if executable
ls -la /opt/ppanel/ppanel-server
sudo chmod +x /opt/ppanel/ppanel-server
# Check for missing libraries (should be none for static binary)
ldd /opt/ppanel/ppanel-server
```
### High Memory Usage
```bash
# Check memory usage
ps aux | grep ppanel
top -p $(pgrep ppanel-server)
# Add memory limit to systemd service
sudo nano /etc/systemd/system/ppanel.service
# Add under [Service]:
# MemoryMax=2G
# MemoryHigh=1.5G
sudo systemctl daemon-reload
sudo systemctl restart ppanel
```
### Database Connection Issues
```bash
# Check database file permissions
ls -la /opt/ppanel/data/
# For SQLite, verify path in config
sudo nano /opt/ppanel/etc/ppanel.yaml
# Test database connection
sqlite3 /opt/ppanel/data/ppanel.db "SELECT 1;"
# Check logs for database errors
sudo journalctl -u ppanel | grep -i database
```
## Uninstallation
To completely remove PPanel:
```bash
# Stop and disable service
sudo systemctl stop ppanel
sudo systemctl disable ppanel
# Remove service file
sudo rm /etc/systemd/system/ppanel.service
sudo systemctl daemon-reload
# Remove installation directory
sudo rm -rf /opt/ppanel
# Remove firewall rules (if added)
sudo ufw delete allow 8080/tcp
# or
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
```
## Advanced Configuration
### Running as Non-Root User
For better security, run as dedicated user:
```bash
# Create dedicated user
sudo useradd -r -s /bin/false ppanel
# Change ownership
sudo chown -R ppanel:ppanel /opt/ppanel
# Update systemd service
sudo nano /etc/systemd/system/ppanel.service
# Change: User=ppanel
# If binding to port < 1024, grant capability
sudo setcap 'cap_net_bind_service=+ep' /opt/ppanel/ppanel-server
sudo systemctl daemon-reload
sudo systemctl restart ppanel
```
### Multiple Instances
To run multiple instances:
```bash
# Create separate directories
sudo mkdir -p /opt/ppanel-1
sudo mkdir -p /opt/ppanel-2
# Copy binaries and configs
sudo cp -r /opt/ppanel/* /opt/ppanel-1/
sudo cp -r /opt/ppanel/* /opt/ppanel-2/
# Edit configs with different ports
sudo nano /opt/ppanel-1/etc/ppanel.yaml # port: 8081
sudo nano /opt/ppanel-2/etc/ppanel.yaml # port: 8082
# Create separate systemd services
sudo cp /etc/systemd/system/ppanel.service /etc/systemd/system/ppanel-1.service
sudo cp /etc/systemd/system/ppanel.service /etc/systemd/system/ppanel-2.service
# Edit service files accordingly
sudo systemctl daemon-reload
sudo systemctl enable ppanel-1 ppanel-2
sudo systemctl start ppanel-1 ppanel-2
```
### Custom Environment Variables
Add environment variables to systemd service:
```ini
[Service]
Environment="PPANEL_ENV=production"
Environment="PPANEL_DEBUG=false"
EnvironmentFile=/opt/ppanel/env.conf
```
## Performance Tuning
### Optimize File Limits
```bash
# Edit limits
sudo nano /etc/security/limits.conf
# Add:
* soft nofile 65535
* hard nofile 65535
# For systemd service, already set in service file:
# LimitNOFILE=65535
```
### Enable Database Optimization
For SQLite:
```bash
# Add to ppanel.yaml
database:
type: sqlite
path: /opt/ppanel/data/ppanel.db
options:
cache_size: -2000
journal_mode: WAL
synchronous: NORMAL
```
## Next Steps
- [Configuration Guide](/guide/configuration) - Detailed configuration options
- [Admin Dashboard](/admin/dashboard) - Start managing your panel
- [API Reference](/api/reference) - API integration
## Need Help?
- Check [GitHub Issues](https://github.com/perfect-panel/ppanel/issues)
- Review systemd logs: `sudo journalctl -u ppanel -f`
- Check application logs: `tail -f /opt/ppanel/logs/ppanel.log`
+443
View File
@@ -0,0 +1,443 @@
# Docker Compose Deployment
Docker Compose is the recommended deployment method for production environments. It provides better service management, easier configuration, and simplified upgrades.
## Prerequisites
### Install Docker
If you haven't installed Docker yet, please follow the official installation guide:
**Ubuntu/Debian:**
```bash
# Update package index
sudo apt-get update
# Install required packages
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up the repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
```
**CentOS/RHEL:**
```bash
# Install yum-utils
sudo yum install -y yum-utils
# Add Docker repository
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Install Docker Engine
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker
```
### Verify Installation
```bash
# Check Docker version
docker --version
# Check Docker Compose version
docker compose version
# Test Docker installation
sudo docker run hello-world
```
## Deployment Steps
### Step 1: Create Project Directory
```bash
# Create project directory
mkdir -p ~/ppanel
cd ~/ppanel
```
### Step 2: Create docker-compose.yml
Create a `docker-compose.yml` file with the following content:
```yaml
version: '3.8'
services:
ppanel:
image: ppanel/ppanel:latest
container_name: ppanel
ports:
- "8080:8080"
volumes:
- ./ppanel-config:/app/etc:ro
- ppanel-data:/app/data
restart: unless-stopped
environment:
- TZ=UTC
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
ppanel-data:
driver: local
```
**Configuration Explanation:**
- **image**: Docker image to use (latest or specific version like `v0.1.2`)
- **ports**: Map container port 8080 to host port 8080
- **volumes**:
- `./ppanel-config:/app/etc:ro` - Configuration directory (read-only)
- `ppanel-data:/app/data` - Persistent data storage
- **restart**: Auto-restart policy
- **environment**: Set timezone (change to your timezone like `Asia/Shanghai`)
- **healthcheck**: Monitor service health
### Step 3: Prepare Configuration
```bash
# Create configuration directory
mkdir -p ppanel-config
# Create configuration file
cat > ppanel-config/ppanel.yaml <<EOF
# PPanel Configuration
server:
host: 0.0.0.0
port: 8080
database:
type: sqlite
path: /app/data/ppanel.db
# Add more configuration as needed
EOF
```
::: tip
For detailed configuration options, please refer to the [Configuration Guide](/guide/configuration).
:::
### Step 4: Start Services
```bash
# Pull the latest image
docker compose pull
# Start in detached mode
docker compose up -d
# View logs
docker compose logs -f
```
### Step 5: Verify Deployment
```bash
# Check service status
docker compose ps
# Check if service is accessible
curl http://localhost:8080
# View real-time logs
docker compose logs -f ppanel
```
## Post-Installation
### Access the Application
After successful installation, you can access:
- **User Panel**: `http://your-server-ip:8080`
- **Admin Panel**: `http://your-server-ip:8080/admin`
::: warning Default Credentials
Please change the default admin password immediately after first login for security.
:::
### Configure Reverse Proxy (Recommended)
For production deployment, it's recommended to use Nginx or Caddy as a reverse proxy to enable HTTPS.
**Nginx Configuration:**
```nginx
server {
listen 80;
server_name your-domain.com;
# Redirect to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
```
**Caddy Configuration:**
```
your-domain.com {
reverse_proxy localhost:8080
}
```
::: tip
Caddy automatically handles SSL certificates via Let's Encrypt.
:::
## Service Management
### View Logs
```bash
# View all logs
docker compose logs
# Follow logs in real-time
docker compose logs -f
# View specific service logs
docker compose logs ppanel
```
### Stop Services
```bash
# Stop all services
docker compose stop
# Stop specific service
docker compose stop ppanel
```
### Restart Services
```bash
# Restart all services
docker compose restart
# Restart specific service
docker compose restart ppanel
```
### Stop and Remove Services
```bash
# Stop and remove containers
docker compose down
# Stop and remove containers and volumes
docker compose down -v
```
::: warning Data Persistence
Using `docker compose down -v` will delete all data volumes. Only use this if you want to completely remove all data.
:::
## Upgrading
### Backup Before Upgrade
```bash
# Backup configuration
tar czf ppanel-config-backup-$(date +%Y%m%d).tar.gz ppanel-config/
# Backup data volume
docker run --rm \
-v ppanel_ppanel-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/ppanel-data-backup-$(date +%Y%m%d).tar.gz /data
```
### Upgrade Steps
```bash
# Pull latest image
docker compose pull
# Recreate containers with new image
docker compose up -d
# View logs to verify
docker compose logs -f
```
### Rollback
If you encounter issues after upgrading:
```bash
# Edit docker-compose.yml and change image to previous version
# image: ppanel/ppanel:v0.1.1
# Restart with previous version
docker compose up -d
```
## Advanced Configuration
### Custom Port
To use a different port, edit `docker-compose.yml`:
```yaml
ports:
- "3000:8080" # Host port 3000 -> Container port 8080
```
### Multiple Instances
To run multiple instances, create separate directories:
```bash
# Instance 1
mkdir ~/ppanel-1
cd ~/ppanel-1
# Create docker-compose.yml with port 8081
# Instance 2
mkdir ~/ppanel-2
cd ~/ppanel-2
# Create docker-compose.yml with port 8082
```
### Resource Limits
Add resource limits to prevent overconsumption:
```yaml
services:
ppanel:
# ... other config ...
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
```
### Custom Network
Create a custom network for better isolation:
```yaml
version: '3.8'
services:
ppanel:
# ... other config ...
networks:
- ppanel-net
networks:
ppanel-net:
driver: bridge
```
## Troubleshooting
### Container Fails to Start
```bash
# Check logs for errors
docker compose logs ppanel
# Check container status
docker compose ps
# Verify configuration
docker compose config
```
### Port Already in Use
```bash
# Check what's using the port
sudo lsof -i :8080
# Change port in docker-compose.yml
# ports:
# - "8081:8080"
```
### Permission Issues
```bash
# Fix configuration directory permissions
sudo chown -R $USER:$USER ppanel-config/
# Make sure files are readable
chmod 644 ppanel-config/ppanel.yaml
```
### Cannot Access from Outside
1. **Check firewall rules:**
```bash
# Ubuntu/Debian
sudo ufw allow 8080
# CentOS/RHEL
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
```
2. **Verify service is listening:**
```bash
docker compose ps
netstat -tlnp | grep 8080
```
## Next Steps
- [Configuration Guide](/guide/configuration) - Detailed configuration options
- [Admin Dashboard](/admin/dashboard) - Start managing your panel
- [API Reference](/api/reference) - API integration guide
## Need Help?
If you encounter any issues:
1. Check the [Troubleshooting](#troubleshooting) section above
2. Review [Docker Compose logs](#view-logs)
3. Search [GitHub Issues](https://github.com/perfect-panel/ppanel/issues)
4. Create a new issue with detailed system information and logs
+348
View File
@@ -0,0 +1,348 @@
# Docker Run Deployment
This guide shows you how to deploy PPanel using the `docker run` command. This method is suitable for quick testing or simple deployments.
::: tip
For production environments, we recommend using [Docker Compose](/guide/installation/docker-compose) instead.
:::
## Prerequisites
### Install Docker
**Ubuntu/Debian:**
```bash
# Update package index
sudo apt-get update
# Install Docker
sudo apt-get install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
```
**CentOS/RHEL:**
```bash
# Install Docker
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
# Start Docker
sudo systemctl start docker
sudo systemctl enable docker
```
### Verify Installation
```bash
docker --version
sudo docker run hello-world
```
## Quick Start
### Step 1: Pull the Image
```bash
# Pull latest version
docker pull ppanel/ppanel:latest
# Or pull a specific version
docker pull ppanel/ppanel:v0.1.2
```
### Step 2: Prepare Configuration
```bash
# Create configuration directory
mkdir -p ~/ppanel-config
# Create configuration file
cat > ~/ppanel-config/ppanel.yaml <<EOF
server:
host: 0.0.0.0
port: 8080
database:
type: sqlite
path: /app/data/ppanel.db
EOF
```
### Step 3: Run Container
**Basic Command:**
```bash
docker run -d \
--name ppanel \
-p 8080:8080 \
-v ~/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
--restart unless-stopped \
ppanel/ppanel:latest
```
**With All Options:**
```bash
docker run -d \
--name ppanel \
-p 8080:8080 \
-v ~/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
-e TZ=UTC \
--restart unless-stopped \
--memory="2g" \
--cpus="2" \
ppanel/ppanel:latest
```
**Parameter Explanation:**
- `-d`: Run in detached mode (background)
- `--name ppanel`: Set container name
- `-p 8080:8080`: Map port (host:container)
- `-v ~/ppanel-config:/app/etc:ro`: Mount configuration (read-only)
- `-v ppanel-data:/app/data`: Create data volume
- `-e TZ=UTC`: Set timezone
- `--restart unless-stopped`: Auto-restart policy
- `--memory="2g"`: Memory limit
- `--cpus="2"`: CPU limit
### Step 4: Verify Running
```bash
# Check container status
docker ps | grep ppanel
# View logs
docker logs -f ppanel
# Test access
curl http://localhost:8080
```
## Container Management
### View Logs
```bash
# View all logs
docker logs ppanel
# Follow logs in real-time
docker logs -f ppanel
# View last 100 lines
docker logs --tail 100 ppanel
# View logs with timestamps
docker logs -t ppanel
```
### Stop Container
```bash
docker stop ppanel
```
### Start Container
```bash
docker start ppanel
```
### Restart Container
```bash
docker restart ppanel
```
### Remove Container
```bash
# Stop and remove
docker stop ppanel
docker rm ppanel
```
::: warning
Removing the container does not delete the data volume. To remove the volume:
```bash
docker volume rm ppanel-data
```
:::
## Upgrading
### Backup Data
```bash
# Backup configuration
tar czf ppanel-config-backup-$(date +%Y%m%d).tar.gz ~/ppanel-config/
# Backup data volume
docker run --rm \
-v ppanel-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/ppanel-data-backup-$(date +%Y%m%d).tar.gz /data
```
### Upgrade Process
```bash
# Pull latest image
docker pull ppanel/ppanel:latest
# Stop old container
docker stop ppanel
# Remove old container
docker rm ppanel
# Start new container with same configuration
docker run -d \
--name ppanel \
-p 8080:8080 \
-v ~/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
--restart unless-stopped \
ppanel/ppanel:latest
# Verify
docker logs -f ppanel
```
## Advanced Usage
### Custom Network
```bash
# Create network
docker network create ppanel-net
# Run with custom network
docker run -d \
--name ppanel \
--network ppanel-net \
-p 8080:8080 \
-v ~/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
ppanel/ppanel:latest
```
### Environment Variables
```bash
docker run -d \
--name ppanel \
-p 8080:8080 \
-e SERVER_PORT=8080 \
-e DATABASE_TYPE=sqlite \
-e TZ=Asia/Shanghai \
-v ~/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
ppanel/ppanel:latest
```
### Multiple Instances
```bash
# Instance 1 on port 8081
docker run -d \
--name ppanel-1 \
-p 8081:8080 \
-v ~/ppanel-config-1:/app/etc:ro \
-v ppanel-data-1:/app/data \
ppanel/ppanel:latest
# Instance 2 on port 8082
docker run -d \
--name ppanel-2 \
-p 8082:8080 \
-v ~/ppanel-config-2:/app/etc:ro \
-v ppanel-data-2:/app/data \
ppanel/ppanel:latest
```
### Resource Limits
```bash
docker run -d \
--name ppanel \
-p 8080:8080 \
--memory="2g" \
--memory-swap="2g" \
--cpus="2" \
--pids-limit=100 \
-v ~/ppanel-config:/app/etc:ro \
-v ppanel-data:/app/data \
ppanel/ppanel:latest
```
## Troubleshooting
### Container Exits Immediately
```bash
# Check logs
docker logs ppanel
# Check architecture
uname -m
docker image inspect ppanel/ppanel:latest --format '{{.Architecture}}'
```
### Port Already in Use
```bash
# Check what's using the port
sudo lsof -i :8080
# Use different port
docker run -d --name ppanel -p 8081:8080 ...
```
### Configuration Not Loading
```bash
# Verify mount
docker exec ppanel ls -la /app/etc
# Check file content
docker exec ppanel cat /app/etc/ppanel.yaml
# Check permissions
ls -la ~/ppanel-config/
```
### Access Container Shell
```bash
# Access bash (if available)
docker exec -it ppanel bash
# Access sh
docker exec -it ppanel sh
# Run command
docker exec ppanel ls -la /app
```
## Next Steps
- Try [Docker Compose](/guide/installation/docker-compose) for easier management
- Configure [Reverse Proxy](/guide/installation/docker-compose#configure-reverse-proxy)
- Learn about [Configuration](/guide/configuration)
## Need Help?
- Check [GitHub Issues](https://github.com/perfect-panel/ppanel/issues)
- Review Docker logs: `docker logs ppanel`
- Verify system requirements
+57
View File
@@ -0,0 +1,57 @@
# Installation Overview
PPanel supports multiple deployment methods to suit different needs and environments. Choose the method that best fits your requirements.
## Deployment Methods
### Docker Deployment (Recommended)
The easiest and most reliable way to deploy PPanel. Docker ensures consistent environments and simplifies updates.
- **[Docker Run](/guide/installation/docker-run)** - Quick deployment with a single command
- **[Docker Compose](/guide/installation/docker-compose)** - Production-ready deployment with better management
### Traditional Deployment
- **[Binary Deployment](/guide/installation/binary)** - Deploy using pre-built binaries with systemd service
### Advanced Deployment
- **[Kubernetes](/guide/installation/kubernetes)** - Deploy PPanel in Kubernetes clusters for high availability
- **[From Source](/guide/installation/from-source)** - Build and run PPanel from source code
## System Requirements
### Minimum Requirements
- **Operating System**: Linux (Ubuntu 20.04+, Debian 10+, CentOS 8+)
- **CPU**: 1 core
- **Memory**: 512MB RAM
- **Storage**: 1GB available disk space
### Recommended Requirements
- **CPU**: 2+ cores
- **Memory**: 2GB+ RAM
- **Storage**: 5GB+ available disk space
## Prerequisites
All deployment methods require:
- Linux-based operating system
- Basic command line knowledge
- Network access for downloading packages/images
Specific prerequisites vary by deployment method - check the individual guides for details.
## Quick Start
For most users, we recommend starting with Docker Compose:
1. [Install Docker and Docker Compose](/guide/installation/docker-compose#prerequisites)
2. [Download configuration files](/guide/installation/docker-compose#download-configuration)
3. [Start the services](/guide/installation/docker-compose#start-services)
## Need Help?
- Check our [Troubleshooting Guide](/guide/troubleshooting)
- Visit [GitHub Issues](https://github.com/perfect-panel/ppanel/issues)
- Join our community discussions
+93
View File
@@ -0,0 +1,93 @@
# Introduction
Welcome to PPanel! This is a pure, professional, and perfect open-source proxy panel tool designed to provide users with a complete management solution.
## What is PPanel?
PPanel is a modern proxy panel system that uses a separated frontend-backend architecture, providing complete user management, subscription services, order management, node management, and more. Whether you're an individual or enterprise user, PPanel can meet your needs.
## Core Features
- **🎯 Complete Management**: Server management, node configuration, subscription system, product management and more
- **💼 Business Operations**: Order management, coupon system, marketing campaigns, announcement publishing
- **👥 User Support System**: User management, ticket system, documentation center for comprehensive user service
- **📊 Data Analytics**: 12 types of logs with comprehensive traffic, balance, commission data analysis
- **🔧 Flexible Configuration**: Payment config, authentication control, ad management and flexible system options
- **🚀 Modern Tech Stack**: Built with React 19 + TypeScript + TailwindCSS + shadcn/ui
## Terminology
Some of PPanel's terminology differs from other panel systems. To ensure accurate understanding and avoid confusion, please familiarize yourself with the following terms before reading the documentation:
### User Frontend
The interface provided to end users, through which users interact with the system. You can customize or refactor this interface according to your needs to achieve site personalization.
### Admin Frontend
The interface for administrator operations, responsible for managing the system, users, and data. You can customize or refactor this interface according to your management needs.
### Backend Server
PPanel's API layer that handles all data interactions with the frontend, responsible for executing business logic and providing data services.
### Node Server
Responsible for communication between PPanel's backend server and various nodes (landing points), ensuring network node connectivity and service stability.
### Client
The application program users use to connect to the system, typically referring to user device software or applications, responsible for establishing connections with the system and using related services.
## Project Architecture
PPanel uses Monorepo architecture for unified management and maintenance:
### Frontend Applications
- **apps/admin**: Admin panel application providing complete backend management features
- **apps/user**: User-facing application providing service interface for end users
### Shared Packages
- **packages/ui**: Shared UI component library containing all reusable UI components
- **packages/typescript-config**: Unified TypeScript configuration
### Tech Stack
- **Framework**: React 19 + TypeScript
- **Router**: TanStack Router
- **State Management**: Zustand
- **Styling**: TailwindCSS 4.0
- **UI Components**: shadcn/ui
- **Build Tools**: Vite + Turbo
- **Code Standards**: Biome
- **Git Standards**: Lefthook + Gitmoji
## Key Features
### Maintenance
- Server Management
- Node Management
- Subscribe Configuration
- Product Management
### Commerce
- Order Management
- Coupon Management
- Marketing Management
- Announcement Management
### Users & Support
- User Management
- Ticket System
- Document Management
### System
- System Configuration
- Authentication Control
- Payment Configuration
- ADS Configuration
### Logs & Analytics
- Complete operation logs
- Traffic statistics
- Financial data tracking
## Next Steps
- [Installation](/guide/installation/) - Learn how to deploy PPanel
- [Configuration](/guide/configuration) - Configure your PPanel instance
- [Admin Panel](/admin/dashboard) - Start using admin features
+168
View File
@@ -0,0 +1,168 @@
# Node Agent Installation
`ppanel-node` is the lightweight agent each edge server runs to sync routes, heartbeats, and transport keys with the PPanel control plane. This guide covers the fastest install path plus alternative deployments.
## Quick start
```bash
wget -N https://raw.githubusercontent.com/perfect-panel/ppanel-node/master/scripts/install.sh
sudo bash install.sh --api-host https://panel.example.com --server-id 1 --secret-key <SECRET>
```
The script auto-detects your distro/architecture, downloads the latest release, installs geo databases, and sets up the `ppnode` CLI + system service.
### Requirements
- 64-bit Linux (Debian/Ubuntu ≥16, CentOS ≥7, Alpine, Arch, etc.)
- Root access and outbound HTTPS connectivity to `github.com`
- Firewall ports open for the protocols you expose as well as panel callbacks
- Matching **Server ID** + **Secret Key** generated in the PPanel admin console
### Optional flags
- Positional `vX.Y.Z` argument installs a specific tag instead of the latest release.
- `--api-host https://panel.example.com`
- `--server-id <ID>` (matches the record you created under Maintenance → Servers)
- `--secret-key <KEY>`
If the flags are omitted the installer will prompt for the values interactively.
### Service operations
Once installed you can manage the agent with the bundled CLI:
```bash
ppnode status # current state
ppnode start # start daemon
ppnode restart # restart + reload config
ppnode log # follow logs
ppnode update # upgrade to latest release
ppnode update v1.2.3
ppnode uninstall
ppnode generate # regenerate /etc/PPanel-node/config.yml
```
## Installation methods
### Method 1 — One-click installer (recommended)
Use the Quick Start command above or run `sudo bash install.sh` and answer the prompts. Behind the scenes the script:
1. Installs prerequisites (`wget`, `curl`, `tar`, `socat`, cron, etc.).
2. Downloads `ppanel-node-linux-<arch>.zip` for amd64, arm64, or s390x.
3. Extracts to `/usr/local/PPanel-node`, installs `geoip.dat`/`geosite.dat`, and wires the service with systemd/OpenRC.
4. Drops the helper CLI to `/usr/bin/ppnode` and enables auto-start.
### Method 2 — Build from source
1. Install Go 1.21 or newer and enable the JSON v2 experiment:
```bash
export GOEXPERIMENT=jsonv2
```
2. Clone the repository and build:
```bash
git clone https://github.com/perfect-panel/ppanel-node.git
cd ppanel-node
GOEXPERIMENT=jsonv2 go build -v -o ./ppnode -trimpath -ldflags "-s -w -buildid="
```
3. Copy the binary plus geo assets to their runtime locations:
```bash
sudo install -Dm755 ./ppnode /usr/local/PPanel-node/ppnode
sudo install -Dm644 ./geoip.dat /etc/PPanel-node/geoip.dat
sudo install -Dm644 ./geosite.dat /etc/PPanel-node/geosite.dat
```
4. Create the systemd unit (adapt paths as needed):
```bash
sudo tee /etc/systemd/system/PPanel-node.service <<'EOF'
[Unit]
Description=PPanel Node
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/PPanel-node/ppnode server
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now PPanel-node
```
5. Copy `config.yml` from the repo or create it manually (see the configuration section) and restart the service.
### Method 3 — Docker / container images
The repository ships a `Dockerfile`. You can build and run it on hosts where installing directly is undesirable:
```bash
git clone https://github.com/perfect-panel/ppanel-node.git
cd ppanel-node
docker build -t ppanel-node:latest .
docker run -d --name ppanel-node \
--net host \
-v /etc/PPanel-node:/etc/PPanel-node \
ppanel-node:latest server
```
Recommended bind mounts:
- `/etc/PPanel-node/config.yml` credentials and API settings.
- `/etc/PPanel-node/geoip.dat` & `/etc/PPanel-node/geosite.dat` keep them on the host so updates persist.
- `/var/log/ppanel-node` (optional) collect structured logs outside the container.
## Configure the node
The runtime configuration lives in `/etc/PPanel-node/config.yml`. The installer generates the file with the following structure:
```yaml
Log:
Level: warn # debug | info | warn | error
Output: "" # empty = stdout, or set a file path
Access: none # path for access logs, or "none"
Api:
ApiHost: https://panel.example.com
ServerID: 3
SecretKey: b23d8ee1cfe44d7f
Timeout: 30
```
After editing the file, restart the service:
```bash
sudo systemctl restart PPanel-node
# or
ppnode restart
```
### Mapping to the panel
1. Create a server entry in the **Maintenance → Servers** page inside the PPanel admin UI.
2. Copy the generated **Server ID** and **Secret Key** into `config.yml`.
3. Ensure the node host can reach the panels HTTPS endpoint defined as `ApiHost`.
4. Approve the node once it appears under the panels node list (heartbeat should update within ~30 seconds).
## Maintenance
- `ppnode update` keeps configuration/geo files intact while replacing the binary.
- `ppnode update vX.Y.Z` pins a specific release for rollbacks.
- For manual builds, rebuild the target tag, replace `/usr/local/PPanel-node/ppnode`, then `systemctl restart PPanel-node`.
## Troubleshooting
- `ppnode log` or `journalctl -u PPanel-node -f` surfaces runtime logs.
- Validate `/etc/PPanel-node/config.yml`—typos in `ApiHost` or `SecretKey` cause auth failures.
- Ensure the host can reach GitHub (updates) and your panel domain on port 443.
- If the panel lists the node as offline, verify firewall rules allow heartbeats and that NTP is synchronized (`chronyc tracking`).
Need more detail? Review the source at [`github.com/perfect-panel/ppanel-node`](https://github.com/perfect-panel/ppanel-node).
+505
View File
@@ -0,0 +1,505 @@
# Backend Separation Deployment
This guide will help you independently deploy the PPanel backend service, suitable for front-end and back-end separation deployment scenarios.
## Overview
Backend separation deployment allows you to deploy the PPanel backend service on an independent server to provide API services for frontend applications. This deployment method has the following advantages:
- 🚀 Independently scale backend service performance
- 🔒 Better security isolation
- 🌐 Support multiple frontend instances connecting to the same backend
- 🛠️ Facilitate independent maintenance and upgrades of backend services
## System Requirements
### Minimum Configuration
- CPU: 1 core
- Memory: 1 GB
- Storage: 10 GB
- OS: Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+ recommended)
### Recommended Configuration
- CPU: 2+ cores
- Memory: 2+ GB
- Storage: 20+ GB
## Deployment Methods
### Method 1: Docker Deployment (Recommended)
#### 1. Install Docker
```bash
# Ubuntu/Debian
curl -fsSL https://get.docker.com | sh
# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker
```
#### 2. Create Configuration File
Create backend config file `config.yaml`:
```yaml
# Database configuration
database:
type: mysql
host: localhost
port: 3306
username: ppanel
password: your_password
database: ppanel
# Redis configuration
redis:
host: localhost
port: 6379
password: ""
db: 0
# Server configuration
server:
host: 0.0.0.0
port: 8080
# CORS configuration (Important: allow frontend domain access)
cors:
allow_origins:
- "https://your-frontend-domain.com"
- "http://localhost:3000" # Development environment
allow_methods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
allow_headers:
- "*"
# JWT configuration
jwt:
secret: "your-secret-key"
expire: 7200 # 2 hours
# API configuration
api:
prefix: "/api"
version: "v1"
```
#### 3. Prepare MySQL Database
```bash
# Run MySQL with Docker
docker run -d \
--name ppanel-mysql \
-e MYSQL_ROOT_PASSWORD=root_password \
-e MYSQL_DATABASE=ppanel \
-e MYSQL_USER=ppanel \
-e MYSQL_PASSWORD=your_password \
-p 3306:3306 \
-v ppanel-mysql-data:/var/lib/mysql \
mysql:8.0
# Wait for MySQL to start
sleep 10
```
#### 4. Prepare Redis
```bash
# Run Redis with Docker
docker run -d \
--name ppanel-redis \
-p 6379:6379 \
-v ppanel-redis-data:/data \
redis:7-alpine
```
#### 5. Run Backend Service
```bash
# Pull backend image
docker pull ghcr.io/perfect-panel/ppanel:latest
# Run backend container
docker run -d \
--name ppanel-backend \
-p 8080:8080 \
-v $(pwd)/config.yaml:/app/config.yaml \
--link ppanel-mysql:mysql \
--link ppanel-redis:redis \
ghcr.io/perfect-panel/ppanel:latest
```
#### 6. Initialize Database
```bash
# Execute database migration
docker exec ppanel-backend ./ppanel migrate
```
### Method 2: Binary Deployment
#### 1. Download Backend Program
```bash
# Download latest version
wget https://github.com/perfect-panel/ppanel/releases/latest/download/ppanel-linux-amd64.tar.gz
# Extract
tar -xzf ppanel-linux-amd64.tar.gz
cd ppanel
# Grant execute permission
chmod +x ppanel
```
#### 2. Configure Backend Service
Create config file `config.yaml` (same content as Docker deployment method).
#### 3. Install and Configure MySQL
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install mysql-server -y
# Create database and user
sudo mysql <<EOF
CREATE DATABASE ppanel;
CREATE USER 'ppanel'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON ppanel.* TO 'ppanel'@'localhost';
FLUSH PRIVILEGES;
EOF
```
#### 4. Install and Configure Redis
```bash
# Ubuntu/Debian
sudo apt install redis-server -y
sudo systemctl start redis-server
sudo systemctl enable redis-server
```
#### 5. Initialize Database
```bash
# Execute database migration
./ppanel migrate
```
#### 6. Create systemd Service
Create service file `/etc/systemd/system/ppanel.service`:
```ini
[Unit]
Description=PPanel Backend Service
After=network.target mysql.service redis.service
[Service]
Type=simple
User=ppanel
WorkingDirectory=/opt/ppanel
ExecStart=/opt/ppanel/ppanel server
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
```
Start service:
```bash
# Create dedicated user
sudo useradd -r -s /bin/false ppanel
# Move files to installation directory
sudo mkdir -p /opt/ppanel
sudo mv ppanel config.yaml /opt/ppanel/
sudo chown -R ppanel:ppanel /opt/ppanel
# Start service
sudo systemctl daemon-reload
sudo systemctl start ppanel
sudo systemctl enable ppanel
# Check service status
sudo systemctl status ppanel
```
## Configure Reverse Proxy
### Nginx Configuration
```nginx
server {
listen 80;
server_name api.your-domain.com;
# HTTPS redirect (recommended to configure SSL certificate)
# return 301 https://$server_name$request_uri;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeout configuration
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
# HTTPS configuration example
# server {
# listen 443 ssl http2;
# server_name api.your-domain.com;
#
# ssl_certificate /path/to/cert.pem;
# ssl_certificate_key /path/to/key.pem;
#
# location / {
# proxy_pass http://127.0.0.1:8080;
# # ... other configs same as above
# }
# }
```
Reload Nginx:
```bash
sudo nginx -t
sudo systemctl reload nginx
```
### Caddy Configuration
```caddy
api.your-domain.com {
reverse_proxy localhost:8080
}
```
## Verify Deployment
### Health Check
```bash
# Check if backend service is running
curl http://localhost:8080/api/health
# Expected output
# {"status":"ok","version":"1.0.0"}
```
### Test API
```bash
# Test public API
curl http://localhost:8080/api/v1/ping
# Expected output
# {"message":"pong"}
```
## Environment Variable Configuration
Besides config file, you can also use environment variables:
```bash
# Database configuration
export DB_HOST=localhost
export DB_PORT=3306
export DB_USER=ppanel
export DB_PASSWORD=your_password
export DB_NAME=ppanel
# Redis configuration
export REDIS_HOST=localhost
export REDIS_PORT=6379
export REDIS_PASSWORD=""
# JWT secret
export JWT_SECRET=your-secret-key
# Server port
export SERVER_PORT=8080
```
Using environment variables with Docker:
```bash
docker run -d \
--name ppanel-backend \
-p 8080:8080 \
-e DB_HOST=mysql \
-e DB_USER=ppanel \
-e DB_PASSWORD=your_password \
-e REDIS_HOST=redis \
--link ppanel-mysql:mysql \
--link ppanel-redis:redis \
ghcr.io/perfect-panel/ppanel:latest
```
## Security Recommendations
1. **Use Strong Passwords**: Set strong passwords for database and JWT secret
2. **Configure Firewall**: Only open necessary ports (e.g., 80, 443)
3. **Enable HTTPS**: Use SSL/TLS certificates to encrypt communication
4. **CORS Configuration**: Only allow trusted frontend domains
5. **Regular Backups**: Regularly backup database and config files
6. **Monitor Logs**: Regularly check application and system logs
## Troubleshooting
### Service Failed to Start
```bash
# View service logs
sudo journalctl -u ppanel -n 50 --no-pager
# Docker view logs
docker logs ppanel-backend
```
### Database Connection Failed
```bash
# Test MySQL connection
mysql -h localhost -u ppanel -p -e "SELECT 1;"
# Check MySQL service status
sudo systemctl status mysql
```
### Redis Connection Failed
```bash
# Test Redis connection
redis-cli ping
# Check Redis service status
sudo systemctl status redis-server
```
### CORS Error
Ensure frontend domain is correctly configured in `config.yaml`:
```yaml
cors:
allow_origins:
- "https://your-frontend-domain.com"
```
## Performance Optimization
### Database Optimization
```sql
-- Create necessary indexes
CREATE INDEX idx_user_email ON users(email);
CREATE INDEX idx_order_status ON orders(status);
CREATE INDEX idx_created_at ON orders(created_at);
```
### Redis Cache Configuration
```yaml
redis:
# Enable cache
cache_enabled: true
# Cache expiration time (seconds)
cache_ttl: 3600
```
### Application Layer Optimization
```yaml
# Enable Gzip compression
server:
gzip: true
# Adjust concurrent connections
server:
max_connections: 1000
```
## Upgrade Guide
### Docker Upgrade
```bash
# Pull latest image
docker pull ghcr.io/perfect-panel/ppanel:latest
# Stop old container
docker stop ppanel-backend
# Backup data
docker exec ppanel-mysql mysqldump -u ppanel -p ppanel > backup.sql
# Remove old container
docker rm ppanel-backend
# Run new container
docker run -d \
--name ppanel-backend \
-p 8080:8080 \
-v $(pwd)/config.yaml:/app/config.yaml \
--link ppanel-mysql:mysql \
--link ppanel-redis:redis \
ghcr.io/perfect-panel/ppanel:latest
# Execute database migration
docker exec ppanel-backend ./ppanel migrate
```
### Binary Upgrade
```bash
# Stop service
sudo systemctl stop ppanel
# Backup old version
sudo cp /opt/ppanel/ppanel /opt/ppanel/ppanel.backup
# Download new version
wget https://github.com/perfect-panel/ppanel/releases/latest/download/ppanel-linux-amd64.tar.gz
tar -xzf ppanel-linux-amd64.tar.gz
# Replace file
sudo mv ppanel /opt/ppanel/
sudo chown ppanel:ppanel /opt/ppanel/ppanel
# Execute database migration
cd /opt/ppanel
sudo -u ppanel ./ppanel migrate
# Start service
sudo systemctl start ppanel
```
## Next Steps
- [Frontend Separation Deployment](./frontend.md) - Deploy frontend application
- [Node Agent Installation](../node/installation.md) - Deploy node service
- [API Documentation](/api/reference) - View complete API documentation
+689
View File
@@ -0,0 +1,689 @@
# Frontend Separation Deployment
This guide will help you independently deploy PPanel frontend applications and connect them to the deployed backend service.
## Overview
Frontend separation deployment allows you to deploy PPanel frontend applications on independent servers or CDN, communicating with backend services through APIs.
PPanel frontend includes two independent applications:
- **User Web** (`ppanel-user-web`): User-facing interface
- **Admin Web** (`ppanel-admin-web`): Administrator backend management interface
### Advantages
- 🚀 Leverage CDN to accelerate static resource access
- 🌍 Support multi-region distribution
- 📦 Independent frontend deployment without affecting backend services
- 🔄 Facilitate rapid frontend iteration and updates
- 🎨 Modern tech stack (React 19, TypeScript, TailwindCSS 4)
## Prerequisites
- Completed [Backend Deployment](./backend.md)
- Backend API address (e.g., `https://api.your-domain.com`)
- Frontend domains:
- User Web: `https://user.your-domain.com`
- Admin Web: `https://admin.your-domain.com`
## Tech Stack
- **Runtime**: Bun (recommended) / Node.js 20+
- **Build Tool**: Vite 6
- **Framework**: React 19 + TypeScript
- **Router**: TanStack Router
- **Styling**: TailwindCSS 4
- **State Management**: Zustand
- **i18n**: i18next
- **Monorepo**: Turborepo
## Deployment Methods
### Method 1: Build from Source (Recommended)
#### 1. Environment Setup
Install Bun (recommended):
```bash
# Linux/macOS
curl -fsSL https://bun.sh/install | bash
# Windows (WSL2)
curl -fsSL https://bun.sh/install | bash
# Verify installation
bun --version
```
Or use Node.js (requires 20+):
```bash
# Check Node.js version
node --version # Should be v20 or higher
```
#### 2. Clone Repository
```bash
git clone https://github.com/perfect-panel/frontend.git
cd frontend
```
#### 3. Install Dependencies
```bash
# Using Bun (recommended, faster)
bun install
# Or using npm
npm install
# Or using pnpm
pnpm install
```
#### 4. Configure Environment Variables
Create environment configuration files in application directories.
**Admin Web Config** (`apps/admin/.env.production`):
```bash
# Backend API address (required)
VITE_API_BASE_URL=https://api.your-domain.com
# CDN address (optional, for accelerating static resources)
VITE_CDN_URL=https://cdn.jsdmirror.com
# Enable tutorial documentation (optional)
VITE_TUTORIAL_DOCUMENT=true
# Development default credentials (leave empty in production)
VITE_USER_EMAIL=
VITE_USER_PASSWORD=
```
**User Web Config** (`apps/user/.env.production`):
```bash
# Backend API address (required)
VITE_API_BASE_URL=https://api.your-domain.com
# CDN address (optional)
VITE_CDN_URL=https://cdn.jsdmirror.com
# Enable tutorial documentation (optional)
VITE_TUTORIAL_DOCUMENT=true
# Development default credentials (leave empty in production)
VITE_USER_EMAIL=
VITE_USER_PASSWORD=
```
#### 5. Build Applications
Build all applications:
```bash
# Using Bun
bun run build
# Or using npm
npm run build
```
Build specific application:
```bash
# Navigate to application directory
cd apps/admin # or apps/user
# Build
bun run build # or npm run build
```
After build completes, static files will be output to:
- Admin Web: `apps/admin/dist/`
- User Web: `apps/user/dist/`
#### 6. Preview Build
```bash
# In application directory
bun run serve # or npm run serve
# Default access address:
# Admin Web: http://localhost:4173
# User Web: http://localhost:4173
```
### Method 2: Deploy with Vercel (One-Click)
#### Admin Web Deployment
Click the button below to deploy to Vercel with one click:
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fadmin.ppanel.dev&demo-title=PPanel%20Admin%20Web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Ffrontend&root-directory=apps%2Fadmin)
#### User Web Deployment
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fuser.ppanel.dev&demo-title=PPanel%20User%20Web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Ffrontend&root-directory=apps%2Fuser)
After deployment, configure environment variables in Vercel console:
- `VITE_API_BASE_URL`: Your backend API address
- `VITE_CDN_URL`: CDN address (optional)
### Method 3: Deploy with Netlify
#### 1. Install Netlify CLI
```bash
npm install -g netlify-cli
```
#### 2. Login to Netlify
```bash
netlify login
```
#### 3. Deploy Application
```bash
# Admin Web
cd apps/admin
bun run build
netlify deploy --prod --dir=dist
# User Web
cd apps/user
bun run build
netlify deploy --prod --dir=dist
```
#### 4. Configure Environment Variables
Add in Netlify console under Site settings → Build & deploy → Environment:
- `VITE_API_BASE_URL`
- `VITE_CDN_URL`
### Method 4: Deploy with Cloudflare Pages
#### 1. Connect GitHub Repository
Login to Cloudflare Dashboard → Workers & Pages → Create application → Pages → Connect to Git
#### 2. Configure Build Settings
**Admin Web**:
- **Framework preset**: None
- **Build command**: `cd .. && bun install && cd apps/admin && bun run build`
- **Build output directory**: `apps/admin/dist`
- **Root directory**: `apps/admin`
**User Web**:
- **Framework preset**: None
- **Build command**: `cd .. && bun install && cd apps/user && bun run build`
- **Build output directory**: `apps/user/dist`
- **Root directory**: `apps/user`
#### 3. Configure Environment Variables
Add in Settings → Environment variables:
- `VITE_API_BASE_URL`
- `VITE_CDN_URL`
## Self-Hosted Server Deployment
### Using Nginx
#### 1. Install Nginx
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install nginx -y
# CentOS/RHEL
sudo yum install nginx -y
```
#### 2. Upload Build Files
```bash
# Create directories
sudo mkdir -p /var/www/ppanel/{admin,user}
# Upload build files
sudo cp -r apps/admin/dist/* /var/www/ppanel/admin/
sudo cp -r apps/user/dist/* /var/www/ppanel/user/
# Set permissions
sudo chown -R www-data:www-data /var/www/ppanel
```
#### 3. Configure Nginx
**Admin Web Config** (`/etc/nginx/sites-available/ppanel-admin`):
```nginx
server {
listen 80;
server_name admin.your-domain.com;
root /var/www/ppanel/admin;
index index.html;
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
gzip_min_length 1024;
# Static resource caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA routing support
location / {
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
}
```
**User Web Config** (`/etc/nginx/sites-available/ppanel-user`):
```nginx
server {
listen 80;
server_name user.your-domain.com;
root /var/www/ppanel/user;
index index.html;
# Other config same as admin web
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
try_files $uri $uri/ /index.html;
}
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}
```
#### 4. Enable Sites
```bash
# Enable sites
sudo ln -s /etc/nginx/sites-available/ppanel-admin /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/ppanel-user /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
```
#### 5. Configure HTTPS (Recommended)
Use Certbot to automatically configure SSL certificates:
```bash
# Install Certbot
sudo apt install certbot python3-certbot-nginx -y
# Obtain certificates
sudo certbot --nginx -d admin.your-domain.com
sudo certbot --nginx -d user.your-domain.com
# Test auto-renewal
sudo certbot renew --dry-run
```
### Using Caddy
Caddy automatically handles HTTPS with simpler configuration.
#### 1. Install Caddy
```bash
# Ubuntu/Debian
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
```
#### 2. Configure Caddyfile
Create `/etc/caddy/Caddyfile`:
```caddy
admin.your-domain.com {
root * /var/www/ppanel/admin
encode gzip
file_server
try_files {path} /index.html
@static {
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.svg *.woff *.woff2 *.ttf *.eot
}
header @static Cache-Control "public, max-age=31536000, immutable"
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
}
}
user.your-domain.com {
root * /var/www/ppanel/user
encode gzip
file_server
try_files {path} /index.html
@static {
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.svg *.woff *.woff2 *.ttf *.eot
}
header @static Cache-Control "public, max-age=31536000, immutable"
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
}
}
```
#### 3. Start Caddy
```bash
sudo systemctl restart caddy
sudo systemctl enable caddy
```
## CDN Configuration
### Cloudflare Configuration
1. Add domain to Cloudflare
2. Configure DNS records pointing to origin server
3. Enable optimization options:
- **Auto Minify**: Enable JavaScript, CSS, HTML minification
- **Brotli**: Enable Brotli compression
- **Rocket Loader**: Enable JS async loading (optional)
- **Caching Level**: Set to Standard
4. Configure page rules:
```
*your-domain.com/*
- Cache Level: Cache Everything
- Edge Cache TTL: 1 month
- Browser Cache TTL: Respect Existing Headers
```
### Alibaba Cloud CDN
1. Create CDN acceleration domain
2. Configure origin server: Point to frontend server
3. Configure caching rules:
- Static files (js, css, images): Cache 1 year
- HTML files: Cache 5 minutes or no cache
4. Enable HTTPS and HTTP/2
## Environment Variables
| Variable | Description | Required | Default | Example |
|----------|-------------|----------|---------|---------|
| `VITE_API_BASE_URL` | Backend API address | ✅ | - | `https://api.your-domain.com` |
| `VITE_CDN_URL` | CDN address | ❌ | `https://cdn.jsdmirror.com` | `https://cdn.your-domain.com` |
| `VITE_TUTORIAL_DOCUMENT` | Enable tutorial docs | ❌ | `true` | `true` / `false` |
| `VITE_USER_EMAIL` | Default login email (dev only) | ❌ | - | - |
| `VITE_USER_PASSWORD` | Default login password (dev only) | ❌ | - | - |
## Verify Deployment
### Check Frontend Service
```bash
# Access frontend addresses
curl -I https://admin.your-domain.com
curl -I https://user.your-domain.com
# Expected output
# HTTP/2 200
# content-type: text/html
```
### Check API Connection
Open frontend address in browser, open developer tools:
1. Check Network tab
2. Verify API requests are successful
3. Confirm request addresses are correct (`https://api.your-domain.com`)
4. Check response data is normal
### Check Build Version
Access `/version.lock` file to view currently deployed version:
```bash
curl https://admin.your-domain.com/version.lock
# Example output: 1.2.0
```
## Performance Optimization
### 1. Enable HTTP/2
In Nginx:
```nginx
listen 443 ssl http2;
```
### 2. Enable Brotli Compression
```bash
# Install Nginx Brotli module
sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static -y
```
In Nginx configuration:
```nginx
brotli on;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml;
brotli_comp_level 6;
```
### 3. Preload Critical Resources
Vite automatically handles this during build, adding `<link rel="modulepreload">` in `index.html`.
### 4. Enable Service Worker
Frontend has built-in PWA support, Service Worker caching is automatically enabled after build.
### 5. Use CDN Acceleration
Configure `VITE_CDN_URL` environment variable to load static resources from CDN.
## Troubleshooting
### API Request Failed
**Issue**: Frontend cannot connect to backend API
**Solution**:
1. Check if `VITE_API_BASE_URL` is correctly configured
2. Check if backend CORS configuration allows frontend domain
3. Open browser console for specific error messages
4. Use `curl` to test if backend API is accessible
```bash
curl https://api.your-domain.com/api/health
```
### Page Route 404
**Issue**: Refreshing page or directly accessing sub-route returns 404
**Solution**: Ensure web server has SPA fallback configured
```nginx
# Nginx
try_files $uri $uri/ /index.html;
# Apache (.htaccess)
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
```
### Static Resource Loading Failed
**Issue**: JS/CSS files 404 or cannot load
**Solution**:
1. Check file permissions
2. Check if Nginx `root` path is correct
3. Clear browser cache
4. Check CDN configuration
### Build Failed
**Issue**: `bun run build` or `npm run build` fails
**Solution**:
1. Ensure Node.js version >= 20
2. Delete `node_modules` and lock file, reinstall
```bash
rm -rf node_modules bun.lockb
bun install
```
3. Check for syntax errors or type errors
```bash
bun run check
```
## Update Deployment
### Update from Source
```bash
# Pull latest code
git pull origin main
# Reinstall dependencies
bun install
# Rebuild
bun run build
# Update files
sudo rm -rf /var/www/ppanel/admin
sudo rm -rf /var/www/ppanel/user
sudo cp -r apps/admin/dist /var/www/ppanel/admin
sudo cp -r apps/user/dist /var/www/ppanel/user
# Clear CDN cache (if using CDN)
```
### Vercel Update
Vercel automatically monitors GitHub repository changes and deploys automatically. Can also trigger manually:
```bash
vercel --prod
```
### Netlify Update
```bash
cd apps/admin # or apps/user
bun run build
netlify deploy --prod
```
## Security Recommendations
1. **Enable HTTPS**: Must use SSL/TLS certificates
2. **Configure CSP**: Content Security Policy
```nginx
add_header Content-Security-Policy "default-src 'self'; connect-src 'self' https://api.your-domain.com; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';";
```
3. **Set Security Headers**: Already included in Nginx configuration
4. **Disable Directory Browsing**: `Options -Indexes` (Apache) or `autoindex off;` (Nginx)
5. **Limit File Upload Size**:
```nginx
client_max_body_size 10M;
```
## Monitoring and Analytics
### Add Web Analytics
Supports Google Analytics, Umami, Plausible, etc.
Configuration: Add tracking code in `index.html` or configure via environment variables.
### Error Tracking
Frontend supports integrating Sentry for error tracking (needs code configuration).
## Development and Production
### Local Development
```bash
# Use development server
cd apps/admin # or apps/user
bun run dev
# Admin Web runs on http://localhost:3001 by default
# User Web runs on http://localhost:3000 by default
```
Development environment uses Vite's proxy feature to proxy API requests to backend.
### Preview Production Build
```bash
# Preview after build
bun run build
bun run serve
```
## Next Steps
- [Backend Separation Deployment](./backend.md) - If backend not yet deployed
- [Node Agent Installation](../node/installation.md) - Deploy node service
- [Feature Documentation](/admin/dashboard) - Learn feature usage