Cloudreve 部署脚本
cloudreve安装脚本,支持Fedora和Debian。
包含docker、docker compose、以及二进制文件安装方式。
包含 数据库设置、SSL设置。
docker compose安装方式采用Github Repo 内的docker-compose.yml文件
懒得测试,就这样吧
#!/bin/bash
# cloudreve.sh
# Copyright (c) [2026] [Konvict Liu / https://konvict.cn]
# 2026-02-07
# License: Mozilla Public License, v. 2.0
# 根据MPL 2.0的要求,对本文件的任何修改必须在文件开头明确说明。
# https://www.mozilla.org/en-US/MPL/2.0/
tarURL="https://github.com/cloudreve/cloudreve/releases/download/4.13.0/cloudreve_4.13.0_linux_amd64.tar.gz"
# shellcheck disable=SC1091
source /etc/os-release
if [[ $(id -u) -ne 0 ]]; then
echo "Please run as root"
exit 1
fi
Color_Text() {
echo -e " \e[0;$2m$1\e[0m"
}
Echo_Red() {
echo $(Color_Text "$1" "31")
}
Echo_Green() {
echo $(Color_Text "$1" "32")
}
Echo_Yellow() {
echo $(Color_Text "$1" "33")
}
Echo_Blue() {
echo $(Color_Text "$1" "34")
}
systemDistroVersion() {
if [[ ${ID} == "debian" ]]; then
Echo_Green "Debian detected"
packageManager="apt"
elif [[ ${ID} == "fedora" ]]; then
Echo_Green "Fedora detected"
packageManager="dnf"
else
Echo_Red "Unsupported OS"
Echo_Red "This script only supports Fedora and Debian."
Echo_Red "Exiting"
exit 1
fi
Echo_Blue "Detecting System Version..."
if [[ ${ID} == "fedora" ]]; then
Echo_Green "Fedora ${VERSION_ID} detected"
elif [[ ${ID} == "debian" ]]; then
Echo_Green "Debian ${VERSION_ID} detected"
fi
}
installMethod() {
echo "Please select the installation method:"
echo "1. Install with systemd (Defalut)"
echo "2. Install with Docker"
echo "3. Install with Docker Compose"
echo "4. Exit"
read -rp "Enter your choice: " installMethod="${installMethod:-1}"
}
installDockerFedora() {
dnf config-manager addrepo --from-repofile https://download.docker.com/linux/fedora/docker-ce.repo
dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker
}
installDockerDebian() {
apt remove $(dpkg --get-selections docker.io docker-compose docker-doc podman-docker containerd runc | cut -f1)
# Add Docker's official GPG key:
apt update && apt install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(source /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update && apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker
}
installDocker() {
if [[ $(command -v docker) ]]; then
Echo_Green "Docker already installed"
else
Echo_Blue "Installing Docker..."
if [[ ${ID} == "fedora" ]]; then
installDockerFedora
elif [[ ${ID} == "debian" ]]; then
installDockerDebian
fi
fi
}
passwordWarning() {
Echo_Yellow "Please input the database password."
Echo_Yellow "The password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one number, and one special character."
}
chooseDatabase() {
echo "Please select a database:"
echo "1. SQLite (default)"
echo "2. MySQL"
echo "3. PostgreSQL"
echo "4. MariaDB"
read -rp "Enter your choice: " dbChoice
dbChoice=${dbChoice:-1}
read -rp "Please enter the database host (default: localhost): " dbHost
dbHost=${dbHost:-localhost}
read -rp "Please enter the database port (default: 3306 for MySQL/MariaDB, 5432 for PostgreSQL): " dbPort
if [[ -z "$dbPort" ]]; then
if [[ $dbChoice -eq 2 ]]; then
dbPort=3306
elif [[ $dbChoice -eq 3 ]]; then
dbPort=5432
elif [[ $dbChoice -eq 4 ]]; then
dbPort=3306
fi
fi
read -rp "Please enter the database name (default: cloudreve): " dbName
dbName=${dbName:-cloudreve}
read -rp "Please enter the database username (default: root): " dbUser
dbUser=${dbUser:-root}
passwordWarning
while true; do
read -rp "Please enter the database password (default: empty): " dbPassword
if [[ ${#dbPassword} -ge 8 && "$dbPassword" == *[[:lower:]]* && "$dbPassword" == *[[:upper:]]* && "$dbPassword" == *[0-9]* && "$dbPassword" == *[[:punct:]]* ]]; then
break
else
Echo_Red "The password is not strong enough."
Echo_Red "Please try again."
fi
done
echo "Database configurations: "
echo "Type: $([[ $dbChoice -eq 1 ]] && echo 'SQLite' || ([[ $dbChoice -eq 2 ]] && echo 'MySQL' || ([[ $dbChoice -eq 4 ]] && echo 'MariaDB' || echo 'PostgreSQL')))"
echo "Host: $dbHost"
echo "Port: $dbPort"
echo "Name: $dbName"
echo "User: $dbUser"
echo "Password: $dbPassword"
}
configDBDocker() {
case $dbChoice in
1)
dbConfig=""
;;
2)
dbConfig="-e CR_CONF_Database.Type=mysql -e CR_CONF_Database.Host=$dbHost -e CR_CONF_Database.Port=$dbPort -e CR_CONF_Database.Name=$dbName -e CR_CONF_Database.User=$dbUser -e CR_CONF_Database.Password=$dbPassword"
;;
3)
# shellcheck disable=SC2034
dbConfig="-e CR_CONF_Database.Type=postgresql -e CR_CONF_Database.Host=$dbHost -e CR_CONF_Database.Port=$dbPort -e CR_CONF_Database.Name=$dbName -e CR_CONF_Database.User=$dbUser -e CR_CONF_Database.Password=$dbPassword"
;;
4)
dbConfig="-e CR_CONF_Database.Type=mariadb -e CR_CONF_Database.Host=$dbHost -e CR_CONF_Database.Port=$dbPort -e CR_CONF_Database.Name=$dbName -e CR_CONF_Database.User=$dbUser -e CR_CONF_Database.Password=$dbPassword"
;;
*)
Echo_Red "Invalid database choice"
exit 1
;;
esac
}
installCloudreveDocker() {
read -r -p "please input the port you want to use for cloudreve (default: 5212): " port
port=${port:-5212}
read -r -p "please input the path you want to use for cloudreve (default: ~/cloudreve): " cloudreveDataDir
cloudreveDataDir=${cloudreveDataDir:-${installDir}/data}
mkdir -p "${cloudreveDataDir}"
docker run -dit --name cloudreve \
--restart=unless-stopped \
-p "${port}":5212 \
-v "${cloudreveDataDir}":/cloudreve/data \
"${dbConfig}" \
cloudreve/cloudreve:latest
Echo_Green "Cloudreve installed successfully"
Echo_Green "Cloudreve is running at: "
for i in $(hostname -I); do echo "http://$i:${port}"; done
unset port cloudreveDataDir i
}
installCloudreveDockerCompose() {
Echo_Yellow "Installing Cloudreve with Docker Compose..."
Echo_Yellow "Database file using PostgreSQL"
Echo_Yellow "Other services: Redis"
read -r -p "please input the port you want to use for cloudreve (default: 5212): " port
port=${port:-5212}
mkdir -p "${cloudreveDataDir}"
cat >docker-compose.yml <<EOF
services:
cloudreve:
image: cloudreve/cloudreve:latest
container_name: cloudreve-backend
depends_on:
- postgresql
- redis
restart: unless-stopped
ports:
- ${port}:5212
environment:
- CR_CONF_Database.Type=postgres
- CR_CONF_Database.Host=postgresql
- CR_CONF_Database.User=cloudreve
- CR_CONF_Database.Name=cloudreve
- CR_CONF_Database.Port=5432
- CR_CONF_Redis.Server=redis:6379
volumes:
- backend_data:/cloudreve/data
postgresql:
# Best practice: Pin to major version.
# NOTE: For major version jumps:
# backup & consult https://www.postgresql.org/docs/current/pgupgrade.html
image: postgres:17
container_name: postgresql
restart: unless-stopped
environment:
- POSTGRES_USER=cloudreve
- POSTGRES_DB=cloudreve
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- database_postgres:/var/lib/postgresql/data
redis:
image: redis:latest
container_name: redis
restart: unless-stopped
volumes:
- redis_data:/data
volumes:
backend_data:
database_postgres:
redis_data:
EOF
if docker compose up -d; then
Echo_Green "Cloudreve installed successfully"
Echo_Green "Cloudreve is running at: "
for i in $(hostname -I); do echo "http://$i:${port}"; done
unset port cloudreveDataDir i
else
Echo_Red "Failed to start cloudreve"
exit 1
fi
}
chooseInstallDir() {
read -r -p "Please input the installation directory for cloudreve (default: /opt/cloudreve): " installDir
installDir=${installDir:-/opt/cloudreve}
}
# Download and extract the tarball
installCloudreveBinary() {
wget ${tarURL}
if [[ -d ${installDir} ]]; then
:
else
mkdir -p "${installDir}"
tar -xzf cloudreve_4.13.0_linux_amd64.tar.gz -C "${installDir}"
fi
}
configFilePath() {
read -r -p "please input the path you want to use for cloudreve (default: ~/cloudreve): " cloudreveDataDir
cloudreveDataDir=${cloudreveDataDir:-${installDir}/data}
read -r -p "Please input the path you want to use for cloudreve (Full path with file name. Default: ${cloudreveDataDir}/config.ini): " cloudreveConfigFilePath
cloudreveConfigFilePath=${cloudreveConfigFilePath:-${cloudreveDataDir}/config.ini}
# shellcheck disable=SC2034
if [[ ${cloudreveConfigFilePath} == "${cloudreveDataDir}/config.ini" ]]; then
cloudreveArgs=""
else
cloudreveArgs="-c ${cloudreveConfigFilePath} "
fi
}
defaultConfigFile() {
cat >"${cloudreveConfigFilePath}" <<EOF
[System]
Debug = false
Mode = master
Listen = :5212
SessionSecret = oOozI3MOb5JYXxuirRuoxgYU3hwZHk4oM5g1d44cGZ7jU2bMzKFmNAK11L8u9kWp
HashIDSalt = {HashIDSalt}
ProxyHeader = X-Forwarded-For
[UnixSocket]
Listen = /run/cloudreve/cloudreve.sock
Perm = 0666
EOF
}
configDBBinary() {
if [[ $dbChoice -eq 1 ]]; then
dbConfig=""
elif [[ $dbChoice -eq 2 ]]; then # MySQL
cat >>"${cloudreveConfigFilePath}" <<EOF
[Database]
Type = mysql
Host = ${dbHost}
Port = ${dbPort}
Name = ${dbName}
User = ${dbUser}
Password = ${dbPassword}
EOF
elif [[ $dbChoice -eq 4 ]]; then # MariaDB
cat >>"${cloudreveConfigFilePath}" <<EOF
[Database]
Type = mariadb
Host = ${dbHost}
Port = ${dbPort}
Name = ${dbName}
User = ${dbUser}
Password = ${dbPassword}
EOF
else # PostgreSQL
cat >>"${cloudreveConfigFilePath}" <<EOF
[Database]
Type = postgresql
Host = ${dbHost}
Port = ${dbPort}
Name = ${dbName}
User = ${dbUser}
Password = ${dbPassword}
EOF
fi
}
# Create systemd service
createSystemdService() {
Echo_Yellow "Creating systemd service..."
systemdFile="/etc/systemd/system/cloudreve.service"
cat >"${systemdFile}" <<EOF
[Unit]
Description=Cloudreve
Documentation=https://docs.cloudreve.org
After=network.target
After=mysqld.service
Wants=network.target
[Service]
WorkingDirectory=${installDir}
ExecStart=${installDir}/cloudreve ${cloudreveArgs}
Restart=on-abnormal
RestartSec=5s
KillMode=mixed
# 日志输出
StandardOutput=/var/log/cloudreve.log
StandardError=syslog
[Install]
WantedBy=multi-user.target
EOF
}
sslConfig() {
read -r -p "Do you want to enable SSL? (y/N): " enableSSL
enableSSL=${enableSSL:-N}
if [[ $enableSSL == [Yy] ]]; then
read -r -p "Please input the path to your SSL certificate file (default: /etc/ssl/certs/cloudreve.crt): " sslCertPath
sslCertPath=${sslCertPath:-/etc/ssl/certs/cloudreve.crt}
read -r -p "Please input the path to your SSL key file (default: /etc/ssl/private/cloudreve.key): " sslKeyPath
sslKeyPath=${sslKeyPath:-/etc/ssl/private/cloudreve.key}
read -r -p "please input the HTTPS port you want to use for cloudreve (default: 443): " httpsPort
httpsPort=${httpsPort:-443}
cat >>"${cloudreveConfigFilePath}" <<EOF
[SSL]
Listen = :${httpsPort}
CertPath = ${sslCertPath} ; 证书文件路径
KeyPath = ${sslKeyPath} ; 私钥文件路径
EOF
fi
}
# Enable and start the service
enableAndStartService() {
systemctl daemon-reload && systemctl enable --now cloudreve
}
systemDistroVersion
installMethod
if [[ ${installMethod} = 1 ]]; then
chooseInstallDir
installCloudreveBinary
configFilePath
defaultConfigFile
chooseDatabase
configDBBinary
sslConfig
createSystemdService
enableAndStartService
elif [[ ${installMethod} = 2 ]]; then
installDocker
chooseDatabase
configDBDocker
installCloudreveDocker
elif [[ ${installMethod} = 3 ]]; then
installDocker
chooseDatabase
installCloudreveDockerCompose
else
Echo_Red "Invalid installation method"
exit 1
fi