## 📋 环境信息
| 组件 | 版本 | 说明 |
|------|------|------|
| **操作系统** | Rocky Linux 9.7 | RHEL 9兼容 |
| **PostgreSQL** | 17.4 | 最新稳定版 |
| **Apache Superset** | 6.0.0 | 最新稳定版 |
| **Python** | 3.11 | Rocky Linux 9.7自带 |
| **Nginx** | 1.24 | 反向代理/静态文件服务 |
| **Redis** | 7.4 | 缓存/消息队列 |
---
## 第一阶段:系统初始化
### 1.1 基础配置
```bash
# 1. 更新系统
sudo dnf update -y
sudo reboot
# 2. 安装基础工具
sudo dnf install -y vim wget curl net-tools telnet yum-utils \
epel-release crb-release chrony ipvsadm ipset \
policycoreutils-python-utils setools-console
# 3. 启用CRB仓库
sudo dnf config-manager --set-enabled crb
# 4. 配置主机名
sudo hostnamectl set-hostname superset-prod-01
# 5. 配置时区
sudo timedatectl set-timezone Asia/Shanghai
sudo systemctl enable chronyd --now
# 6. 关闭SELinux(或配置为permissive)
sudo setenforce 0
sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config
# 7. 防火墙配置
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8088/tcp # Superset内部
sudo firewall-cmd --reload
# 8. 内核优化
sudo tee /etc/sysctl.d/superset.conf << 'EOF'
vm.overcommit_memory = 1
vm.swappiness = 10
net.core.somaxconn = 65535
fs.file-max = 2097152
EOF
sudo sysctl --system
# 9. 创建Superset用户(家目录在/opt/superset)
sudo useradd -r -m -d /opt/superset -s /bin/bash superset
sudo usermod -aG wheel superset
```
---
## 第二阶段:PostgreSQL 17 部署
### 2.1 安装PostgreSQL 17
```bash
# 1. 添加官方仓库
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# 2. 禁用默认模块
sudo dnf -qy module disable postgresql
# 3. 安装PostgreSQL 17
sudo dnf install -y postgresql17-server postgresql17-contrib postgresql17-devel
# 4. 初始化数据库
sudo /usr/pgsql-17/bin/postgresql-17-setup initdb
# 5. 启动服务
sudo systemctl enable postgresql-17
sudo systemctl start postgresql-17
```
### 2.2 配置PostgreSQL
```bash
# 1. 创建配置目录
sudo mkdir -p /etc/postgresql/17/main
sudo cp /var/lib/pgsql/17/data/postgresql.conf /etc/postgresql/17/main/
sudo cp /var/lib/pgsql/17/data/pg_hba.conf /etc/postgresql/17/main/
# 2. 生产优化配置
sudo tee /etc/postgresql/17/main/postgresql.conf << 'EOF'
listen_addresses = '*'
port = 5432
max_connections = 200
# 内存配置(根据实际内存调整,假设32GB)
shared_buffers = 8GB
effective_cache_size = 24GB
maintenance_work_mem = 2GB
work_mem = 20MB
# WAL配置
wal_level = replica
wal_compression = on
max_wal_size = 4GB
min_wal_size = 1GB
checkpoint_completion_target = 0.9
# 性能优化
random_page_cost = 1.1
effective_io_concurrency = 200
# 日志配置
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_min_duration_statement = 1000
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
# 时区
timezone = 'Asia/Shanghai'
EOF
# 3. 访问控制配置
sudo tee /etc/postgresql/17/main/pg_hba.conf << 'EOF'
# 本地连接
local all all scram-sha-256
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
# Superset应用
host all all 127.0.0.1/32 scram-sha-256
# 拒绝其他
host all all 0.0.0.0/0 reject
EOF
# 4. 创建日志目录
sudo mkdir -p /var/log/postgresql
sudo chown postgres:postgres /var/log/postgresql
# 5. 更新数据目录配置
sudo tee /var/lib/pgsql/17/data/postgresql.auto.conf << 'EOF'
include_if_exists = '/etc/postgresql/17/main/postgresql.conf'
EOF
# 6. 重启生效
sudo systemctl restart postgresql-17
```
### 2.3 创建Superset数据库
```bash
# 生成强密码
DB_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
echo "$DB_PASSWORD" | sudo tee /opt/superset/.db_password
sudo chmod 600 /opt/superset/.db_password
# 创建数据库和用户
sudo -u postgres psql << EOF
CREATE USER superset WITH PASSWORD '${DB_PASSWORD}' SUPERUSER;
CREATE DATABASE superset OWNER superset ENCODING 'UTF8' LC_COLLATE='en_US.UTF-8' LC_CTYPE='en_US.UTF-8' TEMPLATE=template0;
CREATE DATABASE superset_cache OWNER superset ENCODING 'UTF8';
GRANT ALL PRIVILEGES ON DATABASE superset TO superset;
GRANT ALL PRIVILEGES ON DATABASE superset_cache TO superset;
EOF
```
---
## 第三阶段:Redis 7 部署
```bash
# 1. 安装Redis
sudo dnf module reset redis -y
sudo dnf module enable redis:7 -y
sudo dnf install -y redis
# 2. 生成密码
REDIS_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
echo "$REDIS_PASSWORD" | sudo tee /opt/superset/.redis_password
sudo chmod 600 /opt/superset/.redis_password
# 3. 配置Redis
sudo tee /etc/redis/redis.conf << EOF
bind 127.0.0.1
port 6379
requirepass ${REDIS_PASSWORD}
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
supervised systemd
loglevel notice
EOF
# 4. 启动服务
sudo systemctl enable redis --now
```
---
## 第四阶段:Superset 6.0.0 部署
### 4.1 安装Python 3.11和依赖
```bash
# 1. 安装Python 3.11和开发工具
sudo dnf install -y python3.11 python3.11-pip python3.11-devel \
gcc gcc-c++ make libffi-devel openssl-devel \
zlib-devel bzip2-devel readline-devel sqlite-devel
# 2. 安装virtualenv
sudo pip3.11 install virtualenv
# 3. 创建虚拟环境(关键:路径为 /opt/superset/venv)
sudo su - superset -c "python3.11 -m venv /opt/superset/venv"
# 4. 安装Superset及依赖
sudo su - superset -c "
source /opt/superset/venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install apache-superset==6.0.0
pip install psycopg2-binary redis celery gevent gunicorn pyarrow pillow
deactivate
"
# 5. 验证安装
sudo su - superset -c "/opt/superset/venv/bin/superset --version"
sudo su - superset -c "/opt/superset/venv/bin/gunicorn --version"
```
### 4.2 创建生产级配置文件
```bash
# 生成密钥
SECRET_KEY=$(openssl rand -base64 42)
echo "$SECRET_KEY" | sudo tee /opt/superset/.secret_key
sudo chmod 600 /opt/superset/.secret_key
# 创建配置目录
sudo mkdir -p /opt/superset/etc
sudo chown -R superset:superset /opt/superset
# 主配置文件
sudo tee /opt/superset/etc/superset_config.py << 'PYTHON_EOF'
import os
from celery.schedules import crontab
# 安全密钥
SECRET_KEY = open('/opt/superset/.secret_key').read().strip()
# 数据库配置
DB_PASSWORD = open('/opt/superset/.db_password').read().strip()
SQLALCHEMY_DATABASE_URI = f'postgresql+psycopg2://superset:{DB_PASSWORD}@localhost:5432/superset'
SQLALCHEMY_ENGINE_OPTIONS = {
"pool_size": 20,
"max_overflow": 10,
"pool_recycle": 3600,
"pool_pre_ping": True,
}
# Redis配置
REDIS_PASSWORD = open('/opt/superset/.redis_password').read().strip()
REDIS_HOST = "localhost"
REDIS_PORT = 6379
# 缓存配置
CACHE_CONFIG = {
"CACHE_TYPE": "RedisCache",
"CACHE_DEFAULT_TIMEOUT": 300,
"CACHE_KEY_PREFIX": "superset_",
"CACHE_REDIS_HOST": REDIS_HOST,
"CACHE_REDIS_PORT": REDIS_PORT,
"CACHE_REDIS_PASSWORD": REDIS_PASSWORD,
"CACHE_REDIS_DB": 1,
}
DATA_CACHE_CONFIG = {
"CACHE_TYPE": "RedisCache",
"CACHE_DEFAULT_TIMEOUT": 3600,
"CACHE_KEY_PREFIX": "superset_data_",
"CACHE_REDIS_HOST": REDIS_HOST,
"CACHE_REDIS_PORT": REDIS_PORT,
"CACHE_REDIS_PASSWORD": REDIS_PASSWORD,
"CACHE_REDIS_DB": 2,
}
# Celery配置
class CeleryConfig:
broker_url = f"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/0"
result_backend = f"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/3"
worker_prefetch_multiplier = 1
task_acks_late = True
task_time_limit = 600
task_soft_time_limit = 300
worker_concurrency = 4
beat_schedule = {
"reports.scheduler": {
"task": "reports.scheduler",
"schedule": crontab(minute="*", hour="*"),
},
"reports.prune_log": {
"task": "reports.prune_log",
"schedule": crontab(minute=10, hour=0),
},
}
CELERY_CONFIG = CeleryConfig
# 功能开关
FEATURE_FLAGS = {
"ALERT_REPORTS": True,
"EMBEDDED_SUPERSET": True,
"ENABLE_TEMPLATE_PROCESSING": True,
"DASHBOARD_RBAC": True,
"THUMBNAILS": True,
"DASHBOARD_NATIVE_FILTERS": True,
}
# 性能配置
SUPERSET_WEBSERVER_TIMEOUT = 300
SQLLAB_TIMEOUT = 300
ROW_LIMIT = 100000
# 上传配置
UPLOAD_FOLDER = "/opt/superset/uploads/"
IMG_UPLOAD_FOLDER = "/opt/superset/images/"
MAX_CONTENT_LENGTH = 50 * 1024 * 1024
# 邮件配置(可选)
SMTP_HOST = os.environ.get("SMTP_HOST", "")
SMTP_PORT = int(os.environ.get("SMTP_PORT", "587"))
SMTP_USER = os.environ.get("SMTP_USER", "")
SMTP_PASSWORD = os.environ.get("SMTP_PASSWORD", "")
SMTP_MAIL_FROM = os.environ.get("SMTP_MAIL_FROM", "")
# 日志
LOG_LEVEL = "INFO"
# 反向代理
ENABLE_PROXY_FIX = True
PYTHON_EOF
sudo chown superset:superset /opt/superset/etc/superset_config.py
```
### 4.3 创建目录结构
```bash
sudo su - superset -c "
mkdir -p /opt/superset/{uploads,images,logs,celery}
mkdir -p /opt/superset/logs/{celery,nginx}
"
```
### 4.4 初始化Superset数据库
```bash
sudo su - superset -c "
source /opt/superset/venv/bin/activate
export SUPERSET_CONFIG_PATH=/opt/superset/etc/superset_config.py
export FLASK_APP=superset
# 数据库迁移
superset db upgrade
# 初始化
superset init
# 创建管理员(密码请修改)
superset fab create-admin \
--username admin \
--firstname Admin \
--lastname User \
--email admin@example.com \
--password 'YourSecureAdminPass123!'
"
```
---
## 第五阶段:Systemd服务配置(关键修复)
### 5.1 Superset Web服务(使用正确路径)
```bash
sudo tee /etc/systemd/system/superset.service << 'EOF'
[Unit]
Description=Apache Superset Web Server
After=network.target postgresql-17.service redis.service
Requires=postgresql-17.service redis.service
[Service]
Type=simple
User=superset
Group=superset
WorkingDirectory=/opt/superset
Environment="PATH=/opt/superset/venv/bin:/usr/local/bin:/usr/bin:/bin"
Environment="SUPERSET_CONFIG_PATH=/opt/superset/etc/superset_config.py"
Environment="FLASK_APP=superset"
Environment="PYTHONPATH=/opt/superset/etc"
# 关键:使用正确的虚拟环境路径
ExecStart=/opt/superset/venv/bin/gunicorn \
--workers 4 \
--worker-class gthread \
--threads 4 \
--timeout 120 \
--keep-alive 5 \
--max-requests 1000 \
--max-requests-jitter 50 \
--bind 127.0.0.1:8088 \
--access-logfile /opt/superset/logs/access.log \
--error-logfile /opt/superset/logs/error.log \
--capture-output \
--enable-stdio-inheritance \
'superset.app:create_app()'
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
```
### 5.2 Celery Worker服务
```bash
sudo tee /etc/systemd/system/superset-worker.service << 'EOF'
[Unit]
Description=Apache Superset Celery Worker
After=network.target postgresql-17.service redis.service
[Service]
Type=simple
User=superset
Group=superset
WorkingDirectory=/opt/superset
Environment="PATH=/opt/superset/venv/bin:/usr/local/bin:/usr/bin:/bin"
Environment="SUPERSET_CONFIG_PATH=/opt/superset/etc/superset_config.py"
Environment="FLASK_APP=superset"
Environment="PYTHONPATH=/opt/superset/etc"
ExecStart=/opt/superset/venv/bin/celery \
--app=superset.tasks.celery_app:app worker \
--pool=gevent \
--concurrency=4 \
--loglevel=INFO \
--logfile=/opt/superset/logs/celery/worker.log \
--pidfile=/tmp/celery-worker.pid
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
```
### 5.3 Celery Beat服务
```bash
sudo tee /etc/systemd/system/superset-beat.service << 'EOF'
[Unit]
Description=Apache Superset Celery Beat
After=network.target postgresql-17.service redis.service
[Service]
Type=simple
User=superset
Group=superset
WorkingDirectory=/opt/superset
Environment="PATH=/opt/superset/venv/bin:/usr/local/bin:/usr/bin:/bin"
Environment="SUPERSET_CONFIG_PATH=/opt/superset/etc/superset_config.py"
ExecStart=/opt/superset/venv/bin/celery \
--app=superset.tasks.celery_app:app beat \
--loglevel=INFO \
--logfile=/opt/superset/logs/celery/beat.log \
--pidfile=/tmp/celerybeat.pid \
--schedule=/opt/superset/celery/celerybeat-schedule
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
```
### 5.4 启动服务
```bash
sudo systemctl daemon-reload
sudo systemctl enable superset superset-worker superset-beat
sudo systemctl start superset superset-worker superset-beat
# 验证状态
sudo systemctl status superset
sudo journalctl -fu superset -n 50
```
---
## 第六阶段:Nginx配置(静态文件修复关键)
### 6.1 安装Nginx
```bash
sudo dnf install -y nginx
sudo systemctl enable nginx
```
### 6.2 关键:复制静态文件到Nginx可访问目录
```bash
# 1. 创建Nginx静态文件目录
sudo mkdir -p /var/www/superset/static
# 2. 复制静态文件(关键修复步骤)
sudo cp -r /opt/superset/venv/lib/python3.11/site-packages/superset/static/* /var/www/superset/static/
# 3. 设置正确权限(Nginx用户可读)
sudo chown -R nginx:nginx /var/www/superset
sudo chmod -R 755 /var/www/superset
# 4. 创建同步脚本(升级Superset时使用)
sudo tee /usr/local/bin/sync-superset-static << 'EOF'
#!/bin/bash
# 同步Superset静态文件到Nginx目录
cp -r /opt/superset/venv/lib/python3.11/site-packages/superset/static/* /var/www/superset/static/
chown -R nginx:nginx /var/www/superset
chmod -R 755 /var/www/superset
systemctl reload nginx
echo "Static files synced at $(date)"
EOF
sudo chmod +x /usr/local/bin/sync-superset-static
```
### 6.3 Nginx生产配置
```bash
sudo tee /etc/nginx/conf.d/superset.conf << 'EOF'
upstream superset_backend {
server 127.0.0.1:8088;
keepalive 32;
}
server {
listen 80;
server_name _;
# 关键:静态文件直接从Nginx服务(避免403错误)
location /static {
alias /var/www/superset/static;
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
# 确保文件存在才返回
try_files $uri $uri/ =404;
}
# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 其他请求代理给Superset
location / {
proxy_pass http://superset_backend;
proxy_http_version 1.1;
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_buffering off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_connect_timeout 60s;
client_max_body_size 50M;
}
}
EOF
# 测试并重载
sudo nginx -t
sudo systemctl start nginx
```
### 6.4 HTTPS配置(Let's Encrypt)
```bash
# 安装Certbot
sudo dnf install -y certbot python3-certbot-nginx
# 申请证书
sudo certbot --nginx -d superset.yourdomain.com
# 自动续期
sudo systemctl enable certbot-renew.timer
```
---
## 第七阶段:备份与维护
### 7.1 自动备份脚本
```bash
sudo tee /opt/superset/backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/opt/superset/backups"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
mkdir -p $BACKUP_DIR
# 备份PostgreSQL
sudo -u postgres pg_dump -U superset superset | gzip > $BACKUP_DIR/superset_db_$DATE.sql.gz
# 备份配置
tar -czf $BACKUP_DIR/superset_config_$DATE.tar.gz -C /opt/superset etc uploads images
# 清理旧备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $DATE"
EOF
sudo chmod +x /opt/superset/backup.sh
# 定时任务
sudo tee /etc/cron.d/superset-backup << 'EOF'
0 2 * * * superset /opt/superset/backup.sh >> /var/log/superset-backup.log 2>&1
EOF
```
### 7.2 升级脚本
```bash
sudo tee /opt/superset/upgrade.sh << 'EOF'
#!/bin/bash
set -e
echo "=== Superset Upgrade ==="
# 1. 备份
/opt/superset/backup.sh
# 2. 停止服务
sudo systemctl stop superset superset-worker superset-beat
# 3. 升级
sudo su - superset -c "
source /opt/superset/venv/bin/activate
pip install --upgrade apache-superset
deactivate
"
# 4. 数据库迁移
sudo su - superset -c "
source /opt/superset/venv/bin/activate
export SUPERSET_CONFIG_PATH=/opt/superset/etc/superset_config.py
superset db upgrade
superset init
deactivate
"
# 5. 同步静态文件
sudo /usr/local/bin/sync-superset-static
# 6. 启动服务
sudo systemctl start superset superset-worker superset-beat
echo "Upgrade completed!"
EOF
sudo chmod +x /opt/superset/upgrade.sh
```
---
## 验证检查清单
```bash
# 1. 服务状态
sudo systemctl status superset
sudo systemctl status nginx
# 2. 静态文件访问(关键测试)
curl -I http://localhost/static/assets/manifest.json
# 应返回 200 OK
# 3. 应用访问
curl http://localhost/health
# 4. 日志检查
sudo tail -20 /var/log/nginx/error.log
sudo tail -20 /opt/superset/logs/error.log
# 5. 数据库连接
sudo -u superset /opt/superset/venv/bin/superset db upgrade --check
```
---