#!/bin/bash
# 设置路径变量
NEXTCLOUD_ROOT="/var/www/nextcloud"
NGINX_CONF_DIR="/etc/nginx/conf.d"
PHP_CONF_DIR="/etc/php"
MYSQL_CONF_DIR="/etc/mysql"
INSTALL_LOG="/var/log/nextcloud_install.log"
# 设置变量
MYSQL_ROOT_PASSWORD="Abner@2024.12"
NEXTCLOUD_DB_PASSWORD="Abner@2024.12"
DOMAIN_NAME="Abner.com"
# 启用日志记录
exec 1> >(tee -a ${INSTALL_LOG})
exec 2>&1
echo "开始安装 $(date '+%Y-%m-%d %H:%M:%S')" | tee -a ${INSTALL_LOG}
# 错误处理函数增强
check_error() {
local exit_code=$?
local error_message=$1
if [ $exit_code -ne 0 ]; then
echo "错误:${error_message}. 退出代码: ${exit_code}" | tee -a ${INSTALL_LOG}
exit $exit_code
fi
}
# 清理函数
cleanup() {
local exit_code=$?
echo "执行清理..." | tee -a ${INSTALL_LOG}
# 删除临时文件
rm -f /tmp/nextcloud-*.zip
if [ $exit_code -ne 0 ]; then
echo "脚本因错误终止,退出代码: $exit_code" | tee -a ${INSTALL_LOG}
fi
}
# 注册信号处理
trap cleanup EXIT
trap 'echo "收到中断信号,正在清理..."; cleanup; exit 1' INT TERM
# 设置PATH
export PATH=$PATH:/usr/sbin:/sbin
# 清理旧的源配置
echo "正在清理旧的源配置..."
rm -f /etc/apt/sources.list.d/php.list
rm -f /etc/apt/sources.list.d/sury-php.list
rm -f /etc/apt/sources.list.d/*.save
# 配置国内源
echo "正在配置国内源..."
cat > /etc/apt/sources.list <<EOF
deb https://mirrors.aliyun.com/debian/ bookworm main non-free-firmware non-free contrib
deb https://mirrors.aliyun.com/debian/ bookworm-updates main non-free-firmware non-free contrib
deb https://mirrors.aliyun.com/debian/ bookworm-backports main non-free-firmware non-free contrib
deb https://mirrors.aliyun.com/debian-security bookworm-security main non-free-firmware non-free contrib
EOF
# 更新系统
echo "正在更新系统..."
apt clean
apt update && apt upgrade -y
if [ $? -ne 0 ]; then
echo "尝试修复未满足的依赖关系..."
apt --fix-broken install -y
apt update && apt upgrade -y
check_error "系统更新失败"
fi
# 自动安装必要的依赖
apt install sudo -y
apt install curl -y
apt install wget -y
# 安装基本工具
apt install -y net-tools
check_error "基本工具安装失败"
# 自动获取最新版本号
echo "正在获取Nextcloud最新版本..."
LATEST_VERSION=$(curl -s https://download.nextcloud.com/server/releases/ | grep -oP 'nextcloud-[0-9]+\.[0-9]+\.[0-9]+\.zip' | sort -V | tail -n 1 | grep -oP '[0-9]+\.[0-9]+\.[0-9]+')
check_error "获取最新版本失败"
echo "检测到Nextcloud最新版本为: $LATEST_VERSION"
# 检查端口占用
echo "检查80和443端口..."
if netstat -tuln | grep -q ':80\|:443'; then
echo "警告:端口80或443已被占用"
netstat -tuln | grep ':80\|:443'
echo "正在尝试停止占用端口的服务..."
systemctl stop apache2 2>/dev/null
fi
# 卸载Apache(如果存在)
echo "正在卸载Apache..."
apt remove --purge -y apache2* libapache2-mod-php*
apt autoremove -y
rm -rf /etc/apache2
check_error "Apache卸载失败"
# 完全重新安装Nginx
echo "正在安装Nginx..."
apt remove --purge -y nginx nginx-common nginx-full
apt autoremove -y
apt clean
# 确保所有必要的目录存在
mkdir -p /etc/nginx
mkdir -p /var/log/nginx
mkdir -p /var/www/html
# 更新软件包列表并安装Nginx
apt update
DEBIAN_FRONTEND=noninteractive apt install -y nginx nginx-full nginx-common
check_error "Nginx安装失败"
# 验证Nginx安装
if [ ! -f /usr/sbin/nginx ]; then
echo "错误:Nginx可执行文件未找到"
exit 1
fi
# 验证Nginx状态
systemctl enable nginx
systemctl start nginx
if ! systemctl is-active nginx >/dev/null 2>&1; then
echo "错误:Nginx服务未能启动"
systemctl status nginx
exit 1
fi
# 测试Nginx配置
nginx -t
check_error "Nginx配置测试失败"
echo "Nginx安装和配置成功!"
# 安装MariaDB
echo "正在重新安装MariaDB..."
# Debian特定的清理命令
systemctl stop mysql mariadb || true
apt-get remove --purge -y mysql* mariadb* galera* || true
apt autoremove --purge -y
apt-get clean
# 彻底清理配置文件和目录
rm -rf /etc/mysql /var/lib/mysql* /var/log/mysql* /run/mysqld
rm -rf /etc/alternatives/my.cnf /etc/alternatives/mariadb.cnf
rm -rf /var/lib/dpkg/info/mariadb* /var/lib/dpkg/info/mysql*
# 修复包管理系统
apt-get update
apt-get install -f
dpkg --configure -a
apt-get clean
rm -rf /var/lib/apt/lists/*
apt-get update
# 修复未满足的依赖关系
echo "尝试修复未满足的依赖关系..."
apt --fix-broken install -y
apt-get update
# 创建必要的目录
mkdir -p /etc/mysql/mariadb.conf.d
mkdir -p /var/log/mysql
mkdir -p /var/run/mysqld
mkdir -p /etc/alternatives
# 创建默认配置文件
cat > /etc/mysql/mariadb.cnf <<EOF
[client]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
bind-address = 127.0.0.1
socket = /run/mysqld/mysqld.sock
pid-file = /run/mysqld/mysqld.pid
[mysql]
default-character-set = utf8mb4
EOF
# 创建符号链接
ln -sf /etc/mysql/mariadb.cnf /etc/alternatives/mariadb.cnf
# 设置目录权限
chown -R mysql:mysql /var/log/mysql
chown -R mysql:mysql /var/run/mysqld
chmod 755 /var/log/mysql
chmod 755 /var/run/mysqld
# 按顺序安装包
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server
sleep 2
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-common
sleep 2
DEBIAN_FRONTEND=noninteractive apt-get install -y libmariadb3
sleep 2
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-client-core
sleep 2
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-client
sleep 2
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server-core
sleep 2
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-plugin-provider-bzip2 mariadb-plugin-provider-lz4 mariadb-plugin-provider-lzma mariadb-plugin-provider-lzo mariadb-plugin-provider-snappy
# 确保服务启动
systemctl enable mariadb
systemctl start mariadb
sleep 5
# 初始化数据库
mysql_install_db --user=mysql --datadir=/var/lib/mysql || true
# 设置root密码
mysqladmin -u root password "$MYSQL_ROOT_PASSWORD" || true
# 创建nextcloud数据库和用户
mysql -u root -p"$MYSQL_ROOT_PASSWORD" <<EOF || true
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS 'nextcloud'@'localhost' IDENTIFIED BY '$NEXTCLOUD_DB_PASSWORD';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;
EOF
# 安装PHP和扩展
echo "正在安装PHP和扩展..."
apt --fix-broken install -y
apt install -y php php-fpm php-mysql \
php-common php-gd php-curl php-zip \
php-xml php-mbstring php-bz2 php-intl php-bcmath \
php-gmp php-redis php-imagick php-apcu \
unzip wget ssl-cert
check_error "PHP及其扩展安装失败"
# 安装额外的PHP模块
echo "安装额外的PHP模块..."
apt install -y \
php-intl php-imagick php-json php-ldap \
php-mbstring php-mysql php-gd php-xml php-zip \
php-curl php-fileinfo php-bz2 php-bcmath \
php-gmp php-apcu php-redis php-igbinary \
php-imap php-memcache php-pear php-ssh2 \
php-tidy php-xmlrpc php-common
# 显示安装的PHP版本
echo "已安装的PHP版本:"
php -v
PHP_VERSION=$(php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;")
# 保留一个完整的PHP-FPM配置(删除其他重复的配置)
echo "配置PHP-FPM..."
cat > /etc/php/$PHP_VERSION/fpm/pool.d/www.conf <<EOF
[www]
user = www-data
group = www-data
listen = /var/run/php/php$PHP_VERSION-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
; 进程管理优化
pm = dynamic
pm.max_children = 200
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 1000
; 性能优化
pm.process_idle_timeout = 10s
request_terminate_timeout = 300
rlimit_files = 65535
; 调试和错误日志
php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php$PHP_VERSION-fpm.log
php_admin_value[memory_limit] = 1024M
php_admin_value[upload_max_filesize] = 1024M
php_admin_value[post_max_size] = 1024M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_time] = 300
; 会话设置
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/sessions
; 环境变量
clear_env = no
env[HOSTNAME] = \$HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
EOF
# 确保目录存在并设置正确权限
mkdir -p /var/run/php
mkdir -p /var/log/php
mkdir -p /var/lib/php/sessions
chown -R www-data:www-data /var/run/php
chown -R www-data:www-data /var/log/php
chown -R www-data:www-data /var/lib/php/sessions
chmod 755 /var/run/php
chmod 755 /var/log/php
chmod 1733 /var/lib/php/sessions
# 验证配置
echo "验证PHP-FPM配置..."
php-fpm$PHP_VERSION -t
# 重启PHP-FPM服务
echo "重启PHP-FPM服务..."
systemctl stop php$PHP_VERSION-fpm
sleep 2
systemctl start php$PHP_VERSION-fpm
# 等待服务启动并验证状态
sleep 2
if ! systemctl is-active php$PHP_VERSION-fpm >/dev/null 2>&1; then
echo "PHP-FPM启动失败,查看日志..."
journalctl -xe --unit=php$PHP_VERSION-fpm.service
exit 1
fi
# 验证安装
echo "正在验证安装..."
echo "验证安装环境..."
echo "Nginx版本: $(nginx -v 2>&1)"
echo "PHP版本: $(php -v | head -n1)"
echo "MariaDB版本: $(mariadb --version)"
echo "系统路径: $PATH"
# 定义变量
MAX_RETRIES=3
NEXTCLOUD_ZIP="nextcloud-${LATEST_VERSION}.zip"
NEXTCLOUD_PATH="/tmp/${NEXTCLOUD_ZIP}"
DOWNLOAD_URL="https://download.nextcloud.com/server/releases/${NEXTCLOUD_ZIP}"
# 优化下载函数
download_and_verify() {
local attempt=1
local MAX_RETRIES=3
while [ $attempt -le $MAX_RETRIES ]; do
echo "下载尝试 $attempt/$MAX_RETRIES..."
wget --progress=bar:force --continue \
--tries=3 --timeout=30 \
-O "$NEXTCLOUD_PATH" "$DOWNLOAD_URL"
# 检查下载是否成功
if [ $? -eq 0 ] && [ -f "$NEXTCLOUD_PATH" ]; then
local file_size=$(stat -c%s "$NEXTCLOUD_PATH" 2>/dev/null)
if [ ! -z "$file_size" ] && [ "$file_size" -gt 1048576 ]; then
echo "验证文件完整性..."
if unzip -t "$NEXTCLOUD_PATH" >/dev/null 2>&1; then
echo "文件验证通过"
return 0
fi
fi
fi
echo "尝试使用备用下载源..."
local mirrors=(
"https://download.nextcloud.com/server/releases/"
"https://mirrors.tuna.tsinghua.edu.cn/nextcloud/server/releases/"
"https://mirrors.ustc.edu.cn/nextcloud/server/releases/"
)
for mirror in "${mirrors[@]}"; do
echo "尝试从 $mirror 下载..."
wget --progress=bar:force --continue \
--tries=3 --timeout=30 \
-O "$NEXTCLOUD_PATH" "${mirror}${NEXTCLOUD_ZIP}"
if [ $? -eq 0 ] && [ -f "$NEXTCLOUD_PATH" ]; then
local file_size=$(stat -c%s "$NEXTCLOUD_PATH" 2>/dev/null)
if [ ! -z "$file_size" ] && [ "$file_size" -gt 1048576 ]; then
if unzip -t "$NEXTCLOUD_PATH" >/dev/null 2>&1; then
echo "从镜像站下载成功"
return 0
fi
fi
fi
done
rm -f "$NEXTCLOUD_PATH"
attempt=$((attempt + 1))
sleep 2
done
return 1
}
# 替换原有的下载验证代码
echo "正在准备下载 Nextcloud $LATEST_VERSION..."
if [ -f "$NEXTCLOUD_PATH" ]; then
echo "发现已存在的下载文件,验证完整性..."
file_size=$(stat -c%s "$NEXTCLOUD_PATH" 2>/dev/null)
if [ ! -z "$file_size" ] && [ "$file_size" -gt 1048576 ] && unzip -t "$NEXTCLOUD_PATH" >/dev/null 2>&1; then
echo "现有文件验证通过,跳过下载"
else
echo "现有文件已损坏,重新下载..."
rm -f "$NEXTCLOUD_PATH"
if ! download_and_verify; then
echo "下载失败,请检查网络连接"
exit 1
fi
fi
else
if ! download_and_verify; then
echo "下载失败,请检查网络连接"
exit 1
fi
fi
# 在解压之前创建和设置数据目录权限
echo "创建和设置数据目录权限..."
mkdir -p /var/www/nextcloud
mkdir -p /var/www/nextcloud/{data,config,apps,apps-external}
chown -R www-data:www-data /var/www/nextcloud
chmod -R 0750 /var/www/nextcloud
chmod -R 0770 /var/www/nextcloud/{data,config,apps,apps-external}
check_error "数据目录创建失败"
# SELinux 配置(如果启用)
if command -v semanage >/dev/null 2>&1; then
echo "配置 SELinux 规则..."
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud(/.*)?'
restorecon -Rv '/var/www/nextcloud/'
check_error "SELinux 配置失败"
fi
# 替换原有的 Nextcloud 解压和权限设置部分
echo "解压和设置 Nextcloud..."
cd /tmp
unzip -q "$NEXTCLOUD_ZIP"
check_error "Nextcloud 解压失败"
# 移动文件时保留权限
echo "移动 Nextcloud 文件..."
rsync -a --remove-source-files nextcloud/ /var/www/nextcloud/
check_error "文件移动失败"
# 设置文件权限(一次性设置)
echo "设置最终权限..."
find /var/www/nextcloud/ -type f -print0 | xargs -0 chmod 0640
find /var/www/nextcloud/ -type d -print0 | xargs -0 chmod 0750
chmod -R 0770 /var/www/nextcloud/{data,config,apps,apps-external}
chown -R www-data:www-data /var/www/nextcloud
check_error "权限设置失败"
# 保留一个完整的Nextcloud配置文件(删除重复的config.php配置)
echo "创建Nextcloud配置..."
cat > /var/www/nextcloud/config/config.php <<EOF
<?php
\$CONFIG = array (
'trusted_domains' => array(
0 => '$DOMAIN_NAME',
1 => 'localhost',
),
'datadirectory' => '/var/www/nextcloud/data',
'overwrite.cli.url' => 'https://$DOMAIN_NAME',
'htaccess.RewriteBase' => '/',
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => array(
'host' => '/var/run/redis/redis-server.sock',
'port' => 0,
'timeout' => 0.0,
),
'maintenance' => false,
'theme' => '',
'loglevel' => 2,
);
EOF
chown www-data:www-data /var/www/nextcloud/config/config.php
chmod 0640 /var/www/nextcloud/config/config.php
check_error "配置文件创建失败"
# 检查关键目录权限
echo "验证关键目录权限..."
for dir in data config apps; do
if [ ! -w "/var/www/nextcloud/$dir" ]; then
echo "警告:目录 /var/www/nextcloud/$dir 不可写"
ls -ld "/var/www/nextcloud/$dir"
fi
done
# 保留一个完整的PHP优化配置(删除重复的99-nextcloud.ini配置)
echo "配置PHP优化参数..."
cat > /etc/php/$PHP_VERSION/fpm/conf.d/99-nextcloud.ini <<EOF
; 内存和上传限制
memory_limit = 1024M
upload_max_filesize = 1024M
post_max_size = 1024M
max_execution_time = 3600
max_input_time = 3600
; OPcache设置
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 512
opcache.interned_strings_buffer = 32
opcache.max_accelerated_files = 15000
opcache.save_comments = 1
opcache.revalidate_freq = 1
; APCu设置
apc.enable_cli = 1
apc.shm_size = 256M
; 会话设置
session.save_handler = files
session.save_path = /var/lib/php/sessions
; 其他优化设置
output_buffering = 0
date.timezone = Asia/Shanghai
EOF
# 在配置Nginx之前,添加SSL证书生成
echo "生成SSL证书..."
# 生成强DH参数
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
# 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/nextcloud.key \
-out /etc/ssl/certs/nextcloud.crt \
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=NextCloud/CN=$DOMAIN_NAME"
# 配置Nginx
echo "正在配置Nginx..."
cat > /etc/nginx/conf.d/nextcloud.conf <<'EOF'
upstream php-handler {
server unix:/var/run/php/php$PHP_VERSION-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name $DOMAIN_NAME;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name $DOMAIN_NAME;
# SSL配置
ssl_certificate /etc/ssl/certs/nextcloud.crt;
ssl_certificate_key /etc/ssl/private/nextcloud.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# 安全响应头配置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header X-Download-Options "noopen" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Frame-Options "SAMEORIGIN" always;
fastcgi_hide_header X-Powered-By;
fastcgi_hide_header X-Runtime;
# 基础配置
root /var/www/nextcloud;
index index.php index.html /index.php$request_uri;
client_max_body_size 512M;
fastcgi_buffers 64 4K;
server_tokens off;
include mime.types;
types {
text/javascript mjs;
application/wasm wasm;
}
# 目录规则
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
try_files $uri $uri/ /index.php$request_uri;
}
# robots.txt 规则
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# .well-known 目录处理
location ^~ /.well-known {
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
return 301 /index.php$request_uri;
}
# 保护系统文件
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# PHP文件处理
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_max_temp_file_size 0;
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
# 超时设置
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
}
# 静态文件处理
location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
access_log off;
location ~ \.wasm$ {
default_type application/wasm;
}
}
# 字体文件处理
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
expires 7d;
access_log off;
}
# remote 路径处理
location /remote {
return 301 /remote.php$request_uri;
}
# 更新器和提供程序
location ~ ^/(?:updater|oc[ms]-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
# 默认路由
location / {
try_files $uri $uri/ /index.php$request_uri;
}
# OCM & OCS Provider support
location ^~ /ocm-provider {
try_files \$uri \$uri/ /index.php\$request_uri;
}
location ^~ /ocs-provider {
try_files \$uri \$uri/ /index.php\$request_uri;
}
}
EOF
# 替换配置文件中的变量
sed -i "s/\$DOMAIN_NAME/$DOMAIN_NAME/g" /etc/nginx/conf.d/nextcloud.conf
sed -i "s/\$PHP_VERSION/$PHP_VERSION/g" /etc/nginx/conf.d/nextcloud.conf
# 检查Nginx配置语法
echo "检查Nginx配置..."
nginx -t
if [ $? -ne 0 ]; then
echo "Nginx配置验证失败,正在回滚..."
if [ -f /etc/nginx/conf.d/nextcloud.conf.bak ]; then
mv /etc/nginx/conf.d/nextcloud.conf.bak /etc/nginx/conf.d/nextcloud.conf
fi
exit 1
fi
# 重启Nginx
echo "重启Nginx服务..."
systemctl restart nginx
if [ $? -ne 0 ]; then
echo "Nginx重启失败,查看错误日志..."
journalctl -xe --unit=nginx.service
exit 1
fi
# 安装Redis服务器前先确保清理旧的进程和配置
echo "准备安装Redis..."
# 使用pkill安全地停止Redis进程
pkill -9 redis-server || true
rm -f /var/run/redis/redis-server.pid || true
rm -f /var/run/redis/redis.sock || true
# 安装Redis服务器
echo "安装Redis服务器..."
DEBIAN_FRONTEND=noninteractive apt install -y redis-server redis-tools || {
echo "Redis安装失败,尝试修复依赖..."
apt --fix-broken install -y
DEBIAN_FRONTEND=noninteractive apt install -y redis-server redis-tools
}
# 配置Redis
echo "配置Redis..."
# 备份原配置
cp /etc/redis/redis.conf /etc/redis/redis.conf.bak || true
# 写入新配置
cat > /etc/redis/redis.conf <<EOF
bind 127.0.0.1
port 0
unixsocket /var/run/redis/redis-server.sock
unixsocketperm 770
maxmemory 512mb
maxmemory-policy allkeys-lru
daemonize yes
supervised systemd
stop-writes-on-bgsave-error no
EOF
# Redis 权限配置
echo "配置 Redis 权限..."
mkdir -p /var/run/redis
chown redis:redis /var/run/redis
chmod 775 /var/run/redis
usermod -a -G redis www-data
check_error "Redis 权限配置失败"
# 将www-data用户添加到redis组
usermod -a -G redis www-data
# 使用kill命令确保Redis进程已停止
redis_pid=$(pgrep redis-server) || true
if [ ! -z "$redis_pid" ]; then
echo "强制停止Redis进程..."
kill -9 $redis_pid || true
fi
# 启动Redis服务(使用直接命令而不是systemctl)
echo "启动Redis服务..."
/usr/bin/redis-server /etc/redis/redis.conf
# 等待Redis启动(使用redis-cli检查)
echo "等待Redis服务就绪..."
for i in {1..10}; do
if redis-cli -s /var/run/redis/redis-server.sock ping >/dev/null 2>&1; then
echo "Redis服务已启动"
break
fi
echo "等待Redis启动... $i/10"
sleep 1
done
# 设置开机自启
systemctl enable redis-server || true
# 验证 Redis 访问权限
echo "验证 Redis 访问权限..."
sudo -u www-data redis-cli -s /var/run/redis/redis-server.sock ping
check_error "Redis 访问测试失败"
# 配置Nextcloud Redis集成
echo "配置Nextcloud Redis集成..."
mkdir -p /var/www/nextcloud/config
# 添加Nextcloud Redis配置
cat > /var/www/nextcloud/config/redis.config.php <<EOF
<?php
\$CONFIG = array (
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' => array(
'host' => '/var/run/redis/redis-server.sock',
'port' => 0,
'timeout' => 0.0,
),
);
EOF
# 设置配置文件权限
chown -R www-data:www-data /var/www/nextcloud/config
chmod 660 /var/www/nextcloud/config/redis.config.php
# 最后重启PHP-FPM和Nginx(不重启Redis)
echo "重启Web服务..."
systemctl restart php$PHP_VERSION-fpm || true
sleep 2
systemctl restart nginx || true
# 配置PHP优化参数
echo "配置PHP优化参数..."
cat > /etc/php/$PHP_VERSION/fpm/conf.d/99-nextcloud-recommended.ini <<EOF
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.memory_consumption=256
opcache.save_comments=1
opcache.revalidate_freq=1
apc.enable_cli=1
memory_limit=512M
upload_max_filesize=512M
post_max_size=512M
max_execution_time=300
max_input_time=300
pm.max_children=50
pm.start_servers=5
pm.min_spare_servers=5
pm.max_spare_servers=35
EOF
# 最后重启所有服务(修改重启方式)
echo "重启所有服务..."
# 重启PHP-FPM
echo "重启 PHP-FPM..."
systemctl restart php$PHP_VERSION-fpm || true
sleep 2
# 重启Redis(使用进程控制而不是systemctl)
echo "重启 Redis..."
# 停止Redis
pkill -F /var/run/redis/redis-server.pid 2>/dev/null || true
pkill redis-server 2>/dev/null || true
sleep 2
# 清理旧的socket和pid文件
rm -f /var/run/redis/redis-server.sock
rm -f /var/run/redis/redis-server.pid
# 以redis用户身份启动Redis
echo "启动Redis服务..."
su - redis -s /bin/bash -c '/usr/bin/redis-server /etc/redis/redis.conf'
sleep 2
# 验证Redis是否运行
if redis-cli -s /var/run/redis/redis-server.sock ping >/dev/null 2>&1; then
echo "Redis已成功重启"
else
echo "警告:Redis可能未正常启动"
fi
# 重启Nginx
echo "重启 Nginx..."
systemctl restart nginx || true
sleep 2
# 验证服务状态
echo "验证服务状态..."
echo "PHP-FPM状态: $(systemctl is-active php$PHP_VERSION-fpm)"
echo "Nginx状态: $(systemctl is-active nginx)"
echo "MariaDB状态: $(systemctl is-active mariadb)"
echo "Redis状态: "
if redis-cli -s /var/run/redis/redis-server.sock ping >/dev/null 2>&1; then
echo "Redis运行正常"
else
echo "Redis运行异常"
fi
# 验证服务状态
echo "正在验证服务状态..."
systemctl is-active php$PHP_VERSION-fpm >/dev/null 2>&1 && echo "PHP-FPM 运行正常" || echo "PHP-FPM 运行异常"
systemctl is-active nginx >/dev/null 2>&1 && echo "Nginx 运行正常" || echo "Nginx 运行异常"
systemctl is-active mariadb >/dev/null 2>&1 && echo "MariaDB 运行正常" || echo "MariaDB 运行异常"
systemctl is-active redis-server >/dev/null 2>&1 && echo "Redis 运行正常" || echo "Redis 运行异常"
# 清理下载文件
echo "清理安装文件..."
rm -f nextcloud-$LATEST_VERSION.zip*
# 添加502错误修复步骤(在安装完成后添加)
echo "执行502错误修复步骤..."
# 1. 确保PHP-FPM配置正确
echo "更新PHP-FPM配置..."
cat > /etc/php/$PHP_VERSION/fpm/pool.d/www.conf <<EOF
[www]
user = www-data
group = www-data
listen = /var/run/php/php$PHP_VERSION-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
; 调试设置
php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php$PHP_VERSION-fpm.log
php_admin_value[memory_limit] = 512M
php_admin_value[upload_max_filesize] = 512M
php_admin_value[post_max_size] = 512M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_time] = 300
; 会话设置
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/sessions
; 环境变量
clear_env = no
env[HOSTNAME] = \$HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
EOF
# 2. 修复权限
echo "修复关键目录权限..."
chown -R www-data:www-data /var/www/nextcloud
find /var/www/nextcloud/ -type f -exec chmod 644 {} \;
find /var/www/nextcloud/ -type d -exec chmod 755 {} \;
chmod -R 770 /var/www/nextcloud/data
chmod -R 770 /var/www/nextcloud/config
chmod -R 770 /var/www/nextcloud/apps
# 3. 确保PHP-FPM socket目录存在并权限正确
mkdir -p /var/run/php
chown -R www-data:www-data /var/run/php
chmod 755 /var/run/php
# 4. 创建并设置日志文件
touch /var/log/php$PHP_VERSION-fpm.log
chown www-data:www-data /var/log/php$PHP_VERSION-fpm.log
chmod 660 /var/log/php$PHP_VERSION-fpm.log
# 5. 更新Nginx配置中的fastcgi设置
sed -i '/fastcgi_pass/c\ fastcgi_pass unix:/var/run/php/php'"$PHP_VERSION"'-fpm.sock;' /etc/nginx/conf.d/nextcloud.conf
# 6. 重启服务
echo "重启服务..."
systemctl daemon-reload
systemctl restart php$PHP_VERSION-fpm
systemctl restart nginx
# 7. 验证服务状态
echo "验证服务状态..."
echo "PHP-FPM socket文件:"
ls -l /var/run/php/php$PHP_VERSION-fpm.sock
echo "PHP-FPM状态:"
systemctl status php$PHP_VERSION-fpm --no-pager
echo "Nginx状态:"
systemctl status nginx --no-pager
echo "最新的PHP-FPM错误日志:"
tail -n 20 /var/log/php$PHP_VERSION-fpm.log
echo "最新的Nginx错误日志:"
tail -n 20 /var/log/nginx/error.log
# 优化系统限制
echo "配置系统限制..."
cat >> /etc/security/limits.conf <<EOF
www-data soft nofile 65535
www-data hard nofile 65535
EOF
# 添加 403 错误修复步骤
echo "执行403错误修复步骤..."
# 1. 修正目录权限
echo "修正目录权限..."
find /var/www/nextcloud/ -type f -print0 | xargs -0 chmod 0640
find /var/www/nextcloud/ -type d -print0 | xargs -0 chmod 0750
chown -R www-data:www-data /var/www/nextcloud
# 2. 特殊目录权限设置
chmod -R 0770 /var/www/nextcloud/config
chmod -R 0770 /var/www/nextcloud/apps
chmod -R 0770 /var/www/nextcloud/data
# 3. 确保data目录存在
mkdir -p /var/www/nextcloud/data
chown -R www-data:www-data /var/www/nextcloud/data
chmod 0770 /var/www/nextcloud/data
# 4. 确保SELinux配置(如果启用)
if command -v semanage >/dev/null 2>&1; then
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/data(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/config(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/apps(/.*)?'
restorecon -R '/var/www/nextcloud/'
fi
# 5. 创建初始配置文件
cat > /var/www/nextcloud/config/config.php <<EOF
<?php
\$CONFIG = array (
'trusted_domains' =>
array (
0 => '$DOMAIN_NAME',
1 => 'localhost',
),
'datadirectory' => '/var/www/nextcloud/data',
'overwrite.cli.url' => 'https://$DOMAIN_NAME',
'htaccess.RewriteBase' => '/',
);
EOF
# 6. 设置正确的配置文件权限
chown www-data:www-data /var/www/nextcloud/config/config.php
chmod 0640 /var/www/nextcloud/config/config.php
# 安装完成标记
echo "创建安装完成标记..."
touch /var/www/nextcloud/.installation_successful
chown www-data:www-data /var/www/nextcloud/.installation_successful
echo "==================================================="
echo "所有安装和配置步骤已完成!"
echo "Nextcloud安装和优化已全部完成"
echo "请访问 https://$DOMAIN_NAME 检查系统状态"
echo "修复完成,请刷新Nextcloud页面查看效果"
echo "如有问题欢迎关注公众号“大刘讲IT”反馈"
echo "==================================================="
安装完成后nextcloud各类报错修复脚本
#!/bin/bash
# 设置变量
NEXTCLOUD_DIR="/var/www/nextcloud"
DOMAIN_NAME=$(grep -oP "(?<=overwrite\.cli\.url' => 'https://).*(?=')" $NEXTCLOUD_DIR/config/config.php)
OCC="sudo -u www-data php $NEXTCLOUD_DIR/occ"
PHP_VERSION=$(php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;")
# 检查root权限
if [ "$(id -u)" != "0" ]; then
echo "此脚本必须以root身份运行" 1>&2
exit 1
fi
echo "开始修复Nextcloud问题..."
# 1. 修复数据目录访问权限
echo "修复数据目录权限..."
find $NEXTCLOUD_DIR/ -type f -print0 | xargs -0 chmod 0640
find $NEXTCLOUD_DIR/ -type d -print0 | xargs -0 chmod 0750
chmod -R 0770 $NEXTCLOUD_DIR/data
chmod -R 0770 $NEXTCLOUD_DIR/config
chmod -R 0770 $NEXTCLOUD_DIR/apps
chown -R www-data:www-data $NEXTCLOUD_DIR
# 2. 修复MIME类型配置
echo "配置MIME类型支持..."
cat > /etc/nginx/conf.d/mime.types <<EOF
types {
text/javascript js;
application/javascript mjs;
application/wasm wasm;
application/json json;
application/map map;
font/otf otf;
application/x-font-ttf ttf;
application/font-woff woff;
application/font-woff2 woff2;
}
EOF
# 3. 更新Nginx配置以支持JavaScript Source Maps
echo "更新Nginx配置..."
cat > /etc/nginx/conf.d/nextcloud-additions.conf <<EOF
map \$sent_http_content_type \$expires {
default 7d;
text/html epoch;
text/css 7d;
application/javascript 7d;
application/wasm 7d;
~image/ 7d;
~font/ 7d;
}
map \$request_uri \$cache_control {
default "public, max-age=15778463";
~*\.js\.map "public, max-age=7200";
~*\.css\.map "public, max-age=7200";
}
EOF
# 4. 修复DNS解析
echo "添加本地DNS解析..."
if ! grep -q "$DOMAIN_NAME" /etc/hosts; then
echo "127.0.0.1 $DOMAIN_NAME" >> /etc/hosts
fi
# 5. 配置默认电话区号和电子邮件设置
echo "配置系统设置..."
$OCC config:system:set default_phone_region --value="CN"
# 6. 配置维护时间窗口
$OCC config:system:set maintenance_window_start --value="1"
# 7. 添加缺失的数据库索引
echo "添加缺失的数据库索引..."
$OCC db:add-missing-indices
# 8. 执行MIME类型迁移
echo "执行MIME类型迁移..."
$OCC maintenance:repair --include-expensive
# 9. 安装imagick SVG支持
echo "安装imagick SVG支持..."
apt-get update
apt-get install -y imagemagick php$PHP_VERSION-imagick
sed -i 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml
sed -i 's/rights="none" pattern="SVG"/rights="read|write" pattern="SVG"/' /etc/ImageMagick-6/policy.xml
# 10. 添加额外的安全头
echo "配置安全头..."
sed -i '/add_header X-Frame-Options/a\ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;\n add_header X-Content-Type-Options "nosniff" always;\n add_header X-XSS-Protection "1; mode=block" always;\n add_header X-Robots-Tag "none" always;\n add_header X-Download-Options "noopen" always;\n add_header X-Permitted-Cross-Domain-Policies "none" always;\n add_header Referrer-Policy "no-referrer" always;' /etc/nginx/conf.d/nextcloud.conf
# 11. 配置PHP-FPM优化
echo "优化PHP-FPM配置..."
cat > /etc/php/$PHP_VERSION/fpm/pool.d/www.conf <<EOF
[www]
user = www-data
group = www-data
listen = /var/run/php/php$PHP_VERSION-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18
pm.process_idle_timeout = 10s
pm.max_requests = 500
php_admin_value[memory_limit] = 512M
php_admin_value[upload_max_filesize] = 512M
php_admin_value[post_max_size] = 512M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_time] = 300
EOF
# 12. 重启服务
echo "重启服务..."
systemctl restart php$PHP_VERSION-fpm
systemctl restart nginx
# 13. 清除缓存
echo "清除Nextcloud缓存..."
$OCC maintenance:repair
$OCC maintenance:mode --off
# 配置系统环境变量
echo "配置系统环境变量..."
cat > /etc/php/$PHP_VERSION/fpm/conf.d/99-environment.ini <<EOF
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
EOF
# 配置系统环境变量
echo "配置系统环境变量..."
cat > /etc/php/$PHP_VERSION/cli/php.ini <<EOF
apc.enable_cli = 1
EOF
# 设置维护时间窗口(凌晨1点)
echo "设置维护时间窗口..."
sudo -u www-data php /var/www/nextcloud/occ config:system:set maintenance_window_start --value="1"
# 执行MIME类型迁移
echo "执行MIME类型迁移..."
sudo -u www-data php /var/www/nextcloud/occ maintenance:repair --include-expensive
# 添加缺失的数据库索引
echo "添加缺失的数据库索引..."
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
# 安装office应用
sudo -u www-data php /var/www/nextcloud/occ app:install richdocuments
sudo -u www-data php /var/www/nextcloud/occ app:enable richdocuments
sudo -u www-data php /var/www/nextcloud/occ app:install richdocumentscode
sudo -u www-data php /var/www/nextcloud/occ app:enable richdocumentscode
# 设置默认国际区号
echo "设置默认国际区号..."
sudo -u www-data php /var/www/nextcloud/occ config:system:set default_phone_region --value="CN"
# 更新PHP-FPM配置以确保环境变量访问
echo "更新PHP-FPM环境变量配置..."
sed -i '/^clear_env/c\clear_env = no' /etc/php/$PHP_VERSION/fpm/pool.d/www.conf
# 重启相关服务
echo "重启服务..."
systemctl restart php$PHP_VERSION-fpm
systemctl restart nginx
# 验证修复
echo "验证修复..."
sudo -u www-data php /var/www/nextcloud/occ status
echo "修复完成!请检查Nextcloud管理面板中的安全和设置警告。"
使用说明:
首先需要修改脚本开头的变量:
MYSQL_ROOT_PASSWORD:MySQL root密码
NEXTCLOUD_DB_PASSWORD:Nextcloud数据库用户密码
DOMAIN_NAME:你的域名
给脚本添加执行权限:
chmod +x install_nextcloud.sh
以root用户运行脚本:
./install_nextcloud.sh
注意事项:
- 这个脚本使用的是自签名SSL证书。在生产环境中,建议使用Let’s Encrypt获取免费的SSL证书。
- 在第一次访问配置页面的时候,要注意用户data目录的配置调整,否则后续可能会造成目录爆满。
- 脚本中的PHP和MySQL配置是基本配置,可能需要根据你的服务器硬件配置进行调整。
- 安装完成后,需要通过Web界面完成Nextcloud的初始化配置。
- 建议在安装完成后:
- 配置定时任务
- 启用缓存
- 配置邮件服务
- 根据需要安装额外的Nextcloud应用
- 为了安全起见,建议:
- 更改默认的MySQL密码
- 配置防火墙
- 定期备份数据
- 保持系统和Nextcloud更新
- Debian12系统为最小安装即可,另外请确保环境中不包含任何其他生产数据和环境。
如有任何疑问,欢迎关注微信公众号“大刘讲IT”