## 1. Project Overview & Quickstart (openspug/docker-compose.yml)

# docker-compose.yml

Open-source repository openspug/docker-compose.yml

### Repository Details
- **Repository:** [openspug/docker-compose.yml](https://github.com/openspug/docker-compose.yml)
- **Primary Language:** Code

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (openspug/docs)

## File: docs/guides/alarm/alarm-contact.md

---
id: alarm-contact
slug: /alarm-contact
title: 报警联系人
sidebar_position: 2
---

## 介绍

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

## 小提示
- 微信 Token 的获取需要关注公众号Spug 在 **我的** 菜单中获取。
- 内置的微信和邮件报警模式需要配置调用凭据，调用凭据的获取方式与微信 Token 相同，获取调用凭据后，将调用凭据配置至系统设置 / 报警服务设置 中的调用凭据中即可。
- 调用凭据可以是任何一个有效的微信 Token。
- 由于微信的限制，你必须关注公众号才能收到微信报警信息。
- [钉钉收不到通知？](/docs/use-problem/#use-dd)
- Spug 服务号

---

## File: docs/guides/alarm/alarm-group.md

---
id: alarm-group
slug: /alarm-group
title: 报警联系组
sidebar_position: 3
---

## 介绍

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

---

## File: docs/guides/alarm/alarm-record.md

---
id: alarm-record
slug: /alarm-record
title: 报警记录
sidebar_position: 1
---

## 介绍

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

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

---

## File: docs/guides/app/deploy-app.md

---
id: deploy-app
slug: /deploy-app
title: 应用管理
---

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

## 配置项
- ***应用名称*** 自定义的应用名称
- ***唯一标识符*** 会作为配置中心生成配置 Key 的前缀，具体请参考配置中心相关文档。

## 小提示
- 配置中心和应用发布模块都可以创建应用，它们的数据是互通的。
- 环境的创建功能，在配置中心模块的环境管理页面。

---

## File: docs/guides/app/deploy-config.md

---
id: deploy-config
slug: /deploy-config
title: 发布配置
---

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

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

:::info 说明
常规发布参考了开源项目 [瓦力](https://github.com/meolu/walle-web) 的一些设计思路，在此感谢。
如果你使用过 `瓦力` 的发布，可以直接迁移至常规发布。
:::

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

:::tip 提示
[使用 `nohup` 或 `&` 启动后台进程页面一直在转圈不会结束？](/docs/use-problem#nohup)
:::

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

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

:::tip 提示
[使用 `nohup` 或 `&` 启动后台进程页面一直在转圈不会结束？](/docs/use-problem#nohup)
:::

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

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

当数据来源为发布时上传，需要注意以下事项：

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

下面以 [Spug](https://github.com/openspug/spug) 开源项目的源代码作为例子来说明当数据来源为本地路径时几种典型情况，假设源代码位于 `/data/spug` 目录下。

- **本地路径：`/data/spug`，目标路径：`/www/spug`，文件过滤：`关闭`**

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

- **本地路径：`/data/spug`，目标路径：`/www/spug`，文件过滤：`包含` `spug_api,spug_web/dist`**

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

- **本地路径：`/data/spug/README.md`，目标路径：`/www/spug/README.md`, 文件过滤：`包含` `spug_api`**

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

- **本地路径：`/data/spug/README.md`, 目标路径：`/www/spug`，文件过滤：`关闭`**

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

- **本地路径：`/data/spug`, 目标路径：`/www/spug/README.md`，文件过滤：`关闭`**

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


## 全局变量 {#global-env}
- `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" 为回滚，"3" Webhook触发自动发布）
- `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` 值（自定义发布有效）

  :::tip 提示
  SPUG_RELEASE 会自动按空格分隔解析为多个环境变量，例如 abc 123 def，会对应有4个变量：
  ```bash
  SPUG_RELEASE = abc 123 def
  SPUG_RELEASE_1 = abc
  SPUG_RELEASE_2 = 123
  SPUG_RELEASE_3 = def
  ```
  :::

---

## File: docs/guides/app/deploy-request.md

---
id: deploy-request
slug: /deploy-request
title: 发布申请
---

## 介绍
创建和执行发布。

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

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

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

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

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

---

## File: docs/guides/app/deploy-rollback.md

---
id: deploy-rollback
slug: /deploy-rollback
title: 回滚机制
---

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

## 常规发布
常规发布由发布配置中的 `保留历史版本数量` 来决定是否可以回滚，超过保留上限的版本将无法执行回滚操作。回滚将经历以下几个步骤：
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` 为回滚发布。 用户可通过判断其值来实现不同情况下的不同操作，
例如：

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

---

## File: docs/guides/config/conf-app.md

---
id: conf-app
slug: /conf-app
title: 应用管理
sidebar_position: 3
---

## 介绍

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

- `公共` 配置

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

- `私有` 配置

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

---

## File: docs/guides/config/conf-env.md

---
id: conf-env
slug: /conf-env
title: 环境管理
sidebar_position: 1
---

## 介绍

管理应用的运行环境，一般包含开发环境、测试环境和生产环境，应用发布和配置管理需要用它来区分不同的环境。

创建环境时设置的 `唯一标识符` 用于配置中心提供的开放 API 调用，详情参考 [API文档](/docs/config-api)。

---

## File: docs/guides/config/conf-service.md

---
id: conf-service
slug: /conf-service
title: 服务管理
sidebar_position: 2
---

## 介绍

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

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

---

## File: docs/guides/config/conf-set.md

---
id: conf-set
slug: /conf-set
title: 配置管理
sidebar_position: 4
---

## 介绍

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

:::tip 提示
在 Spug 之外使用配置中心的配置信息，取请参考 [API文档](/docs/config-api)
:::


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

---

## File: docs/guides/config/config-api.md

---
id: config-api
slug: /config-api
title: API
sidebar_position: 5
---

## 介绍

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

## 规则
应用的配置将从以下途径获取并进行组合：
- 该应用在指定环境下的 `公共` 和 `私有` 配置
- 所依赖的应用的 `公共` 配置
- 所依赖的服务的配置
- 根据指定的环境，仅读取指定环境的以上配置


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

### 在发布配置的钩子内获取

- 请求地址：`/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` 文件中。
    
    

### 独立使用

- 请求地址：`/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
    
    ```shell script
    curl "https://demo.spug.dev/api/apis/config/?apiKey=JLV8IGO0DhoxcM7I&app=order&env=test"
    ```
    输出如下
    ```shell script
    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
    
    ```shell script
    curl "https://demo.spug.dev/api/apis/config/?apiKey=JLV8IGO0DhoxcM7I&app=order&env=test&noPrefix=1"
    ```
    输出如下
    ```shell script
    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
    ```
  
  :::info 说明
  可以通过对比发现，在 `noPrefix` 模式下，服务 `订单主库`（标识符 db_order）的配置 `host` 和 `password` 被服务 `Redis服务`（标识符 redis）覆盖了，所以最终的配置意外丢失了2个。
  :::