Spug软件使用说明书

关于Spug

介绍

Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台,整合了主机管理、主机批量执行、主机在线终端、文件在线上传下载、应用发布部署、在线任务计划、配置中心、监控、报警等一系列功能。

特性

  • 批量执行: 主机命令在线批量执行
  • 在线终端: 主机支持浏览器在线终端登录
  • 文件管理: 主机文件在线上传下载
  • 任务计划: 灵活的在线任务计划
  • 发布部署: 支持自定义发布部署流程
  • 配置中心: 支持 KV、文本、json 等格式的配置
  • 监控中心: 支持站点、端口、进程、自定义等监控
  • 报警中心: 支持短信、邮件、钉钉、微信等报警方式
  • 优雅美观: 基于 Ant Design 的 UI 界面

预览

image

快速开始

Docker安装

依赖环境

  • Docker
  • 现代浏览器

安装步骤

以下安装步骤使用CentOS7.x操作系统

  1. 安装docker

注意
如已安装 docker 则忽略。
以下安装 docker 步骤适用于 Centos,其他系统安装请参考 Docker官方文档

yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
  1. 拉取镜像
docker pull registry.aliyuncs.com/openspug/spug
  1. 启动容器
如果需要持久化存储代码和数据,可以添加:-v 映射容器内/data路径。

镜像内置了 Mysql 数据库。
根据需要,以下两种启动方式任选其一即可。

# 持久化存储启动命令:
# /spug 指的是映射本地的磁盘路径,也可以是其他目录,/data是容器内代码和数据初始化存储的路径
docker run -d --restart=always --name=spug -p 80:80 -v /spug:/data registry.aliyuncs.com/openspug/spug

# 如果你需要在spug内使用docker命令则需要添加额外的参数
docker run -d --restart=always --name=spug -p 80:80 -v /spug/:/data -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker registry.aliyuncs.com/openspug/spug
  1. 初始化
    以下操作会创建一个用户名为 admin 密码为 spug.dev 的管理员账户,可自行替换管理员账户。

如果提示连接数据失败,再次执行尝试就可以了。

docker exec spug init_spug admin spug.dev
  1. 访问测试
    在浏览器中输入 http://localhost:80 访问。
用户名: admin  
密码: spug.dev

安装相关问题

执行数据初始化命令 python manage.py updatedb 报错

一般有以下两种情况

  • Django 版本使用了 3.x 的版本,我们仅支持 2.2.x 版本,安装依赖推荐使用文档中的 pip install -r requirements.txt 来安装。
  • 系统的 Sqlite 版本太低,Django 2.2 Sqlite 的版本最低要求为 3.8.3。

Nginx 访问前端文件提示无权限问题

确认系统是否开启了 selinux。如果开启可通过执行 setenforce 0 来临时关闭后重试。

登录报错 请求失败: 504 Gateway Timeout

请确保 api 服务是否启动,如果已启动则可以通过控制台查看是否监听在 8000 端口,如果不是 8000 端口可以改为 8000 端口或者修改前端项目的 spug/spug_web/src/setupProxy.js 文件中的 target 值为你的 api 服务的监听地址和端口。

登录报错 请求失败: 502 Bad Gateway

请确保 api 服务已正常启动且 nginx 配置正确。另可查看 nginx 日志如有发现 13: Permission denied 字样的报错则可尝试关闭 selinux 后再测试。

登录报错 Exception: Error 61 connecting to 127.0.0.1:6379. Connection refused.

需要安装 Redis,如果安装的 Redis 不是监听在 127.0.0.1 需要修改配置文件 spug_api/spug/settings.py 指定 Redis 的 Host,配置中的 CACHES 和 CHANNEL_LAYERS 均使用了 Redis。

添加主机报错 Exception: not a vaild RSA private key file

当 Spug 生成的密钥对无法通过验证时,会尝试读取系统的 ~/.ssh/ 目录下的密钥进行验证,这个报错一般是在读取系统密钥时出错。 可以尝试先移除系统 的密钥,然后再操作添加主机,等添加完成后再恢复原有的密钥。

如何配置使用带密码的 Redis 服务?

假设 Redis 密码为 foo123,则需要更改以配置文件 spug_api/spug/overrides.py(推荐) 或者 settings.py(影响后续版本升级) 如下内容,修改完成后记得重启服务。

提示
自定义的配置可以在 spug_api/spug/ 目录下创建 overrides.py 文件来覆盖默认的配置。

vi spug_api/spug/overrides.py
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://:foo123@127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": ["redis://:foo123@127.0.0.1:6379/0"],
        },
    },
}

Docker 部署使用外部 Mysql

官方 Docker 镜像内置了数据库服务,如果你想使用自己的外部数据库,可以通过如下方法:

注意
如果需要迁移数据,请查看 版本升级注意事项,以免造成后期无法升级新版本。

# 1. 进入容器
docker exec -it spug bash

# 2. 修改配置文件使访问外部数据库
vi /data/spug/spug_api/spug/overrides.py

DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'spug',
        'USER': 'spug',  # 修改为外部数据库的用户
        'PASSWORD': 'spug.dev',  # 修改为外部数据的用户密码
        'HOST': 'localhost',    # 修改为外部数据的ip
        'OPTIONS': {
            'unix_socket': '/var/lib/mysql/mysql.sock',   # !!!删除该行
            'charset': 'utf8mb4',
            'sql_mode': 'STRICT_TRANS_TABLES',
        }
    }
}

# 3. 停止容器内的数据库服务
vi /etc/supervisord.d/spug.ini

# 找到如下行并删除
[program:mariadb]
command = /usr/libexec/mysqld --user=mysql
autostart = true

# 4. 退出并重启容器
exit
docker restart spug

使用常见问题

使用 nohup 启动后台进程页面一直在转圈不会结束?

在 批量执行 或 发布配置 等的执行脚本中以 nohup 或 & 的方式启动后台子进程时需要 把命令的标准输出重定向至 /dev/null,例如以下启动 Tomcat 的命令:

cd web/WEB-INF/
nohup ./startup.sh &

把上述命令改为:

cd web/WEB-INF/
nohup ./startup.sh > /dev/null &

能否使用自己的密钥对?

可以,v2.3.0 版本开始已支持上传自定义密钥对,可以在 系统管理 \ 系统设置 \ 密钥设置 中,自行上传密钥。

新建常规发布申请 git clone 错误

Spug 无法提供交互式的输入账户密码登录git仓库的能力,如果是公开的仓库 http/https/ssh 任何一种协议都可以,但如果是私有仓库推荐使用 ssh 协议配置密钥来访问。http/https 协议则需要在带上用户名和密码,例如 https://yourname:password@gitee.com/openspug/spug.git 如果账户名中包含了 @ 符号,则需要替换成 %40。特别要注意的是,如果你是通过docker方式部署的则需要确保在容器内可以访问仓库,而不是在宿主机上。

主机 Console 或执行发布页面无内容

这种情况大部分都是 Websocket 连接建立失败了,一般出现在部署时自己加了一层 nginx 之类的代理工具,这些代理工具默认无法处理 Weboscket 请求, 这就需要你配置其支持转发 Websocket 请求,下边给个 Nginx 的例子,这里假设你用 docker 部署的 Spug, 映射了宿主机的 8000 端口:

server {
  listen 80;
  server_name xxx.xxx.xxx;
  
  location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
 
  location ^~ /api/ws/ {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  error_page 404 /index.html;
}

文件管理器上传文件报错 413 Request Entity Too Large

文件上传大小受 Nginx 的 client_max_body_size 影响,请修该值至合适的大小,参考以下配置:

注意
docker 方式部署配置文件位于容器内的 /etc/nginx/nginx.conf, 可以在容器外部编辑后通过 docker cp 至容器内,也可以在容器内执行 vi 在容器内直接修改,最后别忘了重启容器。

server {
  listen 80;
  server_name xxx.xxx.xxx;
  client_max_body_size 100m;

  ...
}

钉钉收不到通知?

钉钉机器人安全设置中 IP地址 添加部署 Spug 的服务器的公网地址,或者使用 自定义关键词 填写 通知,如下图
image

二开相关问题

标准安装批量执行的任务卡住无法看到执行输出

批量执行功能需要启动额外服务,通过以下命令启动,以下操作命令基于 标准安装 文档的环境

cd /data/spug/spug_api
source venv/bin/activate
python manage.py runworker

标准安装任务计划模块添加的任务不会执行

任务计划功能需要启动额外的服务,通过以下命令启动,以下操作命令基于 标准安装 文档的环境

cd /data/spug/spug_api
source venv/bin/activate
python manage.py runscheduler
python manage.py runworker

标准安装监控中心模块添加的监控任务不会执行

监控中心功能需要启动额外的服务,通过以下命令启动,以下操作命令基于 标准安装 文档的环境

cd /data/spug/spug_api
source venv/bin/activate
python manage.py runmonitor
python manage.py runworker

macOS 如何使用 Mysql 替代默认的 Sqlite 数据库?

需要安装 mysqlclient 数据库驱动库,可通过以下步骤安装

brew install mysql-client
export PATH="/usr/local/opt/mysql-client/bin:$PATH"
export LDFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib"
pip install mysqlclient

FAQ

验证主机时我输入的密码安全吗?

安全,你输入的密码仅用于当次建立密钥登录使用,并不会存储在任何地方或用于他处。

我不需要监控中心的功能,可以不启动 runmonitor 服务吗?

可以,包括任务计划模块,如果你不需要这个功能,也不必启动 runscheduler 服务。

内置的报警服务为什么不开源直接放在项目内呢?

因为不管是微信/邮件/短信都需要配置一些敏感信息才可以使用,例如微信的 APP_ID 邮件服务的账户密码等,所以暂无法开源。 另外我们也在系统设置的报警服务设置中提供了自定义邮件服务的相关配置,以便你使用自己的邮件服务。

使用手册

主机管理

介绍

管理维护平台可操作的主机,首次添加主机时需要输入 ssh 指定用户的密码。

原理说明

Spug 会在首次添加主机时尝试直接通过密钥连接目标主机,会出现以下3种可能:

  1. 如果目标主机不支持密钥认证,则直接抛出异常(错误代码 E01)并终止请求。
  2. 如果认证通过则直接完成主机添加。
  3. 如果认证失败,则弹出密码输入框,让用户输入密码然后设置密钥认证。
    当第 3 种情况时用户输入密码,Spug 在接收到输入的密码后,会尝试通过密码连接目标主机并执行以下命令设置密钥认证
mkdir -p -m 700 ~/.ssh
echo 'public key content ....' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

完成以上操作后,会再次尝试使用密钥连接目标主机,会出现以下2中可能:

  1. 认证失败,则直接抛出异常(错误代码 E02)并终止请求。
  2. 认证通过,完整主机添加。

错误说明

  • E01 表示目标主机不支持密钥认证,通常可以尝试查看目标主机的 sshd 配置文件 /etc/ssh/sshd_config 确保 PubkeyAuthentication yes。
  • E02 在 Spug 尝试设置密钥认证后依然无法正常通过密钥连接主机,如果你的目标主机 OpenSSH 版本 8.8 以上版本,则需要在 /etc/ssh/sshd_config 末尾添加一行配置 PubkeyAcceptedKeyTypes +ssh-rsa,然后重启 sshd 服务后再尝试。其他情况需要你自行查看具体原因(确保~/.ssh目录的权限 700 , ~/.ssh/ 目录下所有文件权限600),如果你可以手动操作实现密钥认证可自己尝试实现密钥认证,测试通过后再次添加主机即可。

批量执行

介绍

包含维护命令模版和批量远程执行命令两部分功能,常用来执行一些临时的任务例如,批量安装/卸载某个依赖包等。

执行任务

可以选择一到多个在主机管理中添加的主机作为执行的目标主机,命令内容可以直接写也支持从模板中读取已保存的命令。

提示
使用 nohup 或 & 启动后台进程页面一直在转圈不会结束?

全局变量

在 Shell 脚本中通过 $SPUG_HOST_HOSTNAME 来引用,在 Python 脚本中可以通过 os.getenv('SPUG_HOST_HOSTNAME') 来引用。

变量名 示例 说明
SPUG_HOST_ID 1 主机ID
SPUG_HOST_HOSTNAME 172.10.26.5 主机IP/域名
SPUG_SSH_PORT 22 SSH连接端口
SPUG_SSH_USERNAME root SSH连接用户名
SPUG_INTERPRETER python 命令解释器

模板管理

用于存储复杂、常用的命令集合,以便后期可随时使用。

应用发布

应用管理

介绍

管理和维护可发布的应用。 每个应用又可以创建对应环境的发布配置,发布配置请查看发布配置文档。

配置项

  • 应用名称 自定义的应用名称
  • 唯一标识符 会作为配置中心生成配置 Key 的前缀,具体请参考配置中心相关文档。
    小提示
  • 配置中心和应用发布模块都可以创建应用,它们的数据是互通的。
  • 环境的创建功能,在配置中心模块的环境管理页面。

发布配置

介绍

配置指定应用在某环境下如何执行发布,发布支持两种方式 常规发布 和 自定义发布。

常规发布

由 Spug 负责应用代码的打包、传输和更新,但提供了各个阶段可自定义的钩子。

说明
常规发布参考了开源项目 瓦力 的一些设计思路。

配置项

  • 发布环境 为哪个环境创建的发布配置,例如:测试环境 / 生产环境等。
  • Git仓库地址 该应用的 Git 仓库地址(请确保部署运维平台的服务器有权限通过给定的地址克隆仓库)。
  • 发布审核 开启后创建的发布申请单需要审核后才可以进行发布。
  • 目标主机部署路径 应用部署的路径,例如:静态网站部署在目标服务器的 /var/www/html。
  • 目标主机仓库路径 用于存储应用的历史版本,可自定义任意目录,例如:/data/spug/repos。
  • 保留历史版本数量 即如上边的例子中 /data/spug/repos 保留的历史版本数量,超过后早起的版本会自动删除,以节约存储空间。
  • 发布目标主机 可以选择一个或多个主机进行发布。
  • 文件过滤 可选 仅包含 或 排除 指定的文件,会从克隆的 Git 仓库的源代码中根据指定的规则过滤出符合条件的文件进行发布。
  • 自定义全局变量 可在后边的钩子命令内使用,Spug 本身也包含一些内置全局变量,请参考下文。
  • 代码迁出前执行 在部署 Spug 的服务器上运行,可以执行任意自定义命令。
  • 代码迁出后执行 在部署 Spug 的服务器上运行,当前目录为检出后待发布的源代码目录,可执行任意自定义命令。
  • 应用发布前执行 在发布的目标主机上运行,当前目录为目标主机上待发布的源代码目录,可执行任意自定义命令。
  • 应用发布后执行 在发布的目标主机上运行,当前目录为已发布的应用目录,可执行任意自定义命令。

提示
使用 nohup 或 & 启动后台进程页面一直在转圈不会结束?

自定义发布

该发布模式下 Spug 仅负责按顺序依次执行记录的动作。

配置项

  • 发布环境 为哪个环境创建的发布配置,例如:测试环境 / 生产环境等。
  • 发布审核 开启后创建的发布申请单需要审核后才可以进行发布。
  • 发布目标主机 可以选择一个或多个主机进行发布。
  • 本地执行动作 可以添加多个执行动作,执行对象为部署运维平台的服务器,会优先按顺序执行本地动作。
  • 目标主机执行动作 可以添加多个执行动作,执行对象为发布的目标主机,按顺序依次执行。
  • 数据传输动作 用于文件分发传输,

提示
使用 nohup 或 & 启动后台进程页面一直在转圈不会结束?

数据传输

从 v2.3.7 版本开始已支持添加数据传输动作,用于把文件从部署 Spug 的容器或主机传输至目标主机,其页面展示效果如下:
image

  • 数据来源 数据来源可以选择以下两种
    • 本地路径:位于部署 spug 的容器或主机上,路径可以是文件或目录,请输入绝对路径。
    • 发布时上传:在创建发布申请时上传数据。
  • 过滤规则 仅在数据来源选择本地路径时有效,可以设置包含 和 排除两种规则,内容为基于本地路径的相对路径,多个路径使用英文逗号分割,当传输对象为文件时过滤规则将会被忽略。
  • 目标路径 如果数据来源为发布时上传,则目标路径必须为一个文件路径(例如:/tmp/upload.tar.gz), 如果数据来源为本地路径则请保持目标路径与本地路径的类型一致,如本地路径为文件则目标路径也必须为文件,可参考以下例子
    当数据来源为发布时上传,需要注意以下事项:

注意
目标路径必须为文件路径,例如:/data/upload.jar,大部分情况下还需要其他后续动作去处理上传的文件。
上级目录必须已存在,如上例子则 /data 必须为目标主机上已存在的目录。
每次执行该数据传输动作时将会覆盖已存在的文件。

下面以 Spug 开源项目的源代码作为例子来说明当数据来源为本地路径时几种典型情况,假设源代码位于 /data/spug 目录下。

  • 本地路径:/data/spug,目标路径:/www/spug,文件过滤:关闭

说明
将会把部署 Spug 的容器或主机上的 /data/spug 目录完整传输至目标主机的 /www/spug 目录,特别注意,如果目标主机的 /www/spug 已存在,将会先执行删除操作。

  • 本地路径:/data/spug,目标路径:/www/spug,文件过滤:包含 spug_api,spug_web/dist

说明
仅把 /data/spug 目录下的 spug_api 和 spug_web/dist 传输至目标主机,传输完成后目录主机的 /www/spug 中仅包含上述两个目录,文件 过滤中的 排除 用法与 包含 类似,但只传输除了指定路径以外的其他文件。

  • 本地路径:/data/spug/README.md,目标路径:/www/spug/README.md, 文件过滤:包含 spug_api

说明
仅把 README.md 传输至目标主机,因为传输对象为文件,所以文件过滤规则将会被忽略。

  • 本地路径:/data/spug/README.md, 目标路径:/www/spug,文件过滤:关闭

说明
传输 README.md 至目标主机,删除并替换 /www/spug,特别注意,传输完成后目标主机的 /www/spug 将变更为一个文件,内容为 README.md 文件的内容。这个是一个反例,如果你要传输的是文件,请保持目标路径也是一个完整的文件路径。

  • 本地路径:/data/spug, 目标路径:/www/spug/README.md,文件过滤:关闭

说明
将传输整个 /data/spug 目录至目标主机并将其命名为 README.md,特别注意,传输完成后目标主机的 /www/spug/README.md 将变更为一个目录。 这个是一个反面例子,如果你要传输的是目录,请保持目标路径也是一个完整的目录路径。

全局变量

  • SPUG_APP_NAME 发布应用的名称
  • SPUG_APP_KEY 发布应用的标识符
  • SPUG_APP_ID 发布应用的 ID
  • SPUG_REQUEST_ID 发布申请单 ID
  • SPUG_REQUEST_NAME 发布申请单的名称
  • SPUG_VERSION 发布申请版本
  • SPUG_BUILD_VERSION 发布申请内部版本号(v3.0.5新增)
  • SPUG_ENV_ID 发布环境 ID
  • SPUG_ENV_KEY 发布环境的标识符
  • SPUG_DEPLOY_ID 发布配置 ID(v2.2.3新增)
  • SPUG_DEPLOY_TYPE 发布类型("1" 为正常发布,"2" 为回滚)
  • SPUG_API_TOKEN 访问配置中心获取配置的 API_TOKEN
  • SPUG_HOST_ID 当前执行主机的 ID(v2.2.3新增,仅在主机执行阶段有效)
  • SPUG_HOST_NAME 当前执行主机的 IP /域名(v2.2.3新增,仅在主机执行阶段有效)

常规发布有效

  • SPUG_REPOS_DIR 常规发布源码存储目录(v2.3.4新增,\(SPUG_REPOS_DIR/\)SPUG_DEPLOY_ID 即为本次发布应用的源码目录)
  • SPUG_DST_DIR 常规发布目标主机部署路径(v2.3.8新增)
  • SPUG_GIT_BRANCH 本次发布选择的 Git 分支(v2.3.2新增,常规发布基于分支时有效)
  • SPUG_GIT_COMMIT_ID 本次发布选择的Git Commit ID(v2.3.2新增,常规发布基于分支时有效)
  • SPUG_GIT_TAG 本次发布的Git Tag(v2.3.2新增,常规发布基于 Tag 时有效)

自定义发布有效

  • SPUG_RELEASE 新建自定义发布申请填写的 SPUG_RELEASE 值(自定义发布有效)

提示
SPUG_RELEASE 会自动按空格分隔解析为多个环境变量,例如 abc 123 def,会对应有4个变量:

SPUG_RELEASE = abc 123 def
SPUG_RELEASE_1 = abc
SPUG_RELEASE_2 = 123
SPUG_RELEASE_3 = def

发布申请

介绍

创建和执行发布。

配置项

根据发布方式的不同,对应创建发布申请的配置项也不同。

常规发布

  • 申请标题 申请单的名称。
  • 选择分支/标签/版本 支持选择分支和 CommitID 或 Tag 来确定发布的代码。
  • 发布目标主机 可选择本次申请单要发布的主机(从发布配置添加的目标主机中选择)。

自定义发布

  • 申请标题 申请单的名称。
  • 环境变量(SPUG_RELEASE) 可以在自定义脚本中引用该变量,用于设置本次发布相关的动态变量,可在发布配置添加的动作脚本中通过 $SPUG_RELEASE 来使用该值。
  • 发布目标主机 可选择本次申请单要发布的主机(从发布配置添加的目标主机中选择)。

发布记录的删除

可以发现发布申请在发布后无法被单个直接删除,这并不是我们偷懒,而是故意设计成这样的。以我们以往的经验来看发布记录在某些情况下是重要的排查问题的线索, 例如,某用户在未充分测试的情况下通过 Spug 发布一个应用的新版本,很不巧这个新版本上线后发现了问题造成了服务不可用的情况,出于一些原因该用户把这个发布记录悄悄的删除了, 那么这个行为可能就会在排查问题的时候造成一定的困扰。所以我们只设计了根据时间和保留个数两个维度来批量删除,避免可能遇到的上述问题。

小提示

  • 如果发布配置中启用了审核功能,则创建的申请单需要通过审核后才可以执行发布操作。

回滚机制

介绍

发布目前支持两种方式 常规发布 和 自定义发布,这里来分别讲解下这两种发布方式的回滚机制。

常规发布

常规发布由发布配置中的 保留历史版本数量 来决定是否可以回滚,超过保留上限的版本将无法执行回滚操作。回滚将经历以下几个步骤:

  1. 当用户在发布申请中点击 回滚 按钮时,将会自动基于本次发布的上个版本(例如:有 v1.1.3 v1.1.2 v1.1.1 三个发布记录,当点击 v1.1.3 的回滚按钮时将基于 v1.1.2,同理点击v1.1.2 时将基于 v1.1.1)创建新的发布申请。
  2. 找到第一步所创建的带有 回滚 字样标题的发布申请,如果开启了审核则需要先通过审核,否则可直接点击发布按钮。
  3. 执行回滚发布,回滚发布将跳过检出前后动作,直接执行发布前和发布后任务并使用存储的历史版本发布。
    如果你想控制回滚时行为执行不同的操作,可以在 发布前任务 和 发布后任务 中使用内置的全局变量 SPUG_DEPLOY_TYPE, 通过判断其值来做不同的操作。

自定义发布

因为自定义发布更加的灵活自由,Spug 也无法对回滚进行任何限制或干涉,完全依靠用户来控制。回滚将经历以下几个步骤:

  1. 与常规发布相同,当用户在发布申请中点击 回滚 按钮时,将会自动基于本次发布的上个版本(例如:有 v1.1.3 v1.1.2 v1.1.1 三个发布记录,当点击 v1.1.3 的回滚按钮时将基于 v1.1.2,同理点击v1.1.2 时将基于 v1.1.1)创建新的发布申请。
  2. 找到第一步所创建的带有 回滚 字样标题的发布申请,如果开启了审核则需要先通过审核,否则可直接点击发布按钮。
  3. 执行回滚发布,默认行为与发布一致,会根据定义的顺序完整执行所有动作。
    如果你想控制回滚时行为执行不同的操作,在自定义的动作中使用内置的全局变量 SPUG_DEPLOY_TYPE, 通过判断其值来做不同的操作。

控制行为

内置的全局变量 SPUG_DEPLOY_TYPE 可用于区分回滚和正常发布,1 为正常发布, 2 为回滚发布。 用户可通过判断其值来实现不同情况下的不同操作, 例如:

if [ "$SPUG_DEPLOY_TYPE" = "1" ]; then
    echo "执行正常发布的操作,巴啦啦..."
else
    echo "这里只有回滚时才会执行"
fi

配置中心

环境管理

介绍

管理应用的运行环境,一般包含开发环境、测试环境和生产环境,应用发布和配置管理需要用它来区分不同的环境。
创建环境时设置的 唯一标识符 用于配置中心提供的开放 API 调用。

服务管理

介绍

管理和维护应用依赖的服务配置。例如有两个应用 A 和应用 B,它们共同使用一个数据库,那么就可以把这个数据库提取出来作为单独的服务来管理。 这样带来的好处是如果这个数据库配置变更了,那么只需要在服务管理里把这个数据库的配置更新即可,不必在多个应用之间切换查找更新。

小提示

  • 如果某些配置是多个应用共用配置,请考虑把这些配置提取出来作为单独的服务。
  • 服务配置没有 私有 和 公共 的区分,也可以说所有的服务配置都是 公共 配置。
  • 服务配置并不能直接被获取到,只能通过被依赖的应用获取到。

应用管理

介绍

用于维护应用的配置,应用配置包含 公共 和 私有 两种类型的配置。

  • 公共 配置

该类型的配置可以被其他应用所使用。比较典型的例子:应用 B 需要调用应用 A 的某接口,那么应用 B 必然需要知道应用 A 的 IP 或域名,这时就可以在应用 A 上添加个 公共 类型的配置以供应用B来使用。为什么不把这个配置放在应用 B 里呢?因为如果还有应用 C / D / E / F 也要调用A呢?在 C / D / E / F 中都配 置一遍即麻烦又难以维护。

  • 私有 配置

仅用于此应用的配置,并不会被其他应用所获取到。

小提示

  • 公共 和 私有 类型的配置都会应用自身获取到,它们区别仅仅是当其他应用依赖该应用时,公共 配置会提供给依赖应用而 私有 配置不会。
  • 配置中心用于解决不同环境间配置的差异,如果各个环境下某配置的值都是相同的,就可以直接在代码中硬编码而不需要把这些配置放到配置中心维护。

配置管理

介绍

用户维护服务和应用在不同环境下的具体配置。

小提示

  • 当需要一次性录入大量配置时可以使用 文本模式 或 JSON模式。
  • 当使用 文本模式 或 JSON模式 创建应用的配置时默认会创建为 私有 配置。

API

介绍

配置中心提供了开放的接口用于获取应用在某环境下的配置。

规则

应用的配置将从以下途径获取并进行组合:

  • 该应用在指定环境下的 公共 和 私有 配置
  • 所依赖的应用的 公共 配置
  • 所依赖的服务的配置
  • 根据指定的环境,仅读取指定环境的以上配置

获取方式

配置的获取需要通过调接口的形式来获取,根据需要传的参数又分以下两种途径

在发布配置的钩子内获取

  • 请求地址:/api/apis/config/

  • 请求方法: GET

  • 请求参数:

参数名 类型 必填 默认值 示例 说明
apiToken string $SPUG_API_TOKEN 固定值,Spug 内置的全局变量,仅可在发布配置的钩子中引用
format string kv json 返回的格式,目前支持 kv 、env 和 json 三种格式,分别对应 key = value 、 key=value 和 {"key": "value"},其中 env 为 v2.3.8 新增
noPrefix string 1 v2.3.8 新增,默认返回的 key 会增加应用或服务的标示作为前缀来确保不会出现同名的 key 造成配置的意外覆盖问题,如果不需要这一特性可以传该参数来禁用这一默认行为
  • 使用示例

以下截图即在 应用发布前 中调用了获取配置的接口,将会把该应用该环境下的配置保存在 .env 文件中。
image

独立使用

  • 请求地址:/api/apis/config/

  • 请求方法: GET

  • 请求参数:

参数名 类型 必填 默认值 示例 说明
apiKey string JLV8IGO0DhoxcM7I 调用接口的访问凭据,在 Spug 系统管理/系统设置/开放服务设置 中配置,请勿泄露给他人
app string order 指定要获取其配置的应用的标识符(创建应用时设置的该标识符,请在应用管理或应用配置页面查看应用的标识符)
env string dev 指定获取应用所在环境的标识符(创建环境时设置的该标识符,请在 配置中心/环境管理页面查看环境标识符)
format string kv json 返回的格式,目前支持 kv 、env 和 json 三种格式,分别对应 key = value 、 key=value 和 {"key": "value"},其中 env 为 v2.3.8 新增
noPrefix string 1 v2.3.8 新增,默认返回的 key 会增加应用或服务的标示作为前缀来确保不会出现同名的 key 造成配置的意外覆盖问题,如果不需要这一特性可以传该参数来禁用这一默认行为
  • 使用示例1
curl "https://demo.spug.dev/api/apis/config/?apiKey=JLV8IGO0DhoxcM7I&app=order&env=test"

输出如下

db_order_database = order
db_order_host = 172.26.89.90
db_order_password = 123456
db_order_port = 3306
db_order_username = root
order_app_debug = true
order_cache_driver = file
order_url = http://test-order.internal.com
redis_host = 127.0.0.1
redis_password = 123456
  • 使用示例2
curl "https://demo.spug.dev/api/apis/config/?apiKey=JLV8IGO0DhoxcM7I&app=order&env=test&noPrefix=1"

输出如下

app_debug = true
cache_driver = file
database = order
host = 127.0.0.1
password = 123456
port = 3306
url = http://test-order.internal.com
username = root

说明
可以通过对比发现,在 noPrefix 模式下,服务 订单主库(标识符 db_order)的配置 host 和 password 被服务 Redis服务(标识符 redis)覆盖了,所以最终的配置意外丢失了2个。

任务调度

介绍

方便的维护一些周期性的任务,例如:在一个下单交易的应用里,超时未支付的订单需要被关闭掉,就可以通过任务调度模块添加一个调度任务来每隔 1 分钟调用一次应用的某接口来让应用检查那些超期未支付的订单。

执行历史仅保留每个任务最近 50 条记录,多余的记录将会被自动删除。

监控中心

介绍

该模块提供了以下几种常用的监控模式

  • 站点检测

通过 GET 请求指定的 url 匹配返回的状态码来确定站点是否异常,目前200 - 399之间状态码均为正常,否则为异常,默认超时时间为 10 秒。

  • 端口检测

检测指定目标主机的 TCP 端口是否可以正常建立接连。

  • Ping 检测

(v2.3.10新增)使用 Ping 检测目标主机是否存活,默认超时时间为 3 秒。

  • 进程检测

检测指定目标主机的某个进程是否存活。

  • 自定义脚本检测

在指定主机上运行自定义的脚本,通过判断返回的退出状态码是否为 0 来确定是否有异常。脚本执行中输出的内容将作为报警的描述信息,可利用此特性来灵活控制 报警的规则和报警的内容。

配置说明

  • 监控频率: 每隔多长时间检测一次
  • 报警阈值: 连续指定次数检测失败后才会触发报警,例如:报警阈值设置为3,则表示当出现故障时连续3次检测都为失败的情况才触发报警
  • 报警联系人组: 报警联系人的集合,可以包含一个或多个报警联系人
  • 通道沉默: 相同的检测失败事件在通道沉默周期内只触发一次报警,避免过于频繁重复的报警信息。例如:通道沉默设置为 5 分钟,第一次触发报警后,5分钟内再次触发相同的报警信息则不会发送。
  • 报警方式 目前支持微信、钉钉和邮件三种报警方式,内置开箱即用的微信和邮件报警服务,需要关注下方服务号 Spug 获取调用凭据,将调用凭据配置至系统设置 / 报警服务设置 中的调用凭据中。
  • 微信报警,需要设置报警联系人的微信 Token,获取方式与获取调用凭据相同
  • 钉钉报警,需要设置报警联系人的钉钉机器人 URL,请在钉钉群-安全设置里面添加部署服务器的外网 IP,或者设置关键字 通知
  • 邮件报警,需要设置报警联系人的邮箱地址

报警中心

报警记录

介绍

查询最近30天内的报警记录。

提示
超过30天的报警记录会被自动删除,通道沉默期发送的报警信息不会记录。

报警联系人

介绍

用户维护报警的联系人相关内容,每种额外信息对应一种报警方式。

小提示

  • 微信 Token 的获取需要关注公众号Spug 在 我的 菜单中获取。
  • 内置的微信和邮件报警模式需要配置调用凭据,调用凭据的获取方式与微信 Token 相同,获取调用凭据后,将调用凭据配置至系统设置 / 报警服务设置 中的调用凭据中即可。
  • 调用凭据可以是任何一个有效的微信 Token。
  • 由于微信的限制,你必须关注公众号才能收到微信报警信息。
  • 钉钉收不到通知?

报警联系组

介绍

联系组即为报警联系人的组合,在监控中心模块设置的报警通知对象必须为联系组。

系统管理

账户管理

介绍

除了页面上对普通用的管理,Spug 还提供了 manage.py user 命令可用于管理员账户的管理操作。

创建账户

创建账户使用 manage.py user add 命令,用法示例如下

cd spug/spug_api
source venv/bin/activate
python manage.py user add -u admin -p 123 -n 张三丰 -s

Docker 安装的可以执行如下命令

docker exec spug python3 /data/spug/spug_api/manage.py user add -u admin -p 123 -n 张三丰 -s

以上命令会创建个登录名为 admin 密码为 123 昵称为 张三丰 的管理员账户,注意最后的 -s 参数,如果携带了这个参数意味着该账户为管理员账户, 管理员账户可以不受任何限制的访问所有功能模块。

重置密码

使用 manage.py user reset 命令来重置账户密码,用法示例如下

cd spug/spug_api
source venv/bin/activate
python manage.py user reset -u admin -p abc

Docker 安装的可以执行如下命令

docker exec spug python3 /data/spug/spug_api/manage.py user reset -u admin -p abc

上述操作会重置登录名为 admin 的账户的密码为 abc。

启用账户

当页面上登录连续错误数次超过3次后账户自动转为禁用状态,普通用户可以通过 系统管理 / 账户管理 在页面是启用账户即可,但管理员账户需要使用如下命令来启用

cd spug/spug_api
source venv/bin/activate
python manage.py user enable -u admin

Docker 安装的可以执行如下命令

docker exec spug python3 /data/spug/spug_api/manage.py user enable -u admin

系统设置

介绍

除了页面上对系统设置的管理,Spug 还提供了 manage.py set 命令可用于通过命令行进行管理操作。

禁用登录MFA

当某些特殊情况下可通过 manage.py set mfa disable 命令禁用MFA,用法示例如下

cd spug/spug_api
source venv/bin/activate
python manage.py set mfa disable

Docker 安装的可以执行如下命令

docker exec spug python3 /data/spug/spug_api/manage.py set mfa disable

微信Token

介绍

微信Token 是 Spug 提供内置服务的用户身份标识,通过该标识与微信用户建立关联,提供例如微信告警、登录两步验证等功能。

获取方法

搜索(或扫描下方的二维码)关注微信公众号 Spug。
在公众号底部的 我的 菜单中获取微信Token。

用途

  • 作为 Spug 内置服务的调用凭据(系统设置/基本设置)。
  • 告警模块中,作为微信告警的用户标识。
  • 当启用登录MFA(两步)认证时,作为发送验证码的用户标识。

小提示

  • 同一个 微信Token 可以在不同的模块中使用。
  • 由于微信的限制,你必须关注公众号才能收到相关信息。

发布模板

Java项目配置

概览

以 若依管理系统 https://gitee.com/y_project/RuoYi 作为例子,最终大概是这样子的。

注意
以下基于 spug v2.3.4 版本,如果低于 v2.3.4 可以参考 版本升级文档 进行升级,例子仅作为演示,一般情况下你都需要结合自己的项目情况调整配置。
image

安装 jdk / maven

如果已安装可跳过该步骤,这里以安装 jdk-8u251 和 maven-3.6.3 为例,如果你使用 Docker 部署的 Spug,可参考以下步骤进行安装

注意
以下仅适用于 2.3.4 及以后的镜像(基于 Centos)启动的容器(这里的 2.3.4 并不是 Spug 的版本号,请在 hub.docker.com 查询镜像版本)。

因 Oracle JDK 下载需要登录账户请自行下载,这里直接使用下载完成的 jdk-8u251-linux-x64.tar.gz 文件。

# 自行至 https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html 下载jdk
# 把已下载的压缩包拷贝进容器
docker cp jdk-8u251-linux-x64.tar.gz spug:/
docker exec -it spug bash
tar xf jdk-8u251-linux-x64.tar.gz -C /opt

# 安装maven
curl -o apache-maven-3.6.3-bin.tar.gz http://apache.mirrors.pair.com/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
tar xf apache-maven-3.6.3-bin.tar.gz -C /opt/
echo -e 'export JAVA_HOME=/opt/jdk1.8.0_251\nexport PATH=$PATH:$JAVA_HOME/bin:/opt/apache-maven-3.6.3/bin' > /etc/profile.d/java.sh

# [可选]配置阿里云镜像加速下载,在159-164行(<mirrors\>标签内)添加以下内容
vi /opt/apache-maven-3.6.3/conf/settings.xml

    159     <mirror>
    160       <id>aliyunmaven</id>
    161       <mirrorOf>*</mirrorOf>
    162       <name>阿里云公共仓库</name>
    163       <url>https://maven.aliyun.com/repository/public</url>
    164     </mirror>

# 退出并重启容器
exit
docker restart spug

文件过滤

只需要发布编译过的 jar 包,所以这里选择了 包含 规则。

ruoyi-admin.jar

自定义变量

该例子中并不需要特殊的 全局变量,如果你需要的话可以在这里定义,然后在下边的钩子中类似 $SPUG_DEPLOY_ID 那样去引用。

代码检出前

该例子中也不需要执行。

代码检出后

在这里进行项目的依赖包安装和编译工作,该钩子中当前目录即为按发布申请中选择 Git 分支/版本 检出后的代码目录。

# 执行maven编译
mvn clean package -Dmaven.test.skip=true
cp ruoyi-admin/target/ruoyi-admin.jar .

这里拷贝 ruoyi-admin.jar 至项目根目录,因为咱们文件过滤规则指定的就是相对于项目根目录。

应用发布前

发布前停止现有的服务。

# 停止服务
set +e
ps -ef | grep ruoyi-admin | grep -v grep | awk '{print $2}' | xargs kill -9

因为 Spug 会检测每个钩子内脚本最终退出状态码,如果非 0 则认为执行异常终止发布,所以如果你的目标主机是 Centos 则需要通过 if 来判断进程 是否存在,如果存在才执行 kill。

# 停止服务
PID=$(ps -ef | grep ruoyi-admin | grep -v grep | awk '{print $2}')
if [ ! -z $PID ]; then
   kill -9 $PID
fi

应用发布后

在这里启动服务。

# 添加jdk至PATH变量
PATH=$PATH:/usr/local/jdk1.8.0_231/bin
nohup java -jar ruoyi-admin.jar &> run.log &

Node项目配置

概览

以 Spug 的前端 spug_web 作为例子来说下前端项目的配置,最终大概是这样子的。

注意
以下基于 spug v2.3.4 版本,如果低于 v2.3.4 可以参考 版本升级文档 进行升级,例子仅作为演示,一般情况下你都需要结合自己的项目情况调整配置。
image

安装 node(npm)

如果已安装可跳过该步骤,这里以目前的最新版 v12.18.1 为例,如果你使用 Docker 部署的 Spug,可参考以下步骤进行安装。

注意
以下仅适用于 2.3.4 及以后的镜像(基于 Centos)启动的容器(这里的 2.3.4 并不是 Spug 的版本号,请在 hub.docker.com 查询镜像版本)。

# 进入容器
docker exec -it spug bash
curl -o node-v12.18.1-linux-x64.tar.xz https://nodejs.org/dist/v12.18.1/node-v12.18.1-linux-x64.tar.xz
tar xf node-v12.18.1-linux-x64.tar.xz -C /opt
echo 'export PATH=$PATH:/opt/node-v12.18.1-linux-x64/bin' > /etc/profile.d/node.sh

# 安装yarn,推荐使用yarn来代替npm
source /root/.bashrc
npm install -g yarn

# 退出并重启容器
exit
docker restart spug

文件过滤

前端项目发布的时候只需要编译后的内容就可以,这里选择了 包含 条件,内容为 spug_web/build,这样最终发布到目标主机上的代码仅包含 spug_web/build,并不会把 spug_api 及 spug_web 中的前端源代码发布出去。

自定义变量

该例子中并不需要特殊的全局变量,如果你需要的话可以在这里定义,然后在下边的钩子中类似 $SPUG_DEPLOY_ID 那样去引用。

代码检出前

作为前端项目免不了要处理项目依赖包的问题,依赖安装一般在 package.json 所在的目录(在本示例中即spug_web)中执行 npm install 或 yarn 来安装。这里使用了 全局环境变量 中的 SPUG_REPOS_DIR 和 SPUG_DEPLOY_ID 来切换到源码目录创建公共的 node_modules 目录,以后每次发布时都通过软链接的形式使用它来避免每次 发布都需要全量安装依赖包。

# 创建公共node_modules目录
mkdir -p $SPUG_REPOS_DIR/$SPUG_DEPLOY_ID/node_modules

代码检出后

在这里进行项目的依赖包安装和编译工作,该钩子中当前目录即为按发布申请中选择 Git 分支/版本 检出后的代码目录,我们需要先把上一步创建的公共 node_modules 目录链接到当前目录(这样可以避免每次都完整的执行npm install来重复安装依赖包),然后执行 yarn build 来进行项目编译。

# 创建软链接,指向公共的node_modules,避免每次发布重复安装依赖包
cd spug_web
ln -s $SPUG_REPOS_DIR/$SPUG_DEPLOY_ID/node_modules .
# 执行依赖安装
yarn
# 执行 编译
yarn build

编译后也就生成了我们在 文件过滤 中设置的 spug_web/build 目录。

应用发布前

由于我们设置的文件过滤规则 spug_web/build,所以传输到目标主机上文件结构也是 spug_web/build/xx,我们需要调整下目录结构, 让 spug_web/build 目录下内容放到项目的根目录中。

# 调整目录结构,把编译结果放在项目根目录
mv spug_web/build/* .
rm -rf spug_web

应用发布后

前端项目编译后就是纯静态的 html、js 和一些静态文件,这里一般就不需要额外的处理了。

进阶指南

手动部署

注意
我们推荐你使用 Docker安装 来确保体验的一致性。

准备环境

  • Python 3.6及以上
  • Mysql 5.6及以上
  • 现代浏览器
  • 自v2.3.9 开始 Git 版本需要 2.17.0+ (影响新建常规发布申请单)

安装步骤

以下安装步骤假设项目部署在一台 Centos7 系统的 /data/spug 目录下。

  1. Clone项目代码
git clone https://github.com/openspug/spug /data/spug
cd /data/spug
git checkout x.x.x   # x.x.x 为指定的发行版本,例如 git checkout v2.2.2 
  1. 下载 已编译打包后的前端项目
    将下载好的前端压缩包解压到指定目录,假设web_x.y.z.tar.gz 是的你下载好的压缩包

提示
访问 Github 比较慢的情况下,可以在尝试在 Gitee 下载。

tar xf web_x.y.z.tar.gz -C /data/spug/spug_web/;
  1. 创建运行环境
    如需要使用常规发布功能,则需要安装 git v2.17.0+。
# 安装依赖
yum install mariadb-devel python3-devel gcc openldap-devel redis nginx supervisor

# 创建虚拟环境
cd /data/spug/spug_api
python3 -m venv venv
source venv/bin/activate

# 安装python包
pip install -U pip -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install gunicorn mysqlclient -i https://pypi.tuna.tsinghua.edu.cn/simple/
  1. 修改后端配置
    后端默认使用的 Sqlite 数据库,通过修改配置使用 MYSQL 作为后端数据库。

注意
在 spug_api/spug/ 目录下创建 overrides.py 文件,启动后端服务后会自动覆盖默认的配置,避免直接修改 settings.py 以便于后期获取新版本。

spug_api/spug/overrides.py
DEBUG = False

DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'spug',             # 替换为自己的数据库名,请预先创建好编码为utf8mb4的数据库
        'USER': 'spug_user',        # 数据库用户名
        'PASSWORD': 'spug_passwd',  # 数据库密码
        'HOST': '127.0.0.1',        # 数据库地址
        'OPTIONS': {
            'charset': 'utf8mb4',
            'sql_mode': 'STRICT_TRANS_TABLES',
            #'unix_socket': '/opt/mysql/mysql.sock' # 如果是本机数据库,且不是默认安装的Mysql,需要指定Mysql的socket文件路径
        }
    }
}
  1. 初始化数据库
cd /data/spug/spug_api
python manage.py updatedb
  1. 创建默认管理员账户
python manage.py user add -u admin -p spug.dev -s -n 管理员

# -u 用户名
# -p 密码
# -s 超级管理员
# -n 用户昵称
  1. 创建启动服务脚本
/etc/supervisord.d/spug.ini
[program:spug-api]
command = bash /data/spug/spug_api/tools/start-api.sh
autostart = true
stdout_logfile = /data/spug/spug_api/logs/api.log
redirect_stderr = true

[program:spug-ws]
command = bash /data/spug/spug_api/tools/start-ws.sh
autostart = true
stdout_logfile = /data/spug/spug_api/logs/ws.log
redirect_stderr = true

[program:spug-worker]
command = bash /data/spug/spug_api/tools/start-worker.sh
autostart = true
stdout_logfile = /data/spug/spug_api/logs/worker.log
redirect_stderr = true

[program:spug-monitor]
command = bash /data/spug/spug_api/tools/start-monitor.sh
autostart = true
stdout_logfile = /data/spug/spug_api/logs/monitor.log
redirect_stderr = true

[program:spug-scheduler]
command = bash /data/spug/spug_api/tools/start-scheduler.sh
autostart = true
stdout_logfile = /data/spug/spug_api/logs/scheduler.log
redirect_stderr = true
  1. 创建前端nginx配置文件
/etc/nginx/conf.d/spug.conf
server {
        listen 80;
        server_name _;     # 修改为自定义的访问域名
        root /data/spug/spug_web/build/;
        client_max_body_size 20m;   # 该值会影响文件管理器可上传文件的大小限制,请合理调整

        gzip  on;
        gzip_min_length  1k;
        gzip_buffers     4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 7;
        gzip_types       text/plain text/css text/javascript application/javascript application/json;
        gzip_vary on;

        location ^~ /api/ {
                rewrite ^/api(.*) $1 break;
                proxy_pass http://127.0.0.1:9001;
                proxy_read_timeout 180s;
                proxy_redirect off;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location ^~ /api/ws/ {
                rewrite ^/api(.*) $1 break;
                proxy_pass http://127.0.0.1:9002;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location / {
                try_files $uri /index.html;
        }
}

注意
注意:如果你没有在 spug.conf 中指定 server_name 则需要把 /etc/nginx/nginx.conf 中默认的 server 块注释或删除后才能正常访问, 否则会打开 Nginx 默认页面。

  1. 启动服务
# 设置开机启动
systemctl enable nginx
systemctl enable redis
systemctl enable supervisord

# 启动服务
systemctl restart nginx
systemctl restart redis
systemctl restart supervisord
  1. 访问测试
    通过浏览器访问测试。

  2. 安全建议

  • 请确保安装的 Redis 仅监听在 127.0.0.1。
  • 确保服务端接收到请求 HTTP Header 的 X-Real-IP 为真实的客户端地址,Spug 会使用该 IP 提高安全性(当登用户的 IP 发生变化时 Token 自动失效)。

二次开发

此安装文档适合具有一定编程能力基础的人员进行二次开发时的环境搭建,如果你是在生产环境部署,推荐 Docker安装, 如有必要你也可以考虑 手动部署。

依赖环境

  • Python 3.6及以上
  • Nodejs 12.14 LTS
  • Redis 3.x及以上
  • 现代浏览器

安装步骤

以下安装步骤假设项目安装在一台 macOS 系统的 /data/spug 目录下。

  1. Clone项目代码
git clone https://github.com/openspug/spug /data/spug
  1. 创建运行环境
cd /data/spug/spug_api
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
  1. 初始化数据库
    默认使用的 Sqlite 数据库。
python manage.py updatedb
  1. 创建默认管理员账户
python manage.py user add -u admin -p spug.dev -s -n 管理员

# -u 用户名
# -p 密码
# -s 超级管理员
# -n 用户昵称
  1. 启动 api 开发环境服务
python manage.py runserver
  1. 安装前端依赖
    可以把 npm 用 yarn 或 cnpm 代替。
cd /data/spug/spug_web
npm install --registry=https://registry.npm.taobao.org
  1. 启动前端
npm start
  1. 访问测试
    正常情况下 npm start 会自动在浏览器中打开项目,如果未打开可以在浏览器中输入 http://localhost:3000 访问。
    如果你按照上边的文档执行的话,在第 4 步创建了默认的管理员账户:
用户名:admin  
密码:spug.dev
  1. 其他可选服务
    通过以上步骤已经可以正常访问 Spug 了,但一些功能依赖额外的服务。

实践指南

安全性实践指南

写在前面,没有绝对的安全,如果环境允许的话尽量把 Spug 部署在内网且禁止公网访问,如果必须通过公网访问则尽可能通过防火墙等手段限制指定 IP 访问。
Spug 在登录安全方面提供了连续3次错误密码自动禁用账户的功能,尽可能的避免了被暴力破解登录的可能性。在 Token 安全方便提供了基于访问来源 IP 的 安全策略,当同一个 Token 访问来源 IP 发生变化时 Token 将自动失效,强制重新登录(v3.0.2之后可以通过系统设置关闭该特性)。

注意
Token 安全策略中的来源 IP 依赖 Nginx 转发请求时携带的 HTTP 头 X-Real-IP 和 X-Forwarded-For(v2.3.12+), 所以请务必确保 Spug 能获取到用户的真实 IP 而不是上级的代理 IP,如果你使用的推荐的 Docker 部署方式,则这些工作默认已经做好了。 如果要在 Docker 容器暴露的 80 端口上再增加反向代理层,请正确配置 X-Forwarded-For,例如 Nginx 增加 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;。
在无法验证访问者的真实 IP 的情况下(Spug获取到的IP是内网IP),会在登录时弹出一个警告信息,如果 Spug 部署在内网且仅在内网使用(通过内网地址访问 Spug),则可以在 v2.3.14 版本后通过 系统管理 / 系统设置 / 安全设置 / 访问IP校验 来关闭这一特性。

发布过程中不同主机执行不同操作

假设一个应用需要发布到不同的三台主机上,但发布需要在主机上执行一些比如更新数据库等一次性且不能重复执行的操作,这时候可以考虑使用 Spug 的全局变量 SPUG_HOST_ID 或 SPUG_HOST_NAME 来指定只在某个主机上执行这些操作,例如:

if [ "$SPUG_HOST_NAME" = "192.168.10.100" ]; then
    echo "exec sql"
fi

默认PATH环境变量导致命令找不到问题

默认的 PATH 变量可能并不完整,如果出现一些命令找不到等报错情况可以使用类似如下写法来解决这个问题:

# 添加jdk至PATH变量
PATH=$PATH:/usr/local/jdk1.8.0_231/bin
java -jar xxx.jar

项目数据的持久存储

一些项目会在运行过程中生产需要持久存储的数据,例如用户上传的图片或需要留存的日志文件等。当使用常规发布时每个版本都是全新的目录,默认情况下这些文件会 在新版本中不可见。这种情况可以考虑把这些动态生成且需要持久存储的数据放在发布目录之外,通过软链接的形式链接至项目内,这样实际文件存储在一个公共的地 方每次更新时只需要额外做一个软链接的映射就可以解决问题了。

命令执行中的报错处理

从 v3 开始 Spug 移除了 set -e 特性,保持了与默认执行脚本行为一致。 如果你对执行中命令错误敏感,例如期望任何一个命令执行失败则中断 后续的命令,则可以在你编写的命令开头加上 set -e 即可。

使用 su 切换身份执行

默认情况下直接使用 su 命令将会导致执行到该命令时卡住无法继续执行,可通过如下方式使用 su 以使其正常工作:

su - ubuntu << EOF
echo '以ubuntu用户身份执行'
EOF
posted @ 2022-03-28 11:19  minseo  阅读(2956)  评论(0编辑  收藏  举报