目前,paopao-ce 存在这样几个问题:
截至目前,使用 ZincSearch 尚无法进行搜索和日志两服务,还在研究中。
本文适用于小规模生产部署(比如,自己只有一个乞丐小煮鸡,做出来服务只给你自己或者你认识的朋友),MinIO 之类的对象存储统统不用(太高射炮打蚊子了也)……
首先,出于安全起见,先新建一个专门的用户,这个用户是不给管理员权限的,不能把它添加到 sudo 组中:
sudo adduser paopao
安全起见,所有 Paopao-ce 的进程都使用普通权限运行,占用高位端口,然后再通过 Nginx 反代,将其反代到域名下的路由或者子域名中。
为了能后面和 Web 目录互通文件方便,先新建一个 public 目录,并授予 777 权限:
sudo mkdir /home/public/ sudo chmod a+rw /home/public/
然后先安装基本的 lemp。我在这里使用的是 Oneinstack。当然,使用一般的包管理器安装应该也可以。
安装完成后,使用 Oneinstack 提供的 vhost.sh 先新建一个 virtual host,然后配置好 ssl 访问。如果你使用的是 CloudFlare,需要在 CloudFlare 里新建源站证书(在 SSL/TLS -> Origin Server 中),下载下来私钥和证书以后,放在服务器当中你喜欢的目录里面,配置 Nginx 使用该证书和私钥文件:
server { listen 80; listen 443 ssl http2; ssl_certificate /usr/local/etc/cf-ssl/site-prod/site-prod.cer; //证书 ssl_certificate_key /usr/local/etc/cf-ssl/site-prod/site-prod.pri; //私钥 ssl_protocols TLSv1.2 TLSv1.3; ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-E> ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SH> ssl_conf_command Options PrioritizeChaCha; ssl_prefer_server_ciphers on; ssl_session_timeout 10m; ssl_session_cache shared:SSL:10m; ssl_buffer_size 2k; add_header Strict-Transport-Security max-age=15768000; ...
注意:
在生产前,请确保 Nginx 关闭了 directory listing 或类似功能。在网站静态文件目录(我这里是 /data/wwwroot/<sitename>)为空的情况下,直接访问该域名的目录,此时应该报一个 403 错误。如果是此情况,则继续按照此文档进行操作。
如下,先使用包管理器安装。如果你运行有 Oneinstack,务必不要让它自己装数据库:
sudo apt install golang nodejs npm mariadb-server
然后需要安装 zincsearch。如下:
wget https://github.com/zincsearch/zincsearch/releases/download/v0.4.7/zincsearch_0.4.7_Linux_x86_64.tar.gz tar -zxf zincsearch_0.4.7_Linux_x86_64.tar.gz sudo mkdir -p /usr/local/zinc/ sudo mkdir -p /data/zinc/ sudo cp zincsearch /usr/local/zinc/ sudo chown -R paopao /data/zinc/ sudo chmod a+x /usr/local/zinc/zincsearch
写一个 systemd 文件,管理 zincsearch 启动:
[Unit] Description=Zinc data search service After=network.target StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=paopao ExecStart=/usr/local/zinc/zincsearch Environment="ZINC_DATA_PATH=/data/zinc/" [Install] WantedBy=multi-user.target
现在需要首次启动 zincsearch 并创建用户,如下:
ZINC_FIRST_ADMIN_USER=admin ZINC_FIRST_ADMIN_PASSWORD=Complexpass#123 ZINC_DATA_PATH=/data/zinc/ /usr/local/zinc/zincsearch
为安全起见,创建一个单独的用户,配置一个单独的权限组,把用户放在权限组里面,给它单独给 index。
设置完后开始处理 MariaDB。
之所以这里不建议使用 MySQL 的原因在于。MariaDB 在 secure_installation 时,可以方便地配置使用 unix socket 来鉴权,我一般的习惯是先使用 sudo 进去创建常规权限的用户,再给他们配置权限。这样在维护时直接使用 sudo mariadb 进数据库,方便又安全。
先使用 sudo mariadb_secure_installation 走完 secure_installation 流程之后,使用 sudo 直接登录进去,开始处理用户和数据库:
create database paopao; create user 'paopao'@'localhost'; alter user 'paopao'@'localhost' identified by aohw3yfuawhgfou3h4fgou34f; grant all privileges on paopao.* to 'paopao'@'localhost';
安全起见,只能给这个创建的普通用户这一个数据库的权限。
值得注意的是,如果创建数据库用户时不指定 @localhost,则应该在 config.yaml 配置中写出数据库的地址和端口(比如127.0.0.1:3306),而不是使用 0.0.0.0 来进行连接。从安全层面上而言,0.0.0.0 的设定会使得任意的 IPv4 地址都能与数据库连接,将会导致安全问题。
检查所有新增的系统服务:
ls /etc/systemd/system
dbus-org.freedesktop.timesync1.service php-fpm.service
getty.target.wants sockets.target.wants
multi-user.target.wants sshd.service
mysql.service sysinit.target.wants
network-online.target.wants timers.target.wants
nginx.service zinc.service
目前应该至少有 mysql、nginx、zinc 这几个服务。把它们全部设置为开机自启,并启动:
sudo systemctl enable mysql nginx zinc sudo systemctl start mysql nginx zinc
首先切换进 paopao 用户。在创建该用户时建议也不要给它赋予用户密码,需要使用时,使用 su 命令切换过去:
sudo su - paopao
在家目录中,直接使用 git 下载软件代码:
git clone https://github.com/rocboss/paopao-ce
然后将 scripts 中提供的 paopao-mysql.sql 文件导入 MariaDB 中。
由于等会儿要使用 web 目录下的东西,所以也不要直接下载提供的二进制。升级时,使用二进制文件替换即可。
在配置文件中,要着重关注以下几个方面:
在小规模部署中,我们需要开以下几个服务。模仿之前功能集的格式,新建一个功能集填入服务名字就行:
然后需要改配置里面的几个位置:
LocalOSS 的路由是写死了一部分在 paopao-ce 的核心代码里的。无论如何,假如你不做反向代理的话,路由里都会存在一个 /oss/。它的代码大概是这样:
package localoss import ( "path/filepath" "github.com/gin-gonic/gin" api "github.com/rocboss/paopao-ce/auto/api/s/v1" "github.com/rocboss/paopao-ce/internal/conf" "github.com/sirupsen/logrus" ) // RouteLocalOSS register LocalOSS route if needed func RouteLocalOSS(e *gin.Engine) { savePath, err := filepath.Abs(conf.LocalOSSSetting.SavePath) if err != nil { logrus.Fatalf("get localOSS save path err: %v", err) } e.Static("/oss", savePath) logrus.Infof("register LocalOSS route in /oss on save path: %s", savePath) } // RouteLocaloss register LocalOSS route if needed func RouteLocaloss(e *gin.Engine) { api.RegisterUserServant(e, newUserSrv(), newUserBinding(), newUserRender()) }
还有这样:
... else if cfg.If("LocalOSS") { if !LocalOSSSetting.Secure { uri = "http://" } return uri + LocalOSSSetting.Domain + "/oss/" + LocalOSSSetting.Bucket + "/" } return uri + AliOSSSetting.Domain + "/" }
看到了吗?
也就是说,当 API 接口生成路由的时候,他会按照上面的那个代码生成路由;在 API 的返回里返回图片的网址的时候,他则会按照下面的这个代码,使用字符串拼接的方式生成网址。不管怎么样,网址里面是有一个 oss 在里面的。这个 oss 是分别写死在路由生成和 API 返回的代码里面的。
你需要修改 LocalOSS 配置文件节点,不然容易出现最后在调试器看到文件变成从 127.0.0.1:8080 出来,加载失败的情况。注意,你要修改的配置节点是 LocalOSS,而不是 LocalossServer:
t.example.net/<你的名字>
;cdn.example.net
。另外,假如你需要把 LocalOSS 下挂在别的域名,则应该在 Nginx 中新起一个 vhost,然后按照 LocalossServer(注意不是 LocalOSS)的端口号,在 Nginx 中进行反代。
接下来,我们来考虑 Nginx。
这里配置反代大概应该这样写,我问了下 ChatGPT,大概是这样的
location /api/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:8008/; location ~ ^\/api\/oss\/(.*)$ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:8008/oss/$1; } }
127.0.0.1:8008 是主站 API 的地址。这个规则用来把 API 服务挂载在 /api/
这个子目录下。
如果 location /api/ 这里末尾是带有斜杠的,那么在里面这个 proxy_pass 的网址末尾也应该有斜杠,否则会报 404 错误。
在这个 /api/ 的 location block 中,又套了一个 location block。location 后面的波浪线,表示这条规则进入正则表达式模式。这里分三种情况:
^\/api\/oss\/(.*)$
;^\/<你的名字>\/<你的名字>\/(.*)$
,比如就改成 ^\/static\/(.*)$
;location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:8008/oss/; }
即可。
在项目目录中切进 web 目录,然后编辑 .env
文件:
/api/
,请将 VITE_HOST
填写成对应的目录名字,比如就填成 api
。VITE_ENABLE_ANOUNCEMENT
设为 true。VITE_ENABLE_WALLET
设为 true。VITE_DEFAULT_TWEET_IMAGE_404
,变成你自己 LocalOSS 里面的。然后修改 package.json
,修改里面的 build 命令,改成 node --max_old_space_size=4096 node_modules/vite/bin/vite.js build
,总之就是允许 Node 打包时占用更多的内存,不然会 OOM。(emmm……)
然后在 web 目录运行 yarn build
。
最后,通过 rsync 把 web/dist 下的文件同步给 nginx 的网站目录就行。
可以修改一下最后生成的那个 manifest.json,在那里可以改改网站名字之类的。
写一个 systemd 文件,这样就可以通过 systemctl 控制 paopao-ce 的行为(日志的话,要么在 Zinc 里看,要么在日志文件里看)。
从终端直接启动的时候,我是用这个命令:
GIN_MODE=release GOMAXPROCS=4 ./paopao-ce-build --no-default-features --features prod
写成配置文件就这样:
[Unit] Description=Paopao-ce After=network.target StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=paopao WorkingDirectory=/home/paopao/paopao-ce Environment="GIN_MODE=release" "GOMAXPROCS=4" ExecStart=/home/paopao/paopao-ce/paopao-ce --no-default-features --features prod [Install] WantedBy=multi-user.target
值得一提的是,这个泡泡服务存在一种离谱的机控,如果用户没有填手机号,就强制不允许你发表图片和帖子。这时候只需要改下数据库,输入一个空的电话号在里面,你就能愉快地发帖了。