前提
本文假设你以安装Mysql 8、 redis、Nginx ,部署本系统需要至少4GB内存的服务器,本文以Ubuntu 或兼容Centos8的linux发行版(Alibaba linux 3.x)为例
注意:因为centos7在安装node最新版时可能会遇到一些问题,所以不建议使用
注意:以下教程不适用于宝塔面板,但是可以参考以下教程来使用宝塔面板来部署
1、安装Node
使用 n 来安装node last ltc
curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n | bash -s lts
若未安装curl,使用以下命令安装
Centos:
yum install curl
Ubuntu:
apt-get install curl
2、安装pnpm 和 pm2
npm i -g pnpm
npm i -g pm2
3、克隆项目
克隆后端项目
git clone https://gitee.com/polarbear88/authdog.git
克隆前端项目
git clone https://gitee.com/polarbear88/authdog-ui.git
若未安装git,使用以下命令安装
Centos
yum install git
Ubuntu
apt-get install git
4、配置后端项目
安装gcc gc++ 用于云函数的运行
Centos
yum install gcc72 gcc72-c++
Ubuntu
sudo apt-get install python g++ build-essential gcc
cd到后端目录
cd authdog
安装依赖
pnpm i
注意:内存低于4G会卡住不动
复制一份env文件
cp .env .env.prod
配置env
将.env.prod按照说明进行配置
开发环境时 复制一份到 .env.dev 中 生产环境时 复制一份到 .env.prod 中
APP 配置
APP_PORT =3000
APP_JWT_SECRET = # JWT密钥 32位 随便找个md5小写字符串
TCP_API_PORT = 3001 # TCP API端口
TRUST_PROXY = # 是否信任代理 如果开启了nginx反向代理转发,需要开启此项
DISABLE_DEVELOPER_REGISTER = false # 是否禁止开发者注册
DATABASE 数据库配置
DATABASE_HOST = # 数据库地址
DATABASE_PORT = # 数据库端口
DATABASE_USERNAME = # 数据库用户名
DATABASE_PASSWORD = # 数据库密码
DATABASE_NAME = # 数据库名
DATABASE_SYNCHRONIZE = true # 是否同步数据库结构
请求频率限制
秒
THROTTLE_TTL = 60
次数
THROTTLE_LIMIT = 300
Redis配置
REDIS_HOST = # Redis地址
REDIS_PORT = # Redis端口
REDIS_PASSWORD = # Redis密码
IP归属地接口配置
IP_API_KEY = # 购买地址https://market.aliyun.com/products/57002003/cmapi021970.html
验证配置
GEETEST_ID_LOGIN = # 极验验证ID 登录时使用
GEETEST_KEY_LOGIN = # 极验验证KEY 登录时使用
GEETEST_ID_REGISTER = # 极验验证ID 注册或获取验证码时使用
GEETEST_KEY_REGISTER = # 极验验证KEY 注册或获取验证码时使用
VALIDATE_ENABLE_LOGIN = # 是否开启登录极验验证
VALIDATE_ENABLE_REGISTER = # 是否开启注册极验验证
VALIDATE_ENABLE_SENDSMS = # 发送短信验证码时是否开启极验验证
阿里云短信配置
ALIYUN_ACCESS_KEY_ID = # 阿里云短信服务的AccessKey ID
ALIYUN_ACCESS_KEY_SECRET = # 阿里云短信服务的AccessKey Secret
ALIYUN_SMS_SIGN_NAME = # 短信签名
ALIYUN_SMS_TEMPLATE_CODE = # 短信模板ID
是否开启开发者注册时的短信验证
DEVELOPER_REGISTER_ENABLE_SMS = false
Redis后面的配置均可留空
TRUST_PROXY 设置为 true
注意:首次启动DATABASE_SYNCHRONIZE 必须为true,不然无法自动同步模型到表
5、尝试启动后端项目
npm run start
稍等片刻,若一切正常你将看到
[zxsq-anti-bbcode-Nest] 48984 – 2023/04/17 14:06:14 LOG [zxsq-anti-bbcode-NestApplication] Nest application successfully started +10ms
...(其他信息)
[zxsq-anti-bbcode-Nest] 48984 – 2023/04/17 14:06:14 LOG [zxsq-anti-bbcode-NestMicroservice] Nest microservice successfully started +2ms
好了选择可以按下 Ctrl + C 来关闭运行了,因为下面我们要使用PM2来将项目运行在后台
6、启动后端项目
pm2 start npm — run start
设置PM2开机自动启动项目
pm2 startup
pm2 save
好了,到此Authdog的后端项目已经成功运行了,接下来我们配置前端
7、配置和编译前端项目
目前我们的目录是位于 authdog,让我们切换到authdog-ui
cd ..
cd authdog-ui
安装依赖
pnpm i
复制一份env
cp .env.pro.bak .env.pro
配置env
部署时请复制.env.pro.bak并重命名为.env.pro
环境
NODE_ENV=production
接口前缀
VITE_API_BASEPATH=pro
打包路径
VITE_BASE_PATH=/
是否删除debugger
VITE_DROP_DEBUGGER=true
是否删除console.log
VITE_DROP_CONSOLE=true
是否sourcemap
VITE_SOURCEMAP=false
输出路径
VITE_OUT_DIR=dist-pro
标题
VITE_APP_TITLE=Authdog
代理专用域名 不设置则不会启用代理访问专属域名功能
VITE_SALER_DOMAIN=
帮助文档地址
VITE_HELP_URL=https://ronmbudjli.apifox.cn/doc-2299586
购卡地址
VITE_BUY_URL=https://ronmbudjli.apifox.cn/
第一步,我们配置编译后文件输出路径
VITE_OUT_DIR=/data/www/dist-pro
这里使用的目录为/data/www/ ,服务器一般不存在这个目录,我们需要手动创建
mkdir /data
mkdir /data/www
如果你拥有域名并且使用域名来访问Authdog而不是IP的话,则配置
VITE_SALER_DOMAIN=saler.yourdomain.com
你需要解析一个saler的二级域名到服务器
注意:此配置并不是必须的,它用于区分代理和开发者的访问,使得代理和开发者使用的不是一个域名,从而更好的隔离两者,没有域名则不配置
编译前端项目
pnpm run build:pro
稍等片刻,完成后你配置的输出目录中应该有文件了
8、配置Nginx
默认情况下使用yum或者apt-get安装的nginx其配置文件在
如果你使用域名来访问站点请解析以下几个二级域名到服务器
developer.xxx.com
saler.xxx.com
api.xxx.com
/etc/nginx/nginx.conf
使用域名的示例配置
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 51200;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
access_log off;
server_names_hash_bucket_size 512;
client_header_buffer_size 16k;
large_client_header_buffers 4 32k;
client_max_body_size 2m;
tcp_nodelay on;
server_tokens off;
server {
listen 80;
server_name developer.authdog.cn;
index index.html;
root /data/www/dist-pro;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
location /api {
proxy_pass http://127.0.0.1:3000;
}
}
server {
listen 80;
server_name saler.authdog.cn;
index index.html;
root /data/www/dist-pro;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
location /api {
proxy_pass http://127.0.0.1:3000;
}
}
server {
listen 80;
server_name api.authdog.cn;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
return 404;
}
location /api {
rewrite ^/api/1e382f852e058b07baaa3ae727147b82 /api/v1/user/public/register last;
rewrite ^/api/de1fd239a769f30c3393b0e0f043a16d /api/v1/user/public/login last;
rewrite ^/api/316dbfc31092de00e37ad1d015d471ea /api/v1/user/public/change-password last;
rewrite ^/api/03f483c7bb0db338ac15ae12351fd0f2 /api/v1/user/public/unbind last;
rewrite ^/api/66c1c31c37afd1d16f47b2331f904dbf /api/v1/user/public/recharge last;
rewrite ^/api/10c67bcd7f484c9d70b65ca4f94f81a9 /api/v1/user/poll last;
rewrite ^/api/1e3808ba482e222d9232dcc543eeb25c /api/v1/user/reduce-count last;
rewrite ^/api/9e691c34dfc172db00de65d258249163 /api/v1/device/auth last;
rewrite ^/api/7f65d0e283e5839ee9e305488eea9625 /api/v1/device/recharge last;
rewrite ^/api/31acedea9dbfcc86cc12cc3668429438 /api/v1/device/info last;
rewrite ^/api/de282162029e8a6dcc56fdc7d4f7e1a7 /api/v1/device/reduce-count last;
rewrite ^/api/035ef62bfc710330d1cedbce2f6428be /api/v1/cloudvar/get last;
rewrite ^/api/fe04fefefbf9d8af1269d22b7e5c453f /api/v1/cloudfun/run last;
rewrite ^/api/7dcaeb810dc2c4716e086d75eaa6d7a6 /api/v1/userdata/create last;
rewrite ^/api/a7e6a917e7b5e6aab7006b4e786166de /api/v1/userdata/getByUniqueValue last;
rewrite ^/api/a42fd86236ebb4cf46e504f560c01145 /api/v1/userdata/getListByName last;
rewrite ^/api/a42fd86236ebb4cf46e504f560c01145 /api/v1/userdata/getListByName last;
rewrite ^/api/1289daceb865589bb02aa9b2c7a0a87b /api/v1/userdata/delete last;
rewrite ^/api/e3596f556ad723a5aaf52f643bfdbeaa /api/v1/userdata/update last;
rewrite ^/api/9698493cedafb22acfceb658b258cee2 /api/v1/app/info last;
rewrite ^/api/46461bbb2143b5710f8b906375eb043b /api/v1/feedback/send last;
proxy_pass http://127.0.0.1:3000;
}
}
}
请将以上server_name配置的域名换成你的域名
如果你使用IP访问站点则以下配置适用
使用IP访问的配置示例
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 51200;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
access_log off;
server_names_hash_bucket_size 512;
client_header_buffer_size 16k;
large_client_header_buffers 4 32k;
client_max_body_size 2m;
tcp_nodelay on;
server_tokens off;
server {
listen 80;
server_name 你的外网IP地址;
index index.html;
root /data/www/dist-pro;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
location /api {
rewrite ^/api/1e382f852e058b07baaa3ae727147b82 /api/v1/user/public/register last;
rewrite ^/api/de1fd239a769f30c3393b0e0f043a16d /api/v1/user/public/login last;
rewrite ^/api/316dbfc31092de00e37ad1d015d471ea /api/v1/user/public/change-password last;
rewrite ^/api/03f483c7bb0db338ac15ae12351fd0f2 /api/v1/user/public/unbind last;
rewrite ^/api/66c1c31c37afd1d16f47b2331f904dbf /api/v1/user/public/recharge last;
rewrite ^/api/10c67bcd7f484c9d70b65ca4f94f81a9 /api/v1/user/poll last;
rewrite ^/api/1e3808ba482e222d9232dcc543eeb25c /api/v1/user/reduce-count last;
rewrite ^/api/9e691c34dfc172db00de65d258249163 /api/v1/device/auth last;
rewrite ^/api/7f65d0e283e5839ee9e305488eea9625 /api/v1/device/recharge last;
rewrite ^/api/31acedea9dbfcc86cc12cc3668429438 /api/v1/device/info last;
rewrite ^/api/de282162029e8a6dcc56fdc7d4f7e1a7 /api/v1/device/reduce-count last;
rewrite ^/api/035ef62bfc710330d1cedbce2f6428be /api/v1/cloudvar/get last;
rewrite ^/api/fe04fefefbf9d8af1269d22b7e5c453f /api/v1/cloudfun/run last;
rewrite ^/api/7dcaeb810dc2c4716e086d75eaa6d7a6 /api/v1/userdata/create last;
rewrite ^/api/a7e6a917e7b5e6aab7006b4e786166de /api/v1/userdata/getByUniqueValue last;
rewrite ^/api/a42fd86236ebb4cf46e504f560c01145 /api/v1/userdata/getListByName last;
rewrite ^/api/a42fd86236ebb4cf46e504f560c01145 /api/v1/userdata/getListByName last;
rewrite ^/api/1289daceb865589bb02aa9b2c7a0a87b /api/v1/userdata/delete last;
rewrite ^/api/e3596f556ad723a5aaf52f643bfdbeaa /api/v1/userdata/update last;
rewrite ^/api/9698493cedafb22acfceb658b258cee2 /api/v1/app/info last;
rewrite ^/api/46461bbb2143b5710f8b906375eb043b /api/v1/feedback/send last;
proxy_pass http://127.0.0.1:3000;
}
}
}
将“你的外网IP地址” 换成你的外网IP地址
9、设置目录权限
为了使nginx能够有权限访问前端项目编译的输出目录,你需要设置权限
sudo chmod 777 /data/www
10、重启nginx并尝试访问
systemctl restart nginx
然后尝试访问你的域名或IP
11、更新代码如果需要更新开源使用以下命令更新到最新版本
更新后端
cd authdog
git pull
pm2 restart all
更新后端会重启服务导致十几秒无法访问,请在不影响用户前提下更新
更新前端
cd authdog-ui
git pull
pnpm run build:pro
补充:你还需要执行以下SQL来创建默认配额:
INSERT INTO quota(name, chinaName, maxAppCount, maxUserCount, maxCloudfunCount, maxUserDataCount, maxSalerCOunt, price) VALUES('default', '开源用户', 999999, 9999999, 9999999, 99999999, 999999, 0)
至此结束