# DID-管理台部署文档
## docker-compose单机版部署
### 软件环境准备
| 软件             |   版本   | 描述         |
|:---------------|:------:|:-----------|
| docker         |  18+   | docker容器服务 |
| docker-compose | v1.26+ |            |
| redis集群        |  7.2+  |            |
| mysql          |  V8+   | mysql数据库   |
| 可访问的Docker镜像服务 |   -    | 存储镜像       |
***安装物料包:*** 
[物料包](https://chainmaker-1256298121.cos.ap-beijing.myqcloud.com/did-mgr-docker-compose-v1.1.0_qc.tar.gz)
***解压物料包:***
```shell
    tar xvf ./did-mgr-docker-compose-v1.1.0_qc.tar.gz
```
#### docker与docker-compose
- 确保已有一个运行中的Docker,版本建议为18或更高。
- 已安装docker-compose命令行工具,用于docker-compose.yml的部署。
#### Docker镜像仓库
- 项目方准备一个公网可访问的Docker镜像仓库,用于存储“DID管理台”微服务的镜像。在后续运行部署流程时会自动拉取,如果Kubernetes所在环境无法访问互联网,需要手动载入Docker镜像到Kubernetes的Worker节点。载入命令在物料包中,执行:
```shell 
  ./load_docker_image.sh 
```
即可。
### 部署流程
#### 根据时机需要修改 config 文件
        在实际项目使用中可能会存在测试环境、预生产环境、生产环境等多套环境,请根据实际环境的需求调整ConfigMap中的参数。如复制份数、日志输出等。
```shell
did-kms-etc
└── kms.yaml
did-mgr-common-service-etc
└── did-mgr-common-service-api.yaml
did-mgr-holder-service-etc
└── holder.yaml
did-mgr-issuer-service-etc
└── vc-issuer-api.yaml
```
##### 修改kms.yaml
```shell
Name: kms.rpc
ListenOn: 0.0.0.0:17781
Timeout: 30000
DidService: https://192.168.1.181:30032 #修改为真实的DID服务地址
Database:
  DbType: "mysql"                                                          
  DSN: "root:passw0rd@tcp(ip:13306)/kms_database?parseTime=true"
#  DbType: "kingbase"
#  DSN: "host=192.168.1.181 port=54321 user=SYSTEM password=passw0rd dbname=test sslmode=disable"
```
##### 修改did-mgr-common-service-api.yaml
```shell 
Name: did-mgr-common-service-api
Host: 0.0.0.0
Port: 17782
MaxBytes: 5368709120
Timeout: 10000
service:
  issuer: did-mgr-issuer-service:17884 
  holder: did-mgr-holder-service:17883
  did: http://192.168.1.181:30002 #修改连接到的DID服务地址
adminUser:
  user: admin    #修改默认用户名
  password: password    #修改默认密码
jwt:
  expires_time: 7200
  issuer: did-mgr-issuer-service:17884 
  key: "!@#$abcd%^&*++``123" #修改jwt的key
```
##### 修改holder.yaml
```shell
Name: holder
Host: 0.0.0.0
Port: 17783
GrpcTarget: did-kms:17781
# mysql链接地址,满足 $user:$password@tcp($ip:$port)/$db?$queries 格式即可
#DataSource: root:passw0rd@tcp(192.168.1.181:13306)/holder_database?parseTime=true
Database:
  DbType: "kingbase" #修改为mysql或者kingbase(人大金仓)
  DSN: "root:passw0rd@tcp(mysql:3306)/holder_database?parseTime=true"
  #连接mysql或者人大金仓的数据库连接字符串
```
##### 修改 vc-issuer-api.yaml
```shell
Name: vc-issuer-api
Host: 0.0.0.0
Port: 17784
Database:
  DbType: "mysql" #修改为mysql或者kingbase(人大金仓)
  DSN: "root:passw0rd@tcp(mysql:3306)/mgr_issuer?charset=utf8mb4&parseTime=true&loc=Local" #连接mysql或者人大金仓的数据库连接字符串
Issuer:
  DID: "" #修改颁发者的DID
  IdPrefixUrl: "" #修改服务的URL前缀
DID:
  Endpoint: "192.168.1.181:30003" #DID服务的IP和端口
KMS:
  Endpoints:
    - "did-kms:17781" #DID-KMS服务的server和端口
```
#### 创建Docker容器,部署DID管理台服务
使用`docker-compose`命令部署资源定义文件到docker,以启动所有DID管理台微服务为例(包括数据库):
```shell
docker-compose -f ./db-docker-compose.yml \
-f ./did-kms-docker-compose.yml \
-f ./did-mgr-common-service-docker-compose.yml \
-f ./did-mgr-holder-service-docker-compose.yml \
-f ./did-mgr-issuer-service-docker-compose.yml \
up -d
```
如果没有额外的数据库,那么可以将启动命令改为:
```shell
docker-compose -f ./did-kms-docker-compose.yml \
-f ./did-mgr-common-service-docker-compose.yml \
-f ./did-mgr-holder-service-docker-compose.yml \
-f ./did-mgr-issuer-service-docker-compose.yml \
up -d
```
#### 检查容器部署状态
执行以下命令,确保“DID管理台”微服务已成功启动并运行:
```shell 
 docker ps | grep did-kms
```
返回结果如下,则表示启动成功。
```shell
25473b8ce360   hub-dev.cnbn.org.cn:17754/opennet/did-kms:latest                  "./kms"                  1 hours ago   Up 1 hours   0.0.0.0:17781->17781/tcp, :::17781->17781/tcp
```
#### 访问“DID管理台”
在物料包中提供了checkHealth.sh,运行后可以检查每个服务是否正常运行。其中did-mgr-common-service是对SDK提供服务的网关。
```shell
./checkHealth.sh
```
#### 初始化“DID管理台"数据
打开管理台网站:
http://{NodeIP}:8888
然后注册用户,导入私钥或者企业实名认证生成新私钥,第一个注册的用户将是did管理台的管理员。
### 修改配置管理
        在DID管理台中,所有配置yaml文件进管理,避免在镜像中硬编码配置。当前配置不满足预期,需要进行调整时可执行以下命令进行配置的更新。
        根据需要更新*.yaml中的部分的内容,并使用停止容器然后启动容器以应用新的配置。
```shell
#关闭现有容器
./stopAll.sh
#重新启动容器,将会重新加载配置文件
./startAll.sh
```
### 服务的升级
当DID管理台微服务有新版本发布时,需要更新对应的镜像和容器。
#### 关闭DID管理台服务容器
更新镜像可以如下进行操作,必须先关闭正在运行的容器实例:
```shell
#关闭现有容器
./stopAll.sh
```
#### 更新“DID管理台”服务的镜像
- 在能够访问互联网的情况下,使用以下命令更新镜像:
```shell
 ./pull_docker_image.sh
```
- 对于无法访问互联网的情况下,在服务器上载入最新的物料包,并执行以下命令:
```shell 
 ./load_docker_image.sh
```
#### 重新启动"DID管理台"服务的容器
因为我们保留了latest这个tag,所以无需修改docker-compose.yaml文件,直接运行:
```shell 
./startAll.sh
```
即可通知Docker更新容器为最新的镜像的实例。
## k8s集群版部署
### 软件环境准备
| 软件             |    版本    | 描述         |
|:---------------|:--------:|:-----------|
| k8s集群          |  v1.18+  | 基于docker容器 |
| kubectl工具      | 与k8s集群匹配 |            |
| redis集群        |   7.2+   |            |
| mysql          |   V8+    | mysql数据库   |
| 可访问的Docker镜像服务 |    -     | 存储镜像       |
***物料包下载:***
[物料包](https://chainmaker-1256298121.cos.ap-beijing.myqcloud.com/did-mgr-k8s-v1.1.0_qc.tar.gz)
***解压物料包:***
```shell
tar xvf did-mgr-k8s-v1.1.0_qc.tar.gz
```
#### k8s集群
- 确保已有一个运行中的Kubernetes集群,版本建议为v1.18或更高。
- 已安装并配置`kubectl`命令行工具,用于与Kubernetes集群交互。
#### docker 镜像仓库
- 项目方准备一个公网可访问的Docker镜像仓库,用于存储“DID管理台”微服务的镜像。在后续运行部署流程时会自动拉取,如果Kubernetes所在环境无法访问互联网,需要手动载入Docker镜像到Kubernetes的Worker节点。载入命令在物料包中,执行:
```shell
 ./load_docker_image.sh 
```
即可。
### 部署流程
#### 配置 namespace.yaml 
检查是否存在did namespace,若无记录则创建Namespace
```shell
    kubectl get ns|grep did
```
创建 did namespace 
```shell
    # 进入kubectl命令所在服务器
    vim did-ns.yaml
    # 输入如下配置
    # vim开始
    apiVersion: v1
    kind: Namespace
    metadata:
      name: did
    # vim结束,保存文件退出
    
    # 创建namespace
    kubectl apply -f did-ns.yaml
```
#### 根据时机需要修改 ConfigMap
##### 修改 did-kms-configmap
```shell
    apiVersion: v1
    data:
      kms.yaml: |-
        Name: kms.rpc
        ListenOn: 0.0.0.0:17781
        Timeout: 30000
        DidService: https://192.168.1.181:30032
        Database:
          DbType: "mysql"                                                          
          DSN: "root:passw0rd@tcp(ip:13306)/kms_database?parseTime=true"
       #  DbType: "kingbase"
       #  DSN: "host=192.168.1.181 port=54321 user=SYSTEM password=passw0rd dbname=test sslmode=disable"
        kind: ConfigMap
    metadata:
      name: did-kms-configmap
```
##### 修改did-mgr-common-service-configmap
```shell
    apiVersion: v1
    data:
      did-mgr-common-service-api.yaml: |-
        Name: did-mgr-common-service-api
        Host: 0.0.0.0
        Port: 17782
        MaxBytes: 5368709120
        Timeout: 10000
    
        service:
          issuer: http://did-mgr-issuer-service:17884
          holder: http://did-mgr-holder-service:17883
          did: http://192.168.1.181:30002
    
        adminUser:
          user: admin
          password: password
    
        jwt:
          expires_time: 7200
          issuer: did-mgr-issuer-service:17884
          key: "!@#$abcd%^&*++``123"
    kind: ConfigMap
    metadata:
      creationTimestamp: null
      name: did-mgr-common-service-configmap
```
##### 修改did-mgr-holder-service-configmap
```shell
    apiVersion: v1
    data:
      holder.yaml: |-
        Name: holder
        Host: 0.0.0.0
        Port: 27781
        GrpcTarget: did-kms-service:17781
        Database:
          DbType: "mysql"
          DSN: "root:passw0rd@tcp(9.135.0.21:3306)/holder_database?parseTime=true"
    kind: ConfigMap
    metadata:
      creationTimestamp: null
      name: did-mgr-holder-service-configmap
```
##### 修改did-mgr-issuer-service-configmap
```shell
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: did-mgr-issuer-service-configmap
    data:
      vc-issuer-api.yaml: |-
        Name: vc-issuer-api
        Host: 0.0.0.0
        Port: 17784
        Database:
          DbType: "mysql"
          DSN: "root:passw0rd@tcp(9.135.0.21:3306)/mgr_issuer?charset=utf8mb4&parseTime=true&loc=Local"
        Issuer:
          DID: "did:cnbn:b27356b68f224d6394dabb69144bdf7e"
          IdPrefixUrl: "http://192.168.1.181:30002/api/v1/did/vc/"
        DID:
          Endpoint: "192.168.1.181:30032"
        KMS:
          Endpoints:
            - "did-kms-service:17781"
```
##### 修改did-mgr-front-configmap
这里主要是前端网页的Nginx配置,具体如下:
```shell
    gzip_types
      application/atom+xml
      application/javascript
      application/json
      application/rss+xml
      application/vnd.ms-fontobject
      application/x-font-ttf
      application/x-web-app-manifest+json
      application/xhtml+xml
      application/xml
      application/octet-stream
      font/opentype
      image/svg+xml
      image/x-icon
      text/css
      text/plain
      text/x-component;
    
    server {
        listen 8888;
        root /usr/share/nginx/html;
        index index.html;
    
        location / {
         try_files $uri $uri/ /index.html;
        }
        
        location /api/ {
          proxy_read_timeout 300;
          proxy_pass http://192.168.3.170:18782/;
        }
    
    }
```
#### 部署到k8s集群
        使用`kubectl apply`命令部署资源定义文件到k8s集群,以did-kms微服务为例:
```shell
  kubectl apply -f did-kms-deployment.yaml
```
#### 检查pod状态
执行下列命令,确保"DID管理台”微服务已成功启动并运行:
```shell 
  kubectl apply -f did-kms-deployment.yaml
```
返回结果如下,1/1则表示微服务有一个实例,启动成功1个pod实例,如果是2/2则表示有两个实例,启动成功了2个pod实例。
```shell 
  did-kms-XXXXX-XXX      1/1     Running   0               1d
```
检查Service和Ingress资源配置,保外部访问路径和端口正确:
```shell
  kubectl get svc,ing | grep did-kms
```
#### 部署其他微服务
使用相同的方法,运行kubectl apply可以部署剩余的管理台微服务:
```shell
  kubectl apply -f did-mgr-common-service-deployment.yaml
  kubectl apply -f did-mgr-issuer-service-deployment.yaml
  kubectl apply -f did-mgr-holder-service-deployment.yaml
  kubectl apply -f did-mgr-front.yaml
```
#### 访问“DID管理台”
根据Ingress资源配置,通过或其他HTTP客户端访问“DID理台”的URL:
```shell
    curl -s http://{NodeIP}:30782/api/v1/did/health
    curl -s http://{NodeIP}:30783/api/v1/did/health
    curl -s http://{NodeIP}:30784/api/v1/did/health
```
#### 初始化did管理台数据
打开管理台网站:
http://{NodeIP}:38888
然后注册用户,导入私钥或者企业实名认证生成新私钥,第一个注册的用户将是did管理台的管理员。
### 配置管理
        在DID管理台中,所有配置应通过k8s的ConfigMap进管理,避免在镜像中硬编码配置。当前配置不满足预期,需要进行调整时可执行以下命令进行配置的更新。
- 根据需要更新deployment.yaml中的ConfigMap部分的内容,并使用`kubectl rollout restart`重启Pod以应用新的配置。
```shell
    kubectl rollout restart deployment/did-kms
```
### 服务升级
当DID管理台微服务有新版本发布时,需要更新对应的镜像和容器。
#### 更新“DID管理台”服务的镜像
更新镜像可以进行如下操作, 以did-kms服务为例:
- 在能够访问互联网的情况下,使用以下命令更新镜像:
```shell
  docker pull hub-dev.cnbn.org.cn:17754/opennet/did-kms:latest
```
- 对于无法访问互联网的情况下,在服务器上载入最新的物料包,并执行以下命令:
```shell
  docker load -i did-kms-v2.tar
  docker tag hub-dev.cnbn.org.cn:17754/opennet/did-kms:latest hub-dev.cnbn.org.cn:17754/opennet/did-kms:v1_bak
  docker tag did-kms:v2 hub-dev.cnbn.org.cn:17754/opennet/did-kms:latest
```
#### 更新DID管理台服务的容器
因为我们保留了latest这个tag,所以无需修改deployment.yaml文件,直接运行:
```shell
    kubectl rollout restart did-kms
```
即可通知k8s更新pod容器为最新的镜像的实例。
## 二进制单机版部署
本章节适用于企业环境无K8s集群,无Docker,采用单机二进制部署的场景。
### 软件环境准备
| 软件         |  版本   | 描述                 |
|:-----------|:-----:|:-------------------|
| redis集群    | 7.2+  |                    |
| mysql      |  V8+  | mysql数据库           |
| Nginx      | 1.24+ |                    |   
| Linux部署物料包 |   -   | did-mgr-bin.tar.gz |
### 部署流程
#### 解压物料包
[物料包](https://chainmaker-1256298121.cos.ap-beijing.myqcloud.com/did-mgr-bin-v1.1.0_qc.tar.gz)
```shell
    tar xvf ./did-mgr-bin-v1.1.0_qc.tar.gz
```
#### 根据实际需要修改config文件
        在实际项目使用中可能会存在测试环境、预生产环境、生产环境等多套环境,请根据实际环境的需求调整.yaml配置文件中的参数。如复制份数、日志输出等:
```shell
    did-kms-etc
    └── kms.yaml
    did-mgr-common-service-etc
    └── did-mgr-common-service-api.yaml
    did-mgr-holder-service-etc
    └── holder.yaml
    did-mgr-issuer-service-etc
    └── vc-issuer-api.yaml
```
##### 修改kms.yaml
```shell 
    Name: kms.rpc
    ListenOn: 0.0.0.0:17781
    Timeout: 30000 
    DidService: https://192.168.1.181:30032 #修改为真实的DID服务地址
    Database:
      DbType: "mysql"
      DSN: "root:passw0rd@tcp(192.168.1.182:13306)/kms_database?parseTime=true"
    #  DbType: "kingbase"
    #  DSN: "host=192.168.1.181 port=54321 user=SYSTEM password=passw0rd dbname=test sslmode=disable"
```
##### 修改did-mgr-common-service-api.yaml
```shell
    Name: did-mgr-common-service-api
    Host: 0.0.0.0
    Port: 17782
    MaxBytes: 5368709120
    Timeout: 10000
    
    service:
      issuer: did-mgr-issuer-service:17884 
      holder: did-mgr-holder-service:17883
      did: http://192.168.1.181:30002 #修改连接到的DID服务地址
    
    adminUser:
      user: admin    #修改默认用户名
      password: password    #修改默认密码
    
    jwt:
      expires_time: 7200
      issuer: did-mgr-issuer-service:17884 
      key: "!@#$abcd%^&*++``123" #修改jwt的key
```
##### 修改holder.yaml
```shell
    Name: holder
    Host: 0.0.0.0
    Port: 17783
    GrpcTarget: did-kms:17781
    # mysql链接地址,满足 $user:$password@tcp($ip:$port)/$db?$queries 格式即可
    #DataSource: root:passw0rd@tcp(192.168.1.181:13306)/holder_database?parseTime=true
    Database:
        DbType: "kingbase" #修改为mysql或者kingbase(人大金仓)
        DSN: "root:passw0rd@tcp(mysql:3306)/holder_database?parseTime=true" #连接mysql或者人大金仓的数据库连接字符串
```
##### 修改vc-issuer-api.yaml
```shell
    Name: vc-issuer-api
    Host: 0.0.0.0
    Port: 17784
    
    Database:
      DbType: "mysql" #修改为mysql或者kingbase(人大金仓)
      DSN: "root:passw0rd@tcp(mysql:3306)/mgr_issuer?charset=utf8mb4&parseTime=true&loc=Local" #连接mysql或者人大金仓的数据库连接字符串
    
    Issuer:
      DID: "" #修改颁发者的DID
      IdPrefixUrl: "" #修改服务的URL前缀
    
    DID:
      Endpoint: "192.168.1.181:30003" #DID服务的IP和端口
    
    KMS:
      Endpoints:
        - "did-kms:17781" #DID-KMS服务的server和端口
```
#### 运行二进制,部署DID管理台后台服务
使用`https://startAll.sh`命令部署DID管理台服务,以启动所有DID管理台微服务为例(数据库请提前启动好):
```shell
    #!/bin/bash
    # Start did-kms and output logs to did-kms.log
    nohup ./did-kms -f ./did-kms-etc/kms.yaml > did-kms.log 2>&1 &
    
    # Start did-mgr-holder-service and output logs to did-mgr-holder-service.log
    nohup ./did-mgr-holder-service -f ./did-mgr-holder-service-etc/holder.yaml > did-mgr-holder-service.log 2>&1 &
    
    # Start did-mgr-issuer-service and output logs to did-mgr-issuer-service.log
    nohup ./did-mgr-issuer-service -f ./did-mgr-issuer-service-etc/vc-issuer-api.yaml > did-mgr-issuer-service.log 2>&1 &
    
    # Start did-mgr-common-service and output logs to did-mgr-common-service.log
    nohup ./did-mgr-common-service -f ./did-mgr-common-service-etc/did-mgr-common-service-api.yaml > did-mgr-common-service.log 2>&1 &
    
    echo "All services have been started."
```
#### 检查进程状态
执行完上面的 startAll.sh后,需要执行下面的命令,确认“DID管理台”微服务已成功启动并运行:
```shell 
  ps aux | grep did
```
返回结果如下,则表示启动成功:
```shell 
    devinyz+ 3255760  1.6  0.2 2125964 47460 pts/0   Sl   11:31   0:00 ./did-kms -f ./did-kms-etc/kms.yaml
    devinyz+ 3255761  1.6  0.3 2171468 57412 pts/0   Sl   11:31   0:00 ./did-mgr-holder-service -f ./did-mgr-holder-service-etc/holder.yaml
    devinyz+ 3255762  1.6  0.3 2238116 54528 pts/0   Sl   11:31   0:00 ./did-mgr-issuer-service -f ./did-mgr-issuer-service-etc/vc-issuer-api.yaml
    devinyz+ 3255763  0.6  0.1 1863036 29528 pts/0   Sl   11:31   0:00 ./did-mgr-common-service -f ./did-mgr-common-service-etc/did-mgr-common-service-api.yaml
```
#### 在Nginx中部署“DID管理台”前端
在物料包中提供了did-mgr-front.tar.gz,解压该物料包:
```shell
    tar xvf did-mgr-front.tar.gz
```
将获得dist文件夹和deploy文件夹。
在deploy文件夹中包含Nginx配置文件,复制其到Nginx配置文件夹:
```shell
    sudo cp deploy/nginx/conf.d/default.conf /etc/nginx/conf.d
```
dist文件夹为前端相关html、js等文件,修改/etc/nginx/conf.d/default.conf文件,将默认的/usr/share/nginx/html替换为之前解压出来的dist文件夹路径:
```shell
    root/data/did-mgr-front/dist;
```
proxy_pass的值为前面部署的did-mgr-common-service的URL,如:
```shell
    proxy_pass http://localhost:18782/;
```
重启Nginx服务,浏览器访问: http://{服务器IP}:8888
即可!
#### 初始化did管理台数据
打开管理台网站:
http://{NodeIP}:8888
然后注册用户,导入私钥或者企业实名认证生成新私钥,第一个注册的用户将是did管理台的管理员。
### 修改配置管理
        在DID管理台中,所有配置yaml文件进管理,避免在镜像中硬编码配置。当前配置不满足预期,需要进行调整时可执行以下命令进行配置的更新。
- 对于后端服务: 根据需要更新*.yaml中的部分的内容,并使用stopAll.sh停止进程,然后启动服务以应用新的配置。
```shell 
    #关闭现有DID服务
    ./stopAll.sh
    #重新启动DID服务,将会重新加载配置文件
    ./startAll.sh
```
- 对于前端服务,因为是基于Nginx,请使用Nginx服务的命令进行服务的关闭和重启。
```shell
     #关闭Nginx服务
    sudo systemctl stop nginx
    #重启Nginx服务
    sudo systemctl restart nginx
```
### 服务的升级
当DID管理台微服务有新版本发布时,需要更新对应的二进制。
在服务器上载入最新的物料包,并执行以下命令:
```shell
    ./upgradeAll.sh
```
系统会自动完成物料包的解压、服务的停止、二进制文件的替换、服务的启动等动作。