LAF云开发简单私有化部署(HTTPS)
💧

LAF云开发简单私有化部署(HTTPS)

Created
Jul 7, 2022 08:29 AM
Tags

目录

官方提供了两种部署方式, 分别为k8s和单机的docker-compose, 本篇是基于docker-compose单机部署的

架构图(可能不太准确)

notion image
 

0. 前提要求

以xxx.com域名为例, 需要先申请 *.xxx.com 的泛解析证书并下载key和crt文件(也可以先阅读第6节自动生成一次泛解析证书)
(免费的泛解析证书, 且可以自动续约的工具acme.sh参考第6节)
(使用单域名证书也可以, 只需要每次创建应用之后配置下网关, 参考第5节)
(推荐使用泛域名解析, 第5节可以不用看了)
在域名管理平台增加一条A记录, 主机名为*, 解析到准备安装laf的服务器的IP

1. 环境安装

安装Docker可以使用DaoCloud一键安装脚本
sudo curl -sSL https://get.daocloud.io/docker | sh
安装docker-compose可以在下面这个地址下载
下载完成后上传到服务器上并建立软连接, 比如
ln -s /opt/docker-compose /usr/bin/docker-compose
使用 docker-compose version 命令确认版本 (最好下载最新版, 亲测使用1.18版本会不支持docker-compose.yml中的一些语法)
给docker-compose增加运行权限
chmod +x docker-compose

2. 下载并配置laf

以下是官方说明中给出的一些前置配置
# 下载laf项目 git clone https://github.com/labring/laf.git # 注意后面所有docker-compose操作都要在laf/deploy/路径下操作 cd laf/deploy/docker-compose # 创建docker网络 docker network create laf_shared_network --driver bridge || true # 拉取镜像 docker pull lafyun/app-service:latest
以下是需要修改的一些配置
2.1 修改deploy/docker-compose/docker-compose.yml文件
deploy/docker-compose/docker-compose.yml中的gateway是用的官方直接打包好的镜像文件, 需要替换为 openresty的镜像, 然后增加几条volumes配置, 如下面标红的配置
gateway: image: openresty/openresty:latest depends_on: - system-server - mongo environment: DEPLOY_DOMAIN: "*.${DEPLOY_DOMAIN:?err}" DEPLOY_OSS_DOMAIN: ${OSS_DOMAIN} SYS_CLIENT_HOST: ${SYS_CLIENT_HOST:?err} SYSTEM_EXTENSION_APPID: ${SYSTEM_EXTENSION_APPID} command: "sh /scripts/start.sh" ports: - ${PUBLISH_PORT:-8080}:80 networks: - laf_shared_network volumes: - /cert:/cert - /nginx-conf:/etc/nginx/conf.d - ../../packages/gateway/scripts:/scripts - ../../packages/gateway/conf.docker:/conf.docker
其中- /cert:/cert这一条是把宿主机的/cert文件夹映射到容器内/cert目录, 为了方便以后替换CA证书
其中- /nginx-conf:/etc/nginx/conf.d是为了方便更新容器内的nginx配置文件
2.2 上传CA证书到服务器备用
在服务器上创建 /cert 目录, 把CA证书上传到/cert目录中, 分别更名为tls.crt tls.key
2.3 修改deploy/docker-compose/.env文件
只需要修改下面这几项配置
# 注意把默认用户的密码改掉 INIT_ROOT_ACCOUNT_PASSWORD=xxxxxx # 对外提供服务绑定的端口 PUBLISH_PORT=443 # 服务部署的URL前缀 APP_SERVICE_DEPLOY_URL_SCHEMA=https # 服务部署的域名 DEPLOY_DOMAIN=xxx.com # LAF控制台的域名 SYS_CLIENT_HOST=console.xxx.com # MINIO云存储的域名 OSS_DOMAIN=oss.xxx.com

3. 启动LAF并调整nginx配置文件

执行docker-compose up 或者 docker-compose up -d 启动LAF (-d表示后台运行)
宿主机上的/nginx-conf目录就是容器中的nginx配置文件所在目录, 修改里面的app.conf文件, 主要修改内容为下面标红的部分
其中 ssl表示开启ssl, ssl_certificate 是证书, ssl_certificate_key是私钥
# for app service server { listen 80 ssl; server_name *xxx.com; client_max_body_size 0; ssl_certificate /cert/tls.crt; ssl_certificate_key /cert/tls.key; gzip on; gzip_min_length 10k; gzip_comp_level 1; gzip_vary on; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/json font/ttf font/otf image/svg+xml; location / { # Allow CORS add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS always; add_header Access-Control-Allow-Headers * always; add_header Access-Control-Expose-Headers * always; add_header Access-Control-Max-Age 3600 always; if ($request_method = 'OPTIONS') { return 204; } # Resolve app service resolver 127.0.0.11; if ($host ~* "^([0-9a-z]{3,32})\.(.+)$") { set $appid $1; set $service_id app-$appid; } proxy_pass http://$service_id:8000; add_header appid $appid; proxy_read_timeout 600s; proxy_set_header Host $host; proxy_http_version 1.1; # Upgrade websocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Logging log_by_lua_block { ngx.log(ngx.ERR, ngx.var.appid, ',', ngx.var.service_id, ',', ngx.var.request_uri) } } }
剩下两个conf文件配置与上面一致, 注意不要修改server_name
修改完成之后, 执行docker ps查找到image为openresty/openresty:latest, names为docker-compose-gateway-1 的容器, 复制它的容器ID
执行下面的命令进入容器
docker exec -it 容器ID bash
在容器中执行 nginx -t 校验配置文件是否正确
在容器中执行 nginx -s reload 重新加载nginx配置

4. 浏览器中打开 console.xxx.com 访问控制台 泛域名解析的配置到此完成

PS: 在注册完必须的用户之后, 因为默认开源版本的注册方式是可以随意注册的, 所以如果想为了防止别人恶意注册, 可以关闭注册通道
  1. docker ps找到system-server所在的容器, 使用 docker exec -it 容器ID /bin/sh 进入容器环境
  1. vi /app/dist/handler/account/signup.js 编辑脚本文件, 可以在 handleSignUp 函数入口中加入一行 : return res.send({error: 'Are you thinking of patch?'}); 表示车门已焊死, 你在想patch, :wq 保存脚本
  1. exit退出容器, 执行 docker restart 容器ID 重启此容器
PS: 修改创建应用的规格可以直接修改sys_specs集合中的文档

5. 免费的单域名CA证书配置方式

首先需要申请 console.xxx.com, xxx.com, oss.xxx.com 这三个域名的证书, 放在/cert目录下, crt和key文件分别更改为你喜欢的名称, 依次配置/nginx-conf目录下的 system.conf, app.conf, oss.conf文件, 让各自域名的证书各自指向它自己的证书, 如
#system.conf ssl_certificate /cert/console-tls.crt; ssl_certificate_key /cert/console-tls.key; #app.conf # 注意app.conf中server_name需要把 *.xxx.com 修改为 xxx.com server_name xxx.com; ssl_certificate /cert/app-tls.crt; ssl_certificate_key /cert/app-tls.key; #oss.conf ssl_certificate /cert/oss-tls.crt; ssl_certificate_key /cert/oss-tls.key;
在LAF控制台新增一个应用, 记住应用的ID, 比如 新增应用的应用ID为 7825du
申请 7825du.xxx.com 的单域名CA证书, 并上传到/cert目录中
把app.conf中的 server块 复制一份, 修改以下配置
server_name 7825du.xxx.com; ssl_certificate /cert/7825du-tls.crt; ssl_certificate_key /cert/7825du-tls.key;
配置文件全部内容如下
# for app service server { listen 80 ssl; server_name xxx.com; client_max_body_size 0; ssl_certificate /cert/app-tls.crt; ssl_certificate_key /cert/app-tls.key; gzip on; gzip_min_length 10k; gzip_comp_level 1; gzip_vary on; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/json font/ttf font/otf image/svg+xml; location / { # Allow CORS add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS always; add_header Access-Control-Allow-Headers * always; add_header Access-Control-Expose-Headers * always; add_header Access-Control-Max-Age 3600 always; if ($request_method = 'OPTIONS') { return 204; } # Resolve app service resolver 127.0.0.11; if ($host ~* "^([0-9a-z]{3,32})\.(.+)$") { set $appid $1; set $service_id app-$appid; } proxy_pass http://$service_id:8000; add_header appid $appid; proxy_read_timeout 600s; proxy_set_header Host $host; proxy_http_version 1.1; # Upgrade websocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Logging log_by_lua_block { ngx.log(ngx.ERR, ngx.var.appid, ',', ngx.var.service_id, ',', ngx.var.request_uri) } } } server { listen 80 ssl; server_name 7825du.xxx.com; client_max_body_size 0; ssl_certificate /cert/7825du-tls.crt; ssl_certificate_key /cert/7825du-tls.key; gzip on; gzip_min_length 10k; gzip_comp_level 1; gzip_vary on; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/json font/ttf font/otf image/svg+xml; location / { # Allow CORS add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS always; add_header Access-Control-Allow-Headers * always; add_header Access-Control-Expose-Headers * always; add_header Access-Control-Max-Age 3600 always; if ($request_method = 'OPTIONS') { return 204; } # Resolve app service resolver 127.0.0.11; if ($host ~* "^([0-9a-z]{3,32})\.(.+)$") { set $appid $1; set $service_id app-$appid; } proxy_pass http://$service_id:8000; add_header appid $appid; proxy_read_timeout 600s; proxy_set_header Host $host; proxy_http_version 1.1; # Upgrade websocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Logging log_by_lua_block { ngx.log(ngx.ERR, ngx.var.appid, ',', ngx.var.service_id, ',', ngx.var.request_uri) } } }
进入网关容器, 执行nginx -s reload刷新nginx配置
如果再新增应用, 则再把server块 复制一份, 修改相关配置即可

6. 使用acme.sh自动管理泛解析域名

作者提供了一种免费使用泛解析域名的思路, 以下是作者提供的命令列表
# 部署 acme.sh 生成证书 curl https://get.acme.sh | sh -s email=admin@lafyun.com export Ali_Key="xxxxx" export Ali_Secret="xxxxx" acme.sh --issue --dns dns_ali -d lafyun.com -d *.lafyun.com -d *.oss.lafyun.com acme.sh --install-cert -d lafyun.com --key-file /lafyun/certs/lafyun.key --fullchain-file /lafyun/certs/lafyun.cer --reloadcmd "sh /lafyun/certs/reload.sh"
根据作者提供的思路, 详细写一下教程
  1. 在宿主机上执行命令安装acme.sh
curl https://get.acme.sh | sh -s email=my@example.com
  1. 以aliyun为例, 配置自动DNS验证域名
https://ram.console.aliyun.com/users这里创建一个用户, 勾选 Open API 调用访问
点击添加权限, 勾选”管理云解析(DNS)的权限", 点击确认
点击用户名, 点击创建AccessKey, 记录key和secret
export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" export Ali_Secret="jlsdflanljkljlfdsaklkjflsa" acme.sh --issue --dns dns_ali -d xxx.com -d *.xxx.com -d *.oss.xxx.com
  1. 把生成的证书移动到nginx配置的目录下, 并且文件名要与nginx中配置的一致
其中--reloadcmd指的是移动完成之后的操作, 这边是使用网关容器中的nginx -s reload命令刷新证书
docker ps | grep 0.0.0.0:443 | awk '{print $1}'作用是寻找到网关docker容器的ID, 其中的0.0.0.0:443你也可以自己换成别的, 只要他能唯一确定是网关容器那一行就可以
acme.sh --install-cert -d xxx.com --key-file /cert/tls.key --fullchain-file /cert/tls.crt --reloadcmd "docker exec -it $(docker ps | grep 0.0.0.0:443 | awk '{print $1}') nginx -s reload"
以上所有过程都会被记录下来, 定时任务会在证书到期之前自动运行
  1. 为了网站安全, nginx三个conf文件中推荐加入这几行ssl配置
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE; ssl_prefer_server_ciphers on;
并使用https://myssl.com/对域名进行扫描, 看下有没有其他风险
 
  1. 然后就可以愉快的玩耍了.
 
 
 

7. 0.8.6版本更新之后的说明

从0.8.6版本之后, 不再使用openresty作为网关, 换成了功能更为强大的apisix, 所以配置上需要做一些调整, 目录0-6中所有涉及到修改nginx配置的操作都不需要了
2.1中docker-compose.yml文件也不需要修改
3中 启动LAF并调整nginx配置文件 不需要修改
6中 --reloadcmd 参数也不需要指定, gateway-controller会定时检测证书信息
需要调整的配置:
在deploy/docker-compose目录中新建文件夹 cert
acme.sh命令修改为:
acme.sh --issue --dns dns_ali -d xxx.com -d *.xxx.com -d *.oss.xxx.com acme.sh --install-cert -d xxx.com --key-file /path/to/deploy/docker-compose/cert/global.key --fullchain-file /path/to/deploy/docker-compose/cert/global.crt
具体证书加载细节见 laf/packages/gateway-controller/src/support/apisix-gateway-init.ts 文件