MoreRSS

site iconLala | 荒岛修改

一个应用分享、教程类的博客,主要是那些需要自部署的。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Lala | 荒岛的 RSS 预览

WHMCS集成ConvoyPanel销售小鸡

2025-10-22 11:33:23

我在Github上找到了几个WHMCS对接ConvoyPanel的模块,我全部都试了一遍,这些模块不是这有点问题就是那有点问题。。只有这一个功能是完全正常的:https://github.com/simple-taipei/convoy-for-whmcs。但实际上这个模块也不能做到开箱即用,需要魔改一下WHMCS的产品配置页面。

由于ConvoyPanel的API对创建虚拟机时使用的ROOT密码要求非常严格,至少8位,且要包含一个大写字母,一个小写字母,一个数字,一个特殊符号。而WHMCS默认的ROOT密码输入框没有对用户输入的密码进行强度校验,这导致用户如果输入了一个强度不达标的密码,虚拟机就无法创建成功。

为了解决这个问题,我用AI写了一个WHMCS的Hook,实现的功能就是校验用户输入的ROOT密码是否满足ConvoyPanel的条件,如果不满足条件则阻止表单提交,直到用户输入的ROOT密码满足条件才能下单购买。我顺便还让AI写了一个隐藏WHMCS产品配置页面的NS1/NS2输入框,并填充默认值的Hook。有需要的可以直接从我博客下载。

密码强度校验:validate_rootpw

隐藏NS1/NS2输入框:hidden_nsprefix

使用方法也很简单,把这些PHP文件放到这个目录下:

/var/www/whmcs/includes/hooks

修改文件所有者权限:

chown -R www-data:www-data /var/www/whmcs/includes/hooks/validate_rootpw.php
chown -R www-data:www-data /var/www/whmcs/includes/hooks/hidden_nsprefix.php

效果就是这样,用户购买时只需要输入虚拟机的Hostname和ROOT密码:

目前只测试过WHMCS默认的Standard Cart订单模板,其他的模板能不能用不清楚,不能用的话让AI改一下应该也不难。。但是请注意哈,这两个Hook文件都只是做了简单的前端校验,后端是没有校验的,也就是说用户如果懂点技术的话是可以直接篡改(绕过)这些功能的。当然我觉得不会有人那么无聊吧,让设置高强度的密码不要,要去用弱密码然后机子被人黑=-=

现在就可以来配置模块了,在WHMCS如下路径创建一个目录:

mkdir /var/www/whmcs/modules/servers/convoy

把模块克隆到本地:

git clone https://github.com/simple-taipei/convoy-for-whmcs.git
cd convoy-for-whmcs

把模块文件都复制到对应的目录下:

cp convoy.php /var/www/whmcs/modules/servers/convoy
cp -r lib /var/www/whmcs/modules/servers/convoy
cp -r templates /var/www/whmcs/modules/servers/convoy

修改目录所有者权限:

chown -R www-data:www-data /var/www/whmcs/modules/servers/convoy

[可选]如果想要产品开通后,虚拟机自动开机可以编辑convoy.php:

nano /var/www/whmcs/modules/servers/convoy/convoy.php

把这个配置改成true:

'start_on_completion' => true

转到WHMCS后台,先添加一个组,再添加一个服务:

点击如图所示按钮进入完整的配置页面:

Name随便起一个,Hostname填写你的ConvoyPanel域名(不要带http/https前缀),IP Address填写ConvoyPanel所在服务器的公网IP。Password填写ConvoyPanel面板生成的Token,端口使用443,其他没有提到的配置项全部保持默认值不做修改,点击测试连接,确保能够正常连接到ConvoyPanel:

ConvoyPanel创建Token:

转到WHMCS的Products/Services页面,先创建一个产品组,再创建一个产品:

产品类型一定要选择Server/VPS,因为我们刚才的Hook都是针对的这个模板页面,你用其他的就达不到预期效果:

转到模块设置页面,参考下图来配置VPS产品的具体规格,如CPU、内存、硬盘、流量等:

这里面需要注意是Node ID这个ID在ConvoyPanel的如下页面可以找到:

还有Template UUID:

到这里就全部配置完成了,现在可以测试一下用户下单购买以及开通的情况,用户可以在WHMCS通过SSO登录到ConvoyPanel的虚拟机控制面板:

一切正常:

到这里这篇文章就写的差不多了,当然如果想正式营业的话还需要对接一个支付接口,oneman常用的接口不用多说了,肯定是易支付。。易支付可以自己搭,也可以用别人的,俗称平台。用别人的易支付风险很大,因为这些平台随时都可能跑路,做的都是些“你懂的”的业务。。最好还是自己搭一个。。这里就不多说了。。

Debian13安装WHMCS 8.13.1开心版

2025-10-22 11:31:33

WHMCS和开心授权文件下载:https://whmcsfull.com/,目前的最新版是8.13.1。

由于WHMCS官方不推荐使用NGINX,所以这篇文章中使用的Web服务器软件是Apache2。其实要用NGINX应该也没什么问题,就是要转换一下.htaccess里面的规则,主要还是考虑到安全问题,NGINX规则没写好可能会泄漏一些敏感目录和数据。。

另外由于Debian13官方存储库内的PHP版本已经是8.4了,而WHMCS目前最高只支持到8.3,所以我添加了SURY的存储库来安装PHP8.3。这波属于是反向升级了=-=我其实不喜欢WHMCS,我更看好目前开源的Paymenter,奈何周边生态还不太行,像什么模块、支付接口都没什么人开发=-=

安装PHP8.3:

apt install curl apt-transport-https ca-certificates lsb-release
curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
dpkg -i /tmp/debsuryorg-archive-keyring.deb
sh -c 'echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
apt update
apt install php8.3 php8.3-{common,fpm,cli,curl,gd,imap,mysql,xml,bcmath,gmp,intl,mbstring,soap,zip}

由于我这个系统内原本就安装了PHP8.4,所以这里还需要切换一下版本:

update-alternatives --config php

输入对应数字即可切换:

WHMCS还需要用到ionCube,首先下载ionCube:

wget https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
tar -xzvf ioncube_loaders_lin_x86-64.tar.gz
cd ioncube/

查找PHP8.3的扩展目录:

php -i | grep extension_dir

回显类似内容:

extension_dir => /usr/lib/php/20230831 => /usr/lib/php/20230831

将对应PHP版本的ionCube扩展复制到刚才的目录内:

cp ioncube_loader_lin_8.3.so /usr/lib/php/20230831

编辑PHP-FPM的php.ini配置文件:

nano /etc/php/8.3/fpm/php.ini

新增如下内容,注意是新增不要把现有的zend_extension配置删除或者替换掉:

zend_extension = /usr/lib/php/20230831/ioncube_loader_lin_8.3.so

WHMCS官方不建议在运行环境中使用OPcache,所以顺便还是在这个配置文件内关闭OPcache:

opcache.enable=0

[可选]也可以顺便在这个配置文件内修改一下如下配置,优化WHMCS运行时的性能:

date.timezone=Asia/Shanghai
memory_limit = 256M
max_execution_time = 300
upload_max_filesize = 50M
post_max_size = 50M

别忘了还有PHP-CLI的php.ini配置:

nano /etc/php/8.3/cli/php.ini

也是一样新增如下内容:

zend_extension = /usr/lib/php/20230831/ioncube_loader_lin_8.3.so

关闭OPcache:

opcache.enable=0

重启PHP-FPM服务使更改生效:

systemctl restart php8.3-fpm.service

验证ionCube模块是否正常加载:

php -m | grep ionCube

有类似回显说明正常:

ionCube Loader
the ionCube PHP Loader

安装Apache2/Certbot/Mariadb数据库:

apt install apache2 python3-certbot-apache mariadb-server unzip

检查当前的Apache2运行模式,有两种模式:Event、Prefork,前者性能更好:

a2query -M

如果回显是Event就不用管了,如果回显是Prefork则执行如下命令进行切换:

a2dismod mpm_prefork
a2enmod mpm_event

配置Apache2使用FPM与PHP进行通信,同时启用伪静态重写功能:

a2enmod proxy_fcgi setenvif rewrite

Debian的Apache打包维护者非常贴心啊,自带了Apache2可用的PHP-FPM配置文件,只需要使用下面的命令启用一下即可:

a2enconf php8.3-fpm

重启Apache2使更改生效:

systemctl restart apache2

检查模块是否正常加载:

a2query -m

正常的话应该列出包含proxy_fcgi、rewrite的模块信息:

setenvif (enabled by maintainer script)
ssl (enabled by site administrator)
status (enabled by maintainer script)
mpm_event (enabled by maintainer script)
proxy_fcgi (enabled by site administrator)
socache_shmcb (enabled by site administrator)
env (enabled by maintainer script)
authz_user (enabled by maintainer script)
proxy (enabled by site administrator)
mime (enabled by maintainer script)
authz_core (enabled by maintainer script)
authn_file (enabled by maintainer script)
negotiation (enabled by maintainer script)
authn_core (enabled by maintainer script)
alias (enabled by maintainer script)
dir (enabled by maintainer script)
autoindex (enabled by maintainer script)
auth_basic (enabled by maintainer script)
rewrite (enabled by site administrator)
reqtimeout (enabled by maintainer script)
deflate (enabled by maintainer script)
access_compat (enabled by maintainer script)
authz_host (enabled by maintainer script)
filter (enabled by maintainer script)

刚才虽然启用了rewrite模块,但是Apache2的默认配置是不允许使用.htaccess文件的,为了后续WHMCS提供的.htaccess能够正常工作,我们可以在conf-available目录内新建一个覆盖配置:

nano /etc/apache2/conf-available/allow-override.conf

写入如下内容:

<Directory "/var/www">
    AllowOverride all
</Directory>

启用这个配置:

a2enconf allow-override

重载Apache2使配置生效:

systemctl reload apache2

登录到Mariadb:

mysql -u root -p

创建数据库和用户并授权允许访问:

CREATE USER 'whmcs'@'127.0.0.1' IDENTIFIED BY 'yourpassword';
CREATE DATABASE whmcs;
GRANT ALL PRIVILEGES ON whmcs.* TO 'whmcs'@'127.0.0.1' WITH GRANT OPTION;

下载WHMCS源码解压:

mkdir /var/www/whmcs && cd /var/www/whmcs
wget https://whmcsfull.com/download.whmcs.com/latestVersion/whmcs-8.13.1-release.1.zip
unzip whmcs-8.13.1-release.1.zip
rm whmcs-8.13.1-release.1.zip

进入vendor/whmcs/whmcs-foundation/lib目录,备份原始的授权文件:

cd vendor/whmcs/whmcs-foundation/lib
mv License.php License.php.bak

从这里下载开心版授权文件:https://whmcsfull.com/#license,将开心版授权文件重命名为License.php上传到这个路径下即可完成开心,后续输入授权key的时候随意输入即可。

设置正确的所有者权限:

chown -R www-data:www-data /var/www/whmcs/

新建Apache2的Vhost(站点)配置文件:

nano /etc/apache2/sites-available/whmcs.conf

写入如下内容:

<VirtualHost *:80>
        ServerName whmcs.example.com
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/example
        ErrorLog ${APACHE_LOG_DIR}/example_error.log
        CustomLog ${APACHE_LOG_DIR}/example_access.log combined
</VirtualHost>

启用站点:

a2ensite whmcs

重载Apache2使其生效:

systemctl reload apache2

签发SSL证书:

certbot --apache

访问whmcs.example.com,如果正常应该可以看到如下页面:

检查环境,确保满足WHMCS的条件:

配置数据库连接信息,授权Key可以随意输入:

创建管理员账号:

安装完成后,还需要按照WHMCS的提示进行善后工作。删除WHMCS程序的安装目录:

rm -rf /var/www/whmcs/install/

修改configuration.php的文件权限为400:

chmod 400 configuration.php

配置计划任务:

crontab -u www-data -e

写入如下内容:

*/5 * * * * /usr/bin/php -q /var/www/whmcs/crons/cron.php

Debian13部署ConvoyPanel开HE IPv6隧道小鸡

2025-10-22 11:19:42

介绍

ConvoyPanel是一个可以与Proxmox VE集成的高性能KVM服务器管理面板。

简而言之,PVE默认的Web UI不适合拿来卖VPS,这个面板就是用来解决这个问题的,说白了就是给VPS商家用的。同类型的产品还有Virtfusion、Virtualizor等等。ConvoyPanel这个程序比较冷门,网上介绍的不多,我之前送的免费小鸡其实就是用的这个面板,我觉得ConvoyPanel还挺好用的,只是一直没机会写篇完整的部署文章向大伙介绍一下。。。

ConvoyPanel主打一个便宜,个人非商业用途直接免费,免费,免费!商用的话一个节点每月也就6刀(注意是节点,也就是一台独服。说详细点免得又有杠精说我误导人。)别的程序虽然也谈不上贵,但ConvoyPanel是真的白菜价了。

当然这么低的价格,我感觉作者也是用爱发电,很佛系,开发进度非常缓慢,时间基本可以说是以年为单位,不过这种程序更的快也未必是个好事,功能够用的前提下,不折腾稳定才是王道,只要安全更新能够及时更上就行=-=

准备工作:

1.至少两台服务器,一台用于计算节点(Proxmox VE),一台用于部署ConvoyPanel。

2.做好域名解析:

pve-buf.example.com # Proxmox VE主机
console.example.com # ConvoyPanel
vnc-buf.example.com # Coterm控制台代理,可选

部署ConvoyPanel

我这里没有采用官方的Docker部署方式,简单说下原因。

1.考虑到官方的Docker部署方式需要占用80/443端口,且这个面板程序本身占用资源不大,我觉得单独拿一台服务器出来只部署它太浪费了,我把系统的80/443端口留给NGINX还能干点别的事。

2.我正好有一台机器部署了Paymenter,这个Paymenter运行所需的环境不能说与ConvoyPanel一模一样吧,但大差不差,都是Laravel框架写出来的程序,而且最后我也是把ConvoyPanel与Paymenter对接起来一起用,所以干脆就直接把这两个程序装在一台服务器内了,也就是说这篇文章的步骤我根本不用全部重新再来一遍,我装一遍可以跑两个程序=-=

以下部署步骤基于Debian13。添加sury存储库,安装PHP8.3:

apt update
apt -y install curl gnupg2 lsb-release ca-certificates
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/sury-php.list
curl -fsSL https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/sury-keyring.gpg
apt update
apt -y install php8.3 php8.3-{common,cli,gd,mysql,mbstring,bcmath,xml,fpm,curl,zip,intl,redis,gmp}

安装NGINX/Mariadb/Redis以及其他需要用到的包:

apt -y install nginx mariadb-server redis-server tar unzip

设置开机自启:

systemctl enable nginx.service mariadb.service redis-server.service php8.3-fpm.service

安装composer:

curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

登录到Mariadb,不需要输入root密码直接回车:

mysql -u root -p

创建用户和数据库:

CREATE USER 'convoy'@'127.0.0.1' IDENTIFIED BY 'yourdbpassword';
CREATE DATABASE convoy;
GRANT ALL PRIVILEGES ON convoy.* TO 'convoy'@'127.0.0.1' WITH GRANT OPTION;

创建站点目录:

mkdir -p /var/www/convoy && cd /var/www/convoy

下载程序解压,设置正确的文件权限:

curl -Lo panel.tar.gz https://github.com/convoypanel/panel/releases/latest/download/panel.tar.gz
tar -xzvf panel.tar.gz
chmod -R o+w storage/* bootstrap/cache/

复制一份配置文件:

cp .env.example .env

编辑配置文件:

nano .env

需要修改的配置如下,其他没有列出的内容可以保持默认:

APP_ENV=production
APP_DEBUG=false
APP_URL=https://console.example.com
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=convoy
DB_USERNAME=convoy
DB_PASSWORD=yourdbpassword
REDIS_HOST=127.0.0.1

安装依赖:

composer install --no-dev --optimize-autoloader

生成Application Key:

php artisan key:generate --force
php artisan optimize

初始化数据库:

php artisan migrate --force

创建管理员账号:

php artisan c:user:make

设置正确的所有者权限:

chown -R www-data:www-data /var/www/convoy/

添加计划任务:

crontab -u www-data -e

写入如下内容:

* * * * * php /var/www/convoy/artisan schedule:run --verbose --no-interaction

新建systemd服务:

nano /etc/systemd/system/convoy.service

写入如下内容:

[Unit]
Description=Convoy Horizon

[Service]
User=www-data
Group=www-data
Restart=always
ExecStart=/usr/bin/php /var/www/convoy/artisan horizon
StartLimitInterval=180
StartLimitBurst=30
RestartSec=5s

[Install]
WantedBy=multi-user.target

启动:

systemctl enable --now convoy.service

新建NGINX配置文件:

nano /etc/nginx/sites-available/convoy.conf

写入如下内容:

server {
    listen 80;
    listen [::]:80;
    server_name console.example.com;
    root /var/www/convoy/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
    }
}

启用站点:

ln -s /etc/nginx/sites-available/convoy.conf /etc/nginx/sites-enabled/

签发SSL证书:

certbot --nginx

访问console.example.com,如一切正常就可以使用之前创建的管理员账号登录到后台了:

Proxmox VE配置使用HE IPv6 Tunnel

ConvoyPanel是不支持NAT网络的(没有端口转发的功能,也就是没有DNAT的功能)在这种情况下我们要保证创建的虚拟机至少拥有一个独立IP地址,IPv4或者IPv6均可。IPv4太贵买不起,甚至我用于写文章的这台服务器连IPv6都没有,所以这里介绍一下使用HE IPv6 Tunnel的方法。

访问HE IPv6 Tunnel网站(tunnelbroker),注册账号。

点击Create Regular Tunnel创建隧道,IPv4 Endpoint (Your side)填写你的服务器公网IPv4地址,选择一个离你服务器延迟低的区域:

默认情况下,HE只提供一个/64,你还可以申请一个/48,后续我们使用这个/48来给虚拟机分配IPv6地址:

转到Example Configurations,找到Debian的配置示例,类似下图这样的配置:

由于现在的Proxmox VE 8/9都使用ifupdown2,而非Debian发行版默认的ifupdown,HE提供的这个配置是基于ifupdown的,不能直接用在Proxmox VE 8/9上面,需要稍加修改,下面是修改后的配置:

auto he-ipv6
iface he-ipv6 inet6 tunnel
        mode sit
        address 2001:470:x:x::x
        netmask 64
        endpoint 216.x.x.x
        local 23.x.x.x
        ttl 255
        gateway 2001:470:x:x::x

另外如果你使用的是Proxmox VE 8并且使用了SDN网络,Proxmox VE 8的ifupdown2有个BUG会导致SDN无法正常工作,你可以编辑如下文件:

nano /usr/share/ifupdown2/ifupdown/iface.py

找到325行的:

retconfig[k] = v[0] if len(v) == 1 else v

将其改成:

retconfig[k] = str(v[0] if len(v) == 1 else v)

Proxmox VE 9的ifupdown2无此问题,并且ifupdown2官方就是使用这个帖子里的方法来修复的

编辑interfaces文件:

nano /etc/network/interfaces

完整的配置如下,在这个配置中vmbr0桥接eth1,并为其配置了HE隧道的/48 IPv6:

auto lo
iface lo inet loopback

iface eth1 inet manual

auto vmbr0
iface vmbr0 inet static
        address 23.x.x.x/30
        gateway 23.x.x.x
        bridge-ports eth1
        bridge-stp off
        bridge-fd 0

iface vmbr0 inet6 static
        address 2001:470:x::x/48

auto he-ipv6
iface he-ipv6 inet6 tunnel
        mode sit
        address 2001:470:x:x::x
        netmask 64
        endpoint 216.x.x.x
        local 23.x.x.x
        ttl 255
        gateway 2001:470:x:x::x

使修改后的配置生效:

ifreload -a

还需要启用IPv6转发:

cd /etc/sysctl.d/
nano 99-custom.conf

写入如下内容:

net.ipv6.conf.all.forwarding = 1

使IPv6转发生效:

sysctl --system

HE IPv6 Tunnel的IPv6无论是/64还是/48都是全段路由,不需要使用NDP代理,所以到这里就全部配置完成了。

制作Debian/Ubuntu系统模板

ConvoyPanel创建虚拟机必须用到系统模板,现在来介绍一下如何制作可用于ConvoyPanel的Debian/Ubuntu系统模板。

ConvoyPanel官方其实提供了很多系统模板,但是这些模板太旧了,而且配置的不太好,所以这里我制作了两个系统模板:Debian13、Ubuntu24.04。

[提醒]不建议使用Debian cloud image制作Debian13以下的系统模板,因为内置的cloud-init版本太旧有各种BUG。

[警告]接下来的操作不要在PVE主机上进行!需要用到的libguestfs-tools软件包与PVE不兼容!最好找一台别的服务器安装,这里我在部署ConvoyPanel的服务器上操作。

安装libguestfs-tools:

apt install libguestfs-tools

下载系统Debian13、Ubuntu24.04的系统image:

mkdir /root/convoy-temp && cd /root/convoy-temp
wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img

我们先来定制Debian13的系统image,修改SSH配置允许root用户使用密码登录,这个必须要改,因为ConvoyPanel在创建虚拟机时设置的密码只能是root用户的。使用virt-edit工具来编辑系统image内的SSH配置文件:

virt-edit -a debian-13-genericcloud-amd64.qcow2 /etc/ssh/sshd_config

允许root用户登录:

#PermitRootLogin prohibit-password

改为:

PermitRootLogin yes

允许使用密码登录:

PasswordAuthentication no

改为:

PasswordAuthentication yes

更新系统到最新/设置时区/预装软件,注意这里一定要安装qemu-guest-agent并设置开机自启:

virt-customize -a debian-13-genericcloud-amd64.qcow2 --update
virt-customize -a debian-13-genericcloud-amd64.qcow2 --timezone 'Asia/Shanghai'
virt-customize -a debian-13-genericcloud-amd64.qcow2 --install qemu-guest-agent,wget,curl,git,net-tools
virt-customize -a debian-13-genericcloud-amd64.qcow2 --run-command "systemctl enable qemu-guest-agent"

这样一个Debian13的系统image就修改好了,当然你还可以进行更多的定制化操作。

接下来是Ubuntu24.04的系统image,还是一样需要修改SSH的配置,Ubuntu24.04这个系统与Debian13有一些区别,我们需要编辑如下路径的配置文件:

virt-edit -a noble-server-cloudimg-amd64.img /etc/ssh/sshd_config.d/60-cloudimg-settings.conf

在这个配置文件内增加如下配置:

PermitRootLogin yes
PasswordAuthentication yes

更新系统到最新/设置时区/预装软件,注意这里一定要安装qemu-guest-agent并设置开机自启:

virt-customize -a noble-server-cloudimg-amd64.img --update
virt-customize -a noble-server-cloudimg-amd64.img --timezone 'Asia/Shanghai'
virt-customize -a noble-server-cloudimg-amd64.img --install qemu-guest-agent,wget,curl,git,net-tools
virt-customize -a noble-server-cloudimg-amd64.img --run-command "systemctl enable qemu-guest-agent"

将修改好的系统image传到PVE主机内:

scp debian-13-genericcloud-amd64.qcow2 [email protected]:/root/convoy-temp
scp noble-server-cloudimg-amd64.img [email protected]:/root/convoy-temp

在PVE主机使用qm命令行工具创建一台虚拟机,我使用下面的这些参数来创建,这是目前在PVE创建KVM虚拟机最佳的配置,在这个配置中使用了virtio-scsi-single作为控制器:

qm create 20000 \
--name Convoy-Debian-13 \
--cpu host \
--cores 1 \
--memory 1024 \
--machine q35 \
--bios ovmf \
--efidisk0 local-lvm:0,format=raw,efitype=4m,pre-enrolled-keys=1,size=528K \
--net0 virtio,bridge=vmbr0 \
--scsihw virtio-scsi-single \
--agent enabled=1,freeze-fs-on-backup=1,fstrim_cloned_disks=1 \
--serial0 socket \
--vga serial0

导入之前修改好的Debian13系统image/添加cloud-init设备/修改虚拟机引导顺序/配置cloud-init创建的默认用户为root/转换虚拟机为模板:

qm set 20000 --scsi0 local-lvm:0,import-from=/root/convoy-temp/debian-13-genericcloud-amd64.qcow2,cache=writeback,iothread=1,discard=on,format=raw
qm set 20000 --scsi1 local-lvm:cloudinit
qm set 20000 --boot order=scsi0
qm set 20000 --ciuser=root
qm template 20000

说明:

1.以上执行的命令假设为你的PVE存储使用的是local-lvm,如果不是请自行修改。

2.lvm设备不允许使用qcow2格式,所以这里将image的硬盘格式统一转换为raw了。

3.将iothread开启,与virtio-scsi-single进行配合以达到最佳的硬盘性能。当然cache=writeback也必不可少。

4.我这里没有使用cloud-init设置root用户的密码,这是因为后续在创建虚拟机时密码是交给ConvoyPanel来设置的。

Ubuntu24.04的系统也是一样的步骤,只是要注意使用不同的vmid和name:

qm create 20001 \
--name Convoy-Ubuntu-2404 \
--cpu host \
--cores 1 \
--memory 1024 \
--machine q35 \
--bios ovmf \
--efidisk0 local-lvm:0,format=raw,efitype=4m,pre-enrolled-keys=1,size=528K \
--net0 virtio,bridge=vmbr0 \
--scsihw virtio-scsi-single \
--agent enabled=1,freeze-fs-on-backup=1,fstrim_cloned_disks=1 \
--serial0 socket \
--vga serial0

导入之前修改好的Ubuntu24.04系统image/添加cloud-init设备/修改虚拟机引导顺序/配置cloud-init创建的默认用户为root/转换虚拟机为模板:

qm set 20001 --scsi0 local-lvm:0,import-from=/root/convoy-temp/noble-server-cloudimg-amd64.img,cache=writeback,iothread=1,discard=on,format=raw
qm set 20001 --scsi1 local-lvm:cloudinit
qm set 20001 --boot order=scsi0
qm set 20001 --ciuser=root
qm template 20001

有人可能会觉得有点奇怪,既然都用cloud-init了,为什么还要要用libguestfs-tools去修改系统image,cloud-init不是也可以支持这些操作吗?确实如此,cloud-init完全可以胜任这些操作,并且PVE本身也支持通过snippet(片段)配置文件来加载cloud-init的配置数据,我之前写的这篇文章中就详细说明过这种配置方法。但你要知道的是ConvoyPanel不支持PVE的这种snippet(片段)配置文件,ConvoyPanel在创建虚拟机时只调用cloud-init来配置系统root用户的密码以及网络配置,其他的东西是不管的。

当然,作为一种变通办法,你可以尝试使用cicustom将snippet(片段)配置文件直接附加到刚创建的系统模板内,这样在虚拟机创建的时候应该会自动应用snippet(片段)配置文件内的内容,但是我这里没有试这种方法,不确定是否可行,可能后续我会试试看。

对接Proxmox VE的准备工作

制作好系统模板后,现在就可以尝试与Proxmox VE进行集成了。步骤有点多,有点杂,我尽量写的详细一点。

首先需要在PVE主机上安装一个ConvoyPanel的终端(控制台)代理:

cd /
curl -fsSL https://github.com/convoypanel/broker/releases/latest/download/broker.tar.gz | tar -xzv

注意:必须在/目录运行上述命令,否则安装的路径不对,会导致最终用户无法使用终端(控制台)。

我是要创建IPv6 Only虚拟机,所以这里给Proxmox VE主机配置一个IPv6 DNS,后续虚拟机的cloud-init都可以直接用主机的这个DNS,不需要单独修改了:

Proxmox VE配置SSL证书、生成API Token

在生产环境中,ConvoyPanel要求Proxmox VE主机必须拥有有效的SSL证书。

转到系统–>凭证–>添加ACME账户:

填写账户名和邮箱地址,随便起个名字:

质询类型HTTP,然后填写你解析到Proxmox VE的域名(本文假设域名为pve-buf.example.com):

点击立即预定凭证来申请SSL证书:

后续就可以通过https://pve-buf.example.com:8006来访问Proxmox VE的Web UI了。

现在我们需要创建一个API令牌,转到数据中心–>权限–>API令牌–>添加:

用户选择:root@pam,取消勾选“特权分离”,有效期设置为永久:

会回显给你一个密钥,复制保存下来待会需要用到。

启用Proxmox VE的防火墙

ConvoyPanel在创建虚拟机时会使用ipset对虚拟机的网络进行限制,目的是为了防止MAC地址欺骗、IPv4/v6地址欺骗。为了让这个功能能够生效,我们需要启用PVE的防火墙功能。

首先是启用Proxmox VE数据中心级别的防火墙,为了避免把自己关在外面这种事情发生,请务必先把输入策略改为ACCEPT,或者至少先添加22、8006端口的ACCEPT规则:

然后启用对应节点级别的防火墙:

至于特定于虚拟机级别的防火墙不需要我们手动开启,ConvoyPanel在克隆系统模板创建虚拟机时会自动启用虚拟机的防火墙并添加相应的ipset规则。

在ConvoyPanel添加节点

至此所有需要在Proxmox VE上配置的内容就全部完成了。接下来转到ConvoyPanel,创建一个Location,这里演示我设置为BUF:

创建一个新的节点:

1.Display Name:输入一个名称来标识你的节点。

2.Location Group:选择之前创建的Location。

3.Node Name In Proxmox:输入与Proxmox VE节点名称相同的名称,例如我在Proxmox VE WebUI上看到的是pve,那么这里就填写pve:

4.Verify TLS Certificates:勾选此项验证TLS证书

5.Token ID:填写之前在Proxmox VE WebUI上的创建的API Token名称

6.Secret:填写之前在Proxmox VE WebUI上生成的API Token Secret

7.FQDN:输入你的Proxmox VE域名(FQDN)(不要带http/https前缀)

8.Port:输入你的Proxmox VE的端口。默认情况下为:8006

配置内存、存储、网络等信息:

9.Memory Allocation:输入ConvoyPanel管理的内存分配量(以MiB为单位)

10.Memory Overallocation:输入可以过度分配的内存百分比(%)

11.Disk Allocation:输入ConvoyPanel管理的硬盘分配大小(以MiB为单位)

12.Disk Overallocation:输入可以过度分配的硬盘空间(以MiB为单位)

13.VM Storage:填写用于保存磁盘映像的存储名称,在Proxmox VE WebUI可以看到对应的存储可以用于存储什么内容:

14.Backup Storage:输入要保存备份的存储名称。

15.ISO Storage:输入用于保存ISO文件的存储名称。

16.Network:输入你的网桥名称,本文在之前的Proxmox VE网络配置环节配置的网桥名是vmbr0。

配置IPAM

IPAM是ConvoyPanel的IP地址管理功能,ConvoyPanel会使用IPAM池里面的地址为虚拟机分配IP地址。

我们首先要创建一个Pool,指定可用的节点为刚才添加的:

填写具体的内容:

选择Multiple可以一次性创建多个地址,类型选择IPv6,填写Starting Address(开始地址)和Ending Address(结束地址)。

地址范围可以使用这个网址计算:http://www.gestioip.net/cgi-bin/subnet_calculator.cgi

例如HE IPv6 Tunnel分配给你的/48子网是2001:470:152f::1/48,那么你在网页上按下图所示填写:

然后点击如图所示位置,会列出可用的前256个地址(2001:470:152f:10::1-2001:470:152f:10::100)

把第一个地址(2001:470:152f:10::1)和最后一个地址(2001:470:152f:10::100)分别填写到Starting Address(开始地址)和Ending Address(结束地址)。

[注意]不要把整个/48子网的地址都填写上去,因为地址太多了会导致ConvoyPanel报错无法添加,并且也不方便后续管理。256个地址一般情况下足够使用了,如果还不够,可以直接在这个网页内拆分子网(subnet-level I),例如一个/48可以拆分出65536个/64:

拆分出的/64子网随便选择一个,然后重复之前的步骤即可计算出新的可用地址:

CIDR对于本文而言填写48,因为我们刚才申请的HE Tunnel IPv6子网就是/48。请注意这个CIDR不代表最终虚拟机实际可用的IPv6地址,默认情况下ConvoyPanel只会给虚拟机分配一个可用IPv6。

Gateway(网关)填写之前在vmbr0上配置的IPv6地址。

Mac Address留空,让Proxmox VE随机生成。Assigned Server留空。

配置ConvoyPanel使用Proxmox VE系统模板

转到Node–>Templates创建两个新的模板组:

在对应的模板组里面添加之前创建好的系统模板,ConvoyPanel使用vmid来匹配Proxmox VE的系统模板:

创建一台虚拟机

现在程序对接了,IPAM配置了,系统模板也配置了,是时候创建一台虚拟机了:

成功开机了:

从控制台登录进去简单测试下虚拟机的各项配置是否按预期工作:

配置Coterm隐藏Proxmox VE真实域名和IP

在刚才通过控制台访问虚拟机的时候不难发现浏览器中的URL是直接指向了Proxmox VE的真实域名的,这在生产环境中不太安全,此时Coterm就派上用场了,Coterm相当于是一个控制台代理,最终用户通过Coterm的域名来访问控制台,从而避免暴露Proxmox VE的真实域名。这是可选的,只是为了安全起见,但最好还是配置一下。如果你决定要配置Coterm,最好单独使用一台服务器进行配置。

首先在ConvoyPanel创建一个Coterm实例:

其中FQDN是一个用于提供给最终用户访问的“前端域名”,本文示例vnc-buf.example.com。当用户在前端访问vnc-buf.example.com时,请求会转发到pve-buf.example.com。

创建完成后会回显一个TOKEN,复制保存下来后续需要用到。

安装Docker和NGINX:

apt -y update
apt -y install curl nginx python3-certbot-nginx
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录新建compose文件:

mkdir /opt/coterm && cd /opt/coterm && nano docker-compose.yml

写入如下内容:

services:
  coterm:
    image: ghcr.io/convoypanel/coterm:latest
    restart: unless-stopped
    ports:
      - 127.0.0.1:2115:2115
    env_file:
      - .env

再创建一个env文件:

nano .env

写入如下内容,CONVOY_URL配置为你的ConvoyPanel面板域名,COTERM_TOKEN修改为之前你复制的值:

CONVOY_URL=https://console.example.com
COTERM_TOKEN=yourtoken
DANGEROUS_DISABLE_TLS_VERIFICATION=false

配置NGINX反向代理:

nano /etc/nginx/sites-available/coterm.conf

写入如下内容:

server {
    listen 80;
    server_name vnc-buf.example.com; # 配置Coterm的域名
    client_max_body_size 0;

    location / {
        proxy_pass http://127.0.0.1:2115;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

启用站点:

ln -s /etc/nginx/sites-available/coterm.conf /etc/nginx/sites-enabled/

签发SSL证书:

certbot --nginx

这篇文章不关心你的Proxmox VE是如何安装的,只要你的Proxmox VE能够按照这篇文章配置好HE IPv6 Tunnel,能够知道自己的Proxmox VE用的存储名是什么,那就能够按照文章里面的步骤来开小鸡,所以这篇文章没有记录Proxmox VE的安装步骤。有关ConvoyPanel与Paymenter、WHMCS等计费程序集成的步骤放到后面的文章写了。

另外ConvoyPanel的作者目前正在开发V10版本,到时候发布V10了估计有很多更新和改动,还是值得期待一下的。

OpenCloud:开源文件共享与协作平台

2025-10-09 20:50:03

不知道大伙还记得ownCloud吗,一个用PHP写的网盘程序,Nextcloud就是它的分支项目。

由于ownCloud的性能饱受诟病,所以ownCloud的开发团队几年前就用Go重写了一个ownCloud Infinite Scale(oCIS),我之前还写过一篇部署的文章,但是当时oCIS的完成度还比较低,缺少很多功能。

转眼间又是几年时间过去了,oCIS也有一个分支了,就是今天要给大伙介绍的:OpenCloud。我部署试了一下,完成度很高了,用在生产环境完全没问题,所以特地写篇文章推荐一下,个人网盘又多了一个新的选择。

下面简单列出目前OpenCloud拥有的功能(摘自项目页面):

🚀 快速、简单、干净的用户界面
⌨️ 用于快速选择文件的键盘快捷键
🖱️ 拖放支持
🔍 强大的搜索功能,可按名称、全文、OCR、文件类型、日期或标签进行搜索
🔄 可靠、容错的文件同步
🔗 灵活的共享选项
🌐 通过公开链接共享文件
🗂️工作区:专用项目文件夹,旨在简化团队协作
🛠️ 与 Markdown 编辑器(ToastUI)和 Web Office(Collabora)等工具集成
🕒 文件历史记录可跟踪更改并恢复以前的版本
📱 多设备同步,可在所有设备上离线访问

开始部署前,我们需要做一些准备工作:

1.一台内存至少4GB的服务器。(如果不部署clamav反病毒软件、apache-tika全文搜索,内存只需1-2GB)

以下是我部署的全部服务所需的内存,供参考:

其中clamav反病毒软件的部署目前没有得到官方的支持,文中的部署方法是我自己琢磨出来的,但是我估计后续和官方实装的部署方法应该大差不差=-=

2.服务器的这些端口不能被其他程序占用:

80/443/9200/9300/9980

其中80/443端口给主机的NGINX使用,用于配置反向代理。

3.添加3个域名解析A记录:

cloud.example.com
collabora.example.com
wopiserver.example.com

系统这块我使用的是Debian13,安装NGINX:

apt -y update
apt -y install curl nginx python3-certbot-nginx

安装Docker:

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

克隆这个OpenCloud Compose存储库:

cd /opt
git clone https://github.com/opencloud-eu/opencloud-compose.git
cd opencloud-compose

复制一份环境变量配置文件并编辑:

cp .env.example .env
nano .env

这里只列出必须要修改的内容,其它没有在这里列出的内容可以保持默认值:

#INSECURE=true
COMPOSE_FILE=docker-compose.yml:weboffice/collabora.yml:external-proxy/opencloud.yml:external-proxy/collabora.yml:search/tika.yml:radicale/radicale.yml:antivirus/clamav.yml
OC_DOMAIN=cloud.example.com
INITIAL_ADMIN_PASSWORD=yourpassword
OC_CONFIG_DIR=/opt/opencloud-compose/opencloud_config
OC_DATA_DIR=/opt/opencloud-compose/opencloud_data
START_ADDITIONAL_SERVICES="notifications,antivirus"
COLLABORA_DOMAIN=collabora.example.com
WOPISERVER_DOMAIN=wopiserver.example.com
COLLABORA_ADMIN_USER=imlala
COLLABORA_ADMIN_PASSWORD=yourpassword
ANTIVIRUS_MAX_SCAN_SIZE=512MB
CLAMAV_DOCKER_TAG=stable_base
RADICALE_DATA_DIR=/opt/opencloud-compose/radicale_data

1.OC_DOMAIN、COLLABORA_DOMAIN、WOPISERVER_DOMAIN修改为你的域名。

2.INITIAL_ADMIN_PASSWORD设置你的OpenCloud管理员密码。管理员的默认用户名是:admin。

3.COLLABORA_ADMIN_USER、COLLABORA_ADMIN_PASSWORD设置你的COLLABORA管理员用户名和密码。

4.如果不使用clamav反病毒功能,删除COMPOSE_FILE内的如下内容:

COMPOSE_FILE=docker-compose.yml:weboffice/collabora.yml:external-proxy/opencloud.yml:external-proxy/collabora.yml:search/tika.yml:radicale/radicale.yml:antivirus/clamav.yml

修改START_ADDITIONAL_SERVICES的值为如下内容:

START_ADDITIONAL_SERVICES="notifications"

注释掉如下内容:

ANTIVIRUS_MAX_SCAN_SIZE=512MB
CLAMAV_DOCKER_TAG=stable_base

5.如果不使用apache-tika全文搜索功能,删除如下配置:

COMPOSE_FILE=docker-compose.yml:weboffice/collabora.yml:external-proxy/opencloud.yml:external-proxy/collabora.yml:search/tika.yml:radicale/radicale.yml:antivirus/clamav.yml

6.如果不使用radicale的日历、联系人功能,删除如下配置:

COMPOSE_FILE=docker-compose.yml:weboffice/collabora.yml:external-proxy/opencloud.yml:external-proxy/collabora.yml:search/tika.yml:radicale/radicale.yml:antivirus/clamav.yml

注释掉如下内容:

RADICALE_DATA_DIR=/opt/opencloud-compose/radicale_data

创建所需的目录/给予正确的权限:

mkdir /opt/opencloud-compose/opencloud_config
mkdir /opt/opencloud-compose/opencloud_data
mkdir /opt/opencloud-compose/radicale_data # 不使用radicale可不创建
chown -R 1000:1000 opencloud_config
chown -R 1000:1000 opencloud_data
chown -R 1000:1000 radicale_data # 不使用radicale可不执行

配置clamav反病毒,创建一个名为antivirus的目录并在目录内新建一个名为clamav.yml的compose配置文件:

mkdir /opt/opencloud-compose/antivirus && cd /opt/opencloud-compose/antivirus && nano clamav.yml

写入如下内容:

services:
  opencloud:
    environment:
      ANTIVIRUS_SCANNER_TYPE: "clamav"
      ANTIVIRUS_CLAMAV_SOCKET: "/var/run/clamav/clamd.sock"
      ANTIVIRUS_MAX_SCAN_SIZE_MODE: ${ANTIVIRUS_MAX_SCAN_SIZE_MODE:-partial}
      ANTIVIRUS_MAX_SCAN_SIZE: ${ANTIVIRUS_MAX_SCAN_SIZE:-100MB}
      POSTPROCESSING_STEPS: "virusscan"
      STORAGE_USERS_DATA_GATEWAY_URL: http://opencloud:9200/data
    volumes:
      - "clamav-socket:/var/run/clamav"
  clamav:
    image: clamav/clamav:${CLAMAV_DOCKER_TAG:-latest}
    networks:
      opencloud-net:
    volumes:
      - "clamav-socket:/tmp"
      - "clamav-db:/var/lib/clamav"
    logging:
      driver: ${LOG_DRIVER:-local}
    restart: always
volumes:
  clamav-socket:
  clamav-db:

启动:

docker compose up -d

启动之后collaboration服务的容器可能会不正常,一直重启,但是没关系这是预期行为,等到我们配置好反向代理后就会恢复。

现在就来配置反向代理,新建NGINX站点配置文件:

nano /etc/nginx/sites-available/opencloud

写入如下内容:

server {
    listen 80;
    server_name cloud.example.com;
    client_max_body_size 0;

    location / {
        proxy_pass http://127.0.0.1:9200;
        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;
    }
}

server {
    listen 80;
    server_name collabora.example.com;
    client_max_body_size 0;

    location / {
        proxy_pass http://127.0.0.1:9980;
        proxy_set_header Host $host;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

server {
    listen 80;
    server_name wopiserver.example.com;
    client_max_body_size 0;

    location / {
        proxy_pass http://127.0.0.1:9300;
        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;
    }
}

启用站点:

ln -s /etc/nginx/sites-available/opencloud /etc/nginx/sites-enabled/opencloud

签发SSL证书:

certbot --nginx --email [email protected] --agree-tos --no-eff-email

两个WebUI将在如下网址提供访问:

https://cloud.example.com
https://collabora.example.com/browser/dist/admin/admin.html

使用管理员账号登录:

简单测试一下功能是否正常,全文搜索功能,新建一个docx文档,输入一段文字保存,在搜索栏搜索文档内的文字,可以搜到结果:

clamav防护测试,新建一个txt文本文件,输入测试代码,点击保存,弹出通知:

查看clamav日志:

docker compose -f docker-compose.yml -f /opt/opencloud-compose/antivirus/clamav.yml logs -f clamav

也可以看到日志内显示了相关的内容,说明配置正常:

总的来说OpenCloud还是非常不错的,我感觉要是能加个离线下载功能(aria2、qbittorrent)就更完美了。OpenCloud目前还在积极开发中,潜力很大,值得期待!

Termix:开源的一体化服务器管理平台

2025-10-07 06:33:29

Termix是一个开源、永久免费、自托管的一体化服务器管理平台。它提供了一个基于网页的解决方案,通过一个直观的界面管理你的服务器和基础设施。Termix提供SSH终端访问、SSH隧道功能以及远程文件编辑,还会陆续添加更多工具。

目前已实现的功能:

SSH 终端访问 – 功能完整的终端,支持分屏(最多 4 个面板)和标签系统
SSH 隧道管理 – 创建和管理 SSH 隧道,支持自动重连和健康监控
远程文件编辑器 – 直接在远程服务器编辑文件,支持语法高亮和文件管理功能(上传、删除、重命名等)
SSH 主机管理器 – 保存、组织和管理 SSH 连接,支持标签和文件夹
服务器统计 – 查看任意 SSH 服务器的 CPU、内存和硬盘使用情况
用户认证 – 安全的用户管理,支持管理员控制、OIDC 和双因素认证(TOTP)
现代化界面 – 使用 React、Tailwind CSS 和 Shadcn 构建的简洁界面
语言支持 – 内置中英文支持

计划功能:

增强管理员控制 – 提供更精细的用户和管理员权限控制、共享主机等功能
主题定制 – 修改所有工具的主题风格
增强终端支持 – 添加更多终端协议,如 VNC 和 RDP(有类似 Apache Guacamole 的 RDP 集成经验者请通过创建 issue 联系我)
移动端支持 – 支持移动应用或 Termix 网站移动版,让你在手机上管理服务器

安装Docker和NGINX:

apt -y update
apt -y install curl nginx python3-certbot-nginx
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录/compose文件:

mkdir /opt/termix && cd /opt/termix

写入如下配置:

services:
  termix:
    image: ghcr.io/lukegus/termix:latest
    container_name: termix
    restart: unless-stopped
    environment:
      PORT: "8080"
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - termix-data:/app/data
volumes:
  termix-data:
    driver: local

启动:

docker compose up -d

配置NGINX反向代理:

nano /etc/nginx/sites-available/termix

写入如下配置:

upstream termix {    
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name termix.example.com;
    client_max_body_size 0;

    access_log /var/log/nginx/termix_access.log;
    error_log /var/log/nginx/termix_error.log;

    location / {
        proxy_pass http://termix;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
    }
}

启用站点:

ln -s /etc/nginx/sites-available/termix /etc/nginx/sites-enabled/termix

签发SSL证书:

certbot --nginx --email [email protected] --agree-tos --no-eff-email

目前的版本有个问题,Termix在容器里面也是用的NGINX,但是容器里面的这个NGINX没有配置接收客户端的X-Forwarded-For标头,这会导致Termix获取不到客户端的真实IP,不过这问题下个版本应该就修了

访问termix.example.com创建管理员账号,登录进去后,如果你是自用的话建议把这个用户注册的功能关闭掉:

效果:

这个文件管理的功能非常牛逼,可以预览图片、听音乐,还能播放视频:

这个文件管理目前有个问题,上传大文件的时候会提示上传失败,控制台会报一个超时错误,不知道什么时候能够修复=-=我在反代的NGINX配置了下面的内容也不行:

proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;

好像是程序硬编码超时时间为30秒了。。但最终文件还是上传成功了就是。。

Campfire:一款基于Web的聊天应用程序

2025-10-06 10:31:25

Campfire是一款基于Web的聊天应用程序。它支持许多功能,目前包括:

多个聊天房间(具有访问控制)
私聊
文件上传与预览支持
搜索
通知(使用Web Push)
@提及
支持机器人集成

我搭建了一个试了下体验还不错,给小团体用的话足够了,完全公开当成公共实例的话,我个人认为还少了以下几个关键功能:

禁止用户(开发中)
找回密码(开发中)
表情包支持,目前只支持几个emoji。
更细粒度的权限控制,目前的权限控制比较单一,只能控制房间是完全公开还是私有。

这项目非常值得期待,背后是Basecamp的团队在开发!

考虑到官方提供的Docker部署方案需要占用80/443端口,这里我记录下用NGINX反代部署的方案。

安装NGINX、Node.js、NPM:

apt -y update
apt -y install curl nginx python3-certbot-nginx nodejs npm

安装Docker:

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

安装web-push:

npm install -g web-push

使用web-push生成vapid-key:

web-push generate-vapid-keys

会回显类似的内容,复制下来保存,后续部署需要用到:

Public Key:
BKnuy5nGRaA2uuuonErTAUpH4Moil5w7J3RqWgtklf46h5YIpY-rxiR8GQ8z-3YOgZ1RfeWu1AheG8EeHhgx_04
Private Key:
vvqVf2ZDnMqY4N-xXEOwgqw1ntslfEb0Eq8aUHwfBsE

由于官方没有提供最新的预构建docker image,需要我们自己build一下。这里介绍一个小技巧,对于这种目录里有Dockerfile的项目,不需要把整个项目clone到本地再构建,直接用下面的命令就能构建了:

docker build -t campfire:latest https://github.com/basecamp/once-campfire.git#main

创建目录/compose文件:

mkdir -p /opt/campfire && cd /opt/campfire && nano docker-compose.yml

写入如下配置:

services:
  campfire:
    image: campfire:latest
    container_name: campfire
    restart: unless-stopped
    environment:
      - DISABLE_SSL=true
      - SECRET_KEY_BASE= # 使用openssl rand -hex 32生成
      - VAPID_PUBLIC_KEY= # 粘贴web-push生成的公钥
      - VAPID_PRIVATE_KEY= # 粘贴web-push生成的私钥
    ports:
      - "127.0.0.1:4000:80"
    volumes:
      - campfire_data:/rails/storage
volumes:
    campfire_data:

启动:

docker compose up -d

创建NGINX站点配置文件:

nano /etc/nginx/sites-available/campfire

写入如下内容:

upstream campfire {    
    server 127.0.0.1:4000;
}

server {
    listen 80;
    server_name campfire.example.com;
    client_max_body_size 10m; # 限制文件上传大小,根据自己的需要修改

    access_log /var/log/nginx/campfire_access.log;
    error_log /var/log/nginx/campfire_error.log;

    location /cable {
        proxy_pass http://campfire;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    location / {
        proxy_pass http://campfire;
        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_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

启用站点:

ln -s /etc/nginx/sites-available/campfire /etc/nginx/sites-enabled/campfire

签发SSL证书:

certbot --nginx --email [email protected] --agree-tos --no-eff-email

访问campfire.example.com注册你的账号,第一个注册的账号默认为管理员:

效果: