From abf8e37e7883c11609922e3409a038fac4164a4d Mon Sep 17 00:00:00 2001
From: xuexihuang <1339326187@qq.com>
Date: Mon, 16 Oct 2023 18:02:12 +0800
Subject: [PATCH] feat: Add the help chart script to support k8s deployment
 (#1145)

* Code adaptation k8s: service discovery and registration adaptation, configuration adaptation

* Initial submission of the help charts script for openim API

* change the help charts script

* change the help charts script

* change helm chart codes

* change dockerfiles script

* change chart script:add configmap mounts

* change chart script:change repository

* change chart script:msggateway add one service

* change config.yaml

* roll back some config values

* change chart script:change Ingress rule with a rewrite annotation

* add mysql charts scrible

* change chart script:add mysql.config.yaml

* add nfs provisioner charts

* change chart script:add nfs.config.yaml

* add ingress-nginx charts

* change chart script:add ingress-nginx.config.yaml

* add redis &mongodb charts

* add kafka&minio charts

* change chart script:change redis.values.yaml

* change chart script:add redis.config.yaml

* change chart script:change redis.config.yaml

* change chart script:change mongodb.value.yaml

* change chart script:change mongodb.value.yaml

* change chart script:add mongodb.config.yaml

* change chart script:change minio.values.yaml

* change chart script:add minio.config.yaml

* change chart script:change kafka.values.yaml

* change chart script:add kafka.config.yaml

* change chart script:change services.config.yaml

* bug fix:Delete websocket's Port restrictions

* bug fix:change port value

* change chart script:Submit a stable version script

* fix bug:Implement option interface

* fix bug:change K8sDR.Register

* change config.yaml

* change chats script:minio service add ingress

* change chats script:minio service add ingress

* change chats script:kafka.replicaCount=3& change minio.api ingress

* delete change chats script

* change config.yaml

* change openim.yaml

---------

Co-authored-by: lin.huang <lin.huang@apulis.com>
---
 cmd/openim-api/main.go                        | 19 ++--
 cmd/openim-push/main.go                       |  2 +-
 cmd/openim-rpc/openim-rpc-auth/main.go        |  2 +-
 .../openim-rpc-conversation/main.go           |  2 +-
 cmd/openim-rpc/openim-rpc-friend/main.go      |  2 +-
 cmd/openim-rpc/openim-rpc-group/main.go       |  2 +-
 cmd/openim-rpc/openim-rpc-msg/main.go         |  2 +-
 cmd/openim-rpc/openim-rpc-third/main.go       |  2 +-
 cmd/openim-rpc/openim-rpc-user/main.go        |  2 +-
 config/config.yaml                            |  4 +
 deployments/templates/openim.yaml             |  3 +
 internal/msggateway/n_ws_server.go            |  3 -
 internal/msgtransfer/init.go                  | 15 ++--
 internal/tools/msg.go                         | 14 +--
 manifest/build-docker.sh                      | 37 ++++++++
 manifest/dockerfiles/openim-api/Dockerfile    | 27 ++++++
 .../dockerfiles/openim-crontask/Dockerfile    | 27 ++++++
 .../dockerfiles/openim-msggateway/Dockerfile  | 27 ++++++
 .../dockerfiles/openim-msgtransfer/Dockerfile | 27 ++++++
 manifest/dockerfiles/openim-push/Dockerfile   | 27 ++++++
 .../dockerfiles/openim-rpc-auth/Dockerfile    | 27 ++++++
 .../openim-rpc-conversation/Dockerfile        | 27 ++++++
 .../dockerfiles/openim-rpc-friend/Dockerfile  | 27 ++++++
 .../dockerfiles/openim-rpc-group/Dockerfile   | 27 ++++++
 .../dockerfiles/openim-rpc-msg/Dockerfile     | 27 ++++++
 .../dockerfiles/openim-rpc-third/Dockerfile   | 27 ++++++
 .../dockerfiles/openim-rpc-user/Dockerfile    | 27 ++++++
 pkg/common/cmd/api.go                         | 19 +++-
 pkg/common/cmd/constant.go                    | 12 +++
 pkg/common/cmd/cron_task.go                   |  4 +-
 pkg/common/cmd/msg_gateway.go                 | 22 ++++-
 pkg/common/cmd/msg_transfer.go                |  6 +-
 pkg/common/cmd/root.go                        | 23 ++++-
 pkg/common/cmd/rpc.go                         | 45 +++++++++-
 pkg/common/config/config.go                   | 12 ++-
 .../k8s_discovery_register.go                 | 88 +++++++++++++++++++
 pkg/common/startrpc/start.go                  | 21 +++--
 scripts/install/environment.sh                |  2 +
 38 files changed, 628 insertions(+), 61 deletions(-)
 create mode 100755 manifest/build-docker.sh
 create mode 100644 manifest/dockerfiles/openim-api/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-crontask/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-msggateway/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-msgtransfer/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-push/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-rpc-auth/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-rpc-conversation/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-rpc-friend/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-rpc-group/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-rpc-msg/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-rpc-third/Dockerfile
 create mode 100644 manifest/dockerfiles/openim-rpc-user/Dockerfile
 create mode 100644 pkg/common/cmd/constant.go
 create mode 100644 pkg/common/discovery_register/k8s_discovery_register.go

diff --git a/cmd/openim-api/main.go b/cmd/openim-api/main.go
index 17a7c4724..3034d6645 100644
--- a/cmd/openim-api/main.go
+++ b/cmd/openim-api/main.go
@@ -17,15 +17,13 @@ package main
 import (
 	"context"
 	"fmt"
+	"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
 	"net"
-	"strconv"
-	"time"
-
 	_ "net/http/pprof"
+	"strconv"
 
 	"github.com/OpenIMSDK/protocol/constant"
 	"github.com/OpenIMSDK/tools/discoveryregistry"
-	openkeeper "github.com/OpenIMSDK/tools/discoveryregistry/zookeeper"
 	"github.com/OpenIMSDK/tools/log"
 
 	"github.com/openimsdk/open-im-server/v3/internal/api"
@@ -44,6 +42,7 @@ func main() {
 }
 
 func run(port int) error {
+	fmt.Println("*****openimapi port:", port)
 	if port == 0 {
 		return fmt.Errorf("port is empty")
 	}
@@ -53,11 +52,13 @@ func run(port int) error {
 	}
 	fmt.Println("api start init discov client")
 	var client discoveryregistry.SvcDiscoveryRegistry
-	client, err = openkeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
-		openkeeper.WithFreq(time.Hour), openkeeper.WithUserNameAndPassword(
-			config.Config.Zookeeper.Username,
-			config.Config.Zookeeper.Password,
-		), openkeeper.WithRoundRobin(), openkeeper.WithTimeout(10), openkeeper.WithLogger(log.NewZkLogger()))
+	client, err = discovery_register.NewDiscoveryRegister(config.Config.Envs.Discovery)
+	/*
+		client, err = openkeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
+			openkeeper.WithFreq(time.Hour), openkeeper.WithUserNameAndPassword(
+				config.Config.Zookeeper.Username,
+				config.Config.Zookeeper.Password,
+			), openkeeper.WithRoundRobin(), openkeeper.WithTimeout(10), openkeeper.WithLogger(log.NewZkLogger()))*/
 	if err != nil {
 		return err
 	}
diff --git a/cmd/openim-push/main.go b/cmd/openim-push/main.go
index 6ab2fedab..c19cfda60 100644
--- a/cmd/openim-push/main.go
+++ b/cmd/openim-push/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	pushCmd := cmd.NewRpcCmd("push")
+	pushCmd := cmd.NewRpcCmd(cmd.RpcPushServer)
 	pushCmd.AddPortFlag()
 	pushCmd.AddPrometheusPortFlag()
 	if err := pushCmd.Exec(); err != nil {
diff --git a/cmd/openim-rpc/openim-rpc-auth/main.go b/cmd/openim-rpc/openim-rpc-auth/main.go
index d27a3f11b..645d8cab8 100644
--- a/cmd/openim-rpc/openim-rpc-auth/main.go
+++ b/cmd/openim-rpc/openim-rpc-auth/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	authCmd := cmd.NewRpcCmd("auth")
+	authCmd := cmd.NewRpcCmd(cmd.RpcAuthServer)
 	authCmd.AddPortFlag()
 	authCmd.AddPrometheusPortFlag()
 	if err := authCmd.Exec(); err != nil {
diff --git a/cmd/openim-rpc/openim-rpc-conversation/main.go b/cmd/openim-rpc/openim-rpc-conversation/main.go
index 80a92de92..13d7db605 100644
--- a/cmd/openim-rpc/openim-rpc-conversation/main.go
+++ b/cmd/openim-rpc/openim-rpc-conversation/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	rpcCmd := cmd.NewRpcCmd("conversation")
+	rpcCmd := cmd.NewRpcCmd(cmd.RpcConversationServer)
 	rpcCmd.AddPortFlag()
 	rpcCmd.AddPrometheusPortFlag()
 	if err := rpcCmd.Exec(); err != nil {
diff --git a/cmd/openim-rpc/openim-rpc-friend/main.go b/cmd/openim-rpc/openim-rpc-friend/main.go
index c0c91e4dc..ec18306a2 100644
--- a/cmd/openim-rpc/openim-rpc-friend/main.go
+++ b/cmd/openim-rpc/openim-rpc-friend/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	rpcCmd := cmd.NewRpcCmd("friend")
+	rpcCmd := cmd.NewRpcCmd(cmd.RpcFriendServer)
 	rpcCmd.AddPortFlag()
 	rpcCmd.AddPrometheusPortFlag()
 	if err := rpcCmd.Exec(); err != nil {
diff --git a/cmd/openim-rpc/openim-rpc-group/main.go b/cmd/openim-rpc/openim-rpc-group/main.go
index d2d4f727a..887329926 100644
--- a/cmd/openim-rpc/openim-rpc-group/main.go
+++ b/cmd/openim-rpc/openim-rpc-group/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	rpcCmd := cmd.NewRpcCmd("group")
+	rpcCmd := cmd.NewRpcCmd(cmd.RpcGroupServer)
 	rpcCmd.AddPortFlag()
 	rpcCmd.AddPrometheusPortFlag()
 	if err := rpcCmd.Exec(); err != nil {
diff --git a/cmd/openim-rpc/openim-rpc-msg/main.go b/cmd/openim-rpc/openim-rpc-msg/main.go
index 0ac258d0c..dcc3abef5 100644
--- a/cmd/openim-rpc/openim-rpc-msg/main.go
+++ b/cmd/openim-rpc/openim-rpc-msg/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	rpcCmd := cmd.NewRpcCmd("msg")
+	rpcCmd := cmd.NewRpcCmd(cmd.RpcMsgServer)
 	rpcCmd.AddPortFlag()
 	rpcCmd.AddPrometheusPortFlag()
 	if err := rpcCmd.Exec(); err != nil {
diff --git a/cmd/openim-rpc/openim-rpc-third/main.go b/cmd/openim-rpc/openim-rpc-third/main.go
index 913962b82..cf0bf4b70 100644
--- a/cmd/openim-rpc/openim-rpc-third/main.go
+++ b/cmd/openim-rpc/openim-rpc-third/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	rpcCmd := cmd.NewRpcCmd("third")
+	rpcCmd := cmd.NewRpcCmd(cmd.RpcThirdServer)
 	rpcCmd.AddPortFlag()
 	rpcCmd.AddPrometheusPortFlag()
 	if err := rpcCmd.Exec(); err != nil {
diff --git a/cmd/openim-rpc/openim-rpc-user/main.go b/cmd/openim-rpc/openim-rpc-user/main.go
index f2ebc94db..cbf2a8fc3 100644
--- a/cmd/openim-rpc/openim-rpc-user/main.go
+++ b/cmd/openim-rpc/openim-rpc-user/main.go
@@ -21,7 +21,7 @@ import (
 )
 
 func main() {
-	rpcCmd := cmd.NewRpcCmd("user")
+	rpcCmd := cmd.NewRpcCmd(cmd.RpcUserServer)
 	rpcCmd.AddPortFlag()
 	rpcCmd.AddPrometheusPortFlag()
 	if err := rpcCmd.Exec(); err != nil {
diff --git a/config/config.yaml b/config/config.yaml
index d2162d4b2..0f980b4e4 100644
--- a/config/config.yaml
+++ b/config/config.yaml
@@ -26,6 +26,9 @@
 # Zookeeper address
 # Zookeeper username
 # Zookeeper password
+envs:
+  discovery: zookeeper
+
 zookeeper:
   schema: openim
   address: [ 172.28.0.1:12181 ]
@@ -213,6 +216,7 @@ log:
 # Websocket connection handshake timeout
 longConnSvr:
   openImWsPort: [ 10001 ]
+  openImMessageGatewayPort: [ 10140 ]
   websocketMaxConnNum: 100000
   websocketMaxMsgLen: 4096
   websocketTimeout: 10
diff --git a/deployments/templates/openim.yaml b/deployments/templates/openim.yaml
index b029826a9..ff0121062 100644
--- a/deployments/templates/openim.yaml
+++ b/deployments/templates/openim.yaml
@@ -19,6 +19,9 @@
 # --| target: config/config.yaml
 # -----------------------------------------------------------------
 
+envs:
+  discovery: ${ENVS_DISCOVERY}
+
 ###################### Zookeeper ######################
 # Zookeeper configuration
 # It's not recommended to modify the schema
diff --git a/internal/msggateway/n_ws_server.go b/internal/msggateway/n_ws_server.go
index f437f9d8c..07a83fb5c 100644
--- a/internal/msggateway/n_ws_server.go
+++ b/internal/msggateway/n_ws_server.go
@@ -143,9 +143,6 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
 	for _, o := range opts {
 		o(&config)
 	}
-	if config.port < 1024 {
-		return nil, errors.New("port not allow to listen")
-	}
 	v := validator.New()
 	return &WsServer{
 		port:             config.port,
diff --git a/internal/msgtransfer/init.go b/internal/msgtransfer/init.go
index db48ead70..4487826ee 100644
--- a/internal/msgtransfer/init.go
+++ b/internal/msgtransfer/init.go
@@ -16,14 +16,11 @@ package msgtransfer
 
 import (
 	"fmt"
-	"sync"
-	"time"
-
+	"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
+	"sync"
 
-	openkeeper "github.com/OpenIMSDK/tools/discoveryregistry/zookeeper"
-	"github.com/OpenIMSDK/tools/log"
 	"github.com/OpenIMSDK/tools/mw"
 
 	"github.com/openimsdk/open-im-server/v3/pkg/common/config"
@@ -62,9 +59,11 @@ func StartTransfer(prometheusPort int) error {
 	if err := mongo.CreateMsgIndex(); err != nil {
 		return err
 	}
-	client, err := openkeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
-		openkeeper.WithFreq(time.Hour), openkeeper.WithRoundRobin(), openkeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
-			config.Config.Zookeeper.Password), openkeeper.WithTimeout(10), openkeeper.WithLogger(log.NewZkLogger()))
+	client, err := discovery_register.NewDiscoveryRegister(config.Config.Envs.Discovery)
+	/*
+		client, err := openkeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
+			openkeeper.WithFreq(time.Hour), openkeeper.WithRoundRobin(), openkeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
+				config.Config.Zookeeper.Password), openkeeper.WithTimeout(10), openkeeper.WithLogger(log.NewZkLogger()))*/
 	if err != nil {
 		return err
 	}
diff --git a/internal/tools/msg.go b/internal/tools/msg.go
index 93f5c3a8a..5397689b2 100644
--- a/internal/tools/msg.go
+++ b/internal/tools/msg.go
@@ -17,14 +17,12 @@ package tools
 import (
 	"context"
 	"fmt"
-	"math"
-	"time"
-
+	"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
 	"github.com/redis/go-redis/v9"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
+	"math"
 
-	"github.com/OpenIMSDK/tools/discoveryregistry/zookeeper"
 	"github.com/OpenIMSDK/tools/errs"
 	"github.com/OpenIMSDK/tools/log"
 	"github.com/OpenIMSDK/tools/mcontext"
@@ -74,9 +72,11 @@ func InitMsgTool() (*MsgTool, error) {
 	if err != nil {
 		return nil, err
 	}
-	discov, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
-		zookeeper.WithFreq(time.Hour), zookeeper.WithRoundRobin(), zookeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
-			config.Config.Zookeeper.Password), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))
+	discov, err := discovery_register.NewDiscoveryRegister(config.Config.Envs.Discovery)
+	/*
+		discov, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
+			zookeeper.WithFreq(time.Hour), zookeeper.WithRoundRobin(), zookeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
+				config.Config.Zookeeper.Password), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))*/
 	if err != nil {
 		return nil, err
 	}
diff --git a/manifest/build-docker.sh b/manifest/build-docker.sh
new file mode 100755
index 000000000..648e6370d
--- /dev/null
+++ b/manifest/build-docker.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+IMAGEHUB="registry.cn-shenzhen.aliyuncs.com/huanglin_hub"
+PROJECT=$1
+ALLPRO="all"
+servers=(openim-api openim-crontask openim-msggateway openim-msgtransfer openim-push openim-rpc-auth openim-rpc-conversation openim-rpc-friend openim-rpc-group openim-rpc-msg openim-rpc-third openim-rpc-user)
+
+
+if [ "$1" != "" ]
+then
+    if [[ "${servers[@]}"  =~ "${1}" ]]
+    then
+        echo "building ${PROJECT}"
+        DOCKER_PUSHIMG=${IMAGEHUB}/${PROJECT}:dev
+        docker rmi  ${DOCKER_PUSHIMG}
+        docker build -f manifest/dockerfiles/${PROJECT}/Dockerfile -t ${DOCKER_PUSHIMG} .
+        docker push ${DOCKER_PUSHIMG}
+    elif [[ ! "${servers[@]}"  =~ "${1}" ]]
+    then
+        if [ ${PROJECT} == ${ALLPRO} ]
+        then
+            echo "building allproject"
+            for element in ${servers[@]}
+            do
+                SUB_IMG=${element}
+                SUB_PUSHIMG=${IMAGEHUB}/${element}:dev
+                docker rmi  ${SUB_PUSHIMG}
+                docker build -f manifest/dockerfiles/${SUB_IMG}/Dockerfile -t ${SUB_PUSHIMG} .
+                docker push ${SUB_PUSHIMG}
+            done
+        else
+          echo "输入的项目名称不正确"
+        fi
+    fi
+else
+    echo "请传入一个参数"
+fi
\ No newline at end of file
diff --git a/manifest/dockerfiles/openim-api/Dockerfile b/manifest/dockerfiles/openim-api/Dockerfile
new file mode 100644
index 000000000..c5198d2ad
--- /dev/null
+++ b/manifest/dockerfiles/openim-api/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-api/openim-api cmd/openim-api/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-api/openim-api /app/bin/
+ENTRYPOINT ["/app/bin/openim-api"]
diff --git a/manifest/dockerfiles/openim-crontask/Dockerfile b/manifest/dockerfiles/openim-crontask/Dockerfile
new file mode 100644
index 000000000..bba54b2e2
--- /dev/null
+++ b/manifest/dockerfiles/openim-crontask/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-crontask/openim-crontask cmd/openim-crontask/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-crontask/openim-crontask /app/bin/
+ENTRYPOINT ["/app/bin/openim-crontask"]
diff --git a/manifest/dockerfiles/openim-msggateway/Dockerfile b/manifest/dockerfiles/openim-msggateway/Dockerfile
new file mode 100644
index 000000000..582178013
--- /dev/null
+++ b/manifest/dockerfiles/openim-msggateway/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-msggateway/openim-msggateway cmd/openim-msggateway/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-msggateway/openim-msggateway /app/bin/
+ENTRYPOINT ["/app/bin/openim-msggateway"]
diff --git a/manifest/dockerfiles/openim-msgtransfer/Dockerfile b/manifest/dockerfiles/openim-msgtransfer/Dockerfile
new file mode 100644
index 000000000..1e08eb38a
--- /dev/null
+++ b/manifest/dockerfiles/openim-msgtransfer/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-msgtransfer/openim-msgtransfer cmd/openim-msgtransfer/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-msgtransfer/openim-msgtransfer /app/bin/
+ENTRYPOINT ["/app/bin/openim-msgtransfer"]
diff --git a/manifest/dockerfiles/openim-push/Dockerfile b/manifest/dockerfiles/openim-push/Dockerfile
new file mode 100644
index 000000000..c1ae3ed84
--- /dev/null
+++ b/manifest/dockerfiles/openim-push/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-push/openim-push cmd/openim-push/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-push/openim-push /app/bin/
+ENTRYPOINT ["/app/bin/openim-push"]
diff --git a/manifest/dockerfiles/openim-rpc-auth/Dockerfile b/manifest/dockerfiles/openim-rpc-auth/Dockerfile
new file mode 100644
index 000000000..5124da7a1
--- /dev/null
+++ b/manifest/dockerfiles/openim-rpc-auth/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-rpc/openim-rpc-auth/openim-rpc-auth cmd/openim-rpc/openim-rpc-auth/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-rpc/openim-rpc-auth/openim-rpc-auth /app/bin/
+ENTRYPOINT ["/app/bin/openim-rpc-auth"]
diff --git a/manifest/dockerfiles/openim-rpc-conversation/Dockerfile b/manifest/dockerfiles/openim-rpc-conversation/Dockerfile
new file mode 100644
index 000000000..539d441b9
--- /dev/null
+++ b/manifest/dockerfiles/openim-rpc-conversation/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-rpc/openim-rpc-conversation/openim-rpc-conversation cmd/openim-rpc/openim-rpc-conversation/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-rpc/openim-rpc-conversation/openim-rpc-conversation /app/bin/
+ENTRYPOINT ["/app/bin/openim-rpc-conversation"]
diff --git a/manifest/dockerfiles/openim-rpc-friend/Dockerfile b/manifest/dockerfiles/openim-rpc-friend/Dockerfile
new file mode 100644
index 000000000..9927c1d30
--- /dev/null
+++ b/manifest/dockerfiles/openim-rpc-friend/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-rpc/openim-rpc-friend/openim-rpc-friend cmd/openim-rpc/openim-rpc-friend/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-rpc/openim-rpc-friend/openim-rpc-friend /app/bin/
+ENTRYPOINT ["/app/bin/openim-rpc-friend"]
diff --git a/manifest/dockerfiles/openim-rpc-group/Dockerfile b/manifest/dockerfiles/openim-rpc-group/Dockerfile
new file mode 100644
index 000000000..754151156
--- /dev/null
+++ b/manifest/dockerfiles/openim-rpc-group/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-rpc/openim-rpc-group/openim-rpc-group cmd/openim-rpc/openim-rpc-group/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-rpc/openim-rpc-group/openim-rpc-group /app/bin/
+ENTRYPOINT ["/app/bin/openim-rpc-group"]
diff --git a/manifest/dockerfiles/openim-rpc-msg/Dockerfile b/manifest/dockerfiles/openim-rpc-msg/Dockerfile
new file mode 100644
index 000000000..0f942ba8e
--- /dev/null
+++ b/manifest/dockerfiles/openim-rpc-msg/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-rpc/openim-rpc-msg/openim-rpc-msg cmd/openim-rpc/openim-rpc-msg/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-rpc/openim-rpc-msg/openim-rpc-msg /app/bin/
+ENTRYPOINT ["/app/bin/openim-rpc-msg"]
diff --git a/manifest/dockerfiles/openim-rpc-third/Dockerfile b/manifest/dockerfiles/openim-rpc-third/Dockerfile
new file mode 100644
index 000000000..a1391c0c3
--- /dev/null
+++ b/manifest/dockerfiles/openim-rpc-third/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-rpc/openim-rpc-third/openim-rpc-third cmd/openim-rpc/openim-rpc-third/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-rpc/openim-rpc-third/openim-rpc-third /app/bin/
+ENTRYPOINT ["/app/bin/openim-rpc-third"]
diff --git a/manifest/dockerfiles/openim-rpc-user/Dockerfile b/manifest/dockerfiles/openim-rpc-user/Dockerfile
new file mode 100644
index 000000000..b45b4aa2f
--- /dev/null
+++ b/manifest/dockerfiles/openim-rpc-user/Dockerfile
@@ -0,0 +1,27 @@
+
+# build container
+FROM golang:1.20-alpine3.18 AS builder
+ENV GOPROXY https://goproxy.cn,direct
+ENV GOSUMDB=sum.golang.google.cn
+ENV GO111MODULE=on
+
+WORKDIR /app
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add git pkgconfig build-base
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+ADD . .
+RUN go build -o cmd/openim-rpc/openim-rpc-user/openim-rpc-user cmd/openim-rpc/openim-rpc-user/main.go
+
+# archive container
+FROM alpine:3.18
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
+RUN apk --no-cache add ca-certificates libdrm
+RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+    && echo "Asia/Shanghai" > /etc/timezone \
+    && apk del tzdata
+
+WORKDIR /app/bin
+COPY --from=builder /app/cmd/openim-rpc/openim-rpc-user/openim-rpc-user /app/bin/
+ENTRYPOINT ["/app/bin/openim-rpc-user"]
diff --git a/pkg/common/cmd/api.go b/pkg/common/cmd/api.go
index 4cb5e34fc..19b11d4b2 100644
--- a/pkg/common/cmd/api.go
+++ b/pkg/common/cmd/api.go
@@ -14,14 +14,21 @@
 
 package cmd
 
-import "github.com/spf13/cobra"
+import (
+	"fmt"
+	"github.com/OpenIMSDK/protocol/constant"
+	config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
+	"github.com/spf13/cobra"
+)
 
 type ApiCmd struct {
 	*RootCmd
 }
 
 func NewApiCmd() *ApiCmd {
-	return &ApiCmd{NewRootCmd("api")}
+	ret := &ApiCmd{NewRootCmd("api")}
+	ret.SetRootCmdPt(ret)
+	return ret
 }
 
 func (a *ApiCmd) AddApi(f func(port int) error) {
@@ -29,3 +36,11 @@ func (a *ApiCmd) AddApi(f func(port int) error) {
 		return f(a.getPortFlag(cmd))
 	}
 }
+func (a *ApiCmd) GetPortFromConfig(portType string) int {
+	fmt.Println("GetPortFromConfig:", portType)
+	if portType == constant.FlagPort {
+		return config2.Config.Api.OpenImApiPort[0]
+	} else {
+		return 0
+	}
+}
diff --git a/pkg/common/cmd/constant.go b/pkg/common/cmd/constant.go
new file mode 100644
index 000000000..835593bbe
--- /dev/null
+++ b/pkg/common/cmd/constant.go
@@ -0,0 +1,12 @@
+package cmd
+
+const (
+	RpcPushServer         = "push"
+	RpcAuthServer         = "auth"
+	RpcConversationServer = "conversation"
+	RpcFriendServer       = "friend"
+	RpcGroupServer        = "group"
+	RpcMsgServer          = "msg"
+	RpcThirdServer        = "third"
+	RpcUserServer         = "user"
+)
diff --git a/pkg/common/cmd/cron_task.go b/pkg/common/cmd/cron_task.go
index 25dc9aae4..1b0e796ac 100644
--- a/pkg/common/cmd/cron_task.go
+++ b/pkg/common/cmd/cron_task.go
@@ -21,7 +21,9 @@ type CronTaskCmd struct {
 }
 
 func NewCronTaskCmd() *CronTaskCmd {
-	return &CronTaskCmd{NewRootCmd("cronTask", WithCronTaskLogName())}
+	ret := &CronTaskCmd{NewRootCmd("cronTask", WithCronTaskLogName())}
+	ret.SetRootCmdPt(ret)
+	return ret
 }
 
 func (c *CronTaskCmd) addRunE(f func() error) {
diff --git a/pkg/common/cmd/msg_gateway.go b/pkg/common/cmd/msg_gateway.go
index 34a9f3b4e..c96bbd7af 100644
--- a/pkg/common/cmd/msg_gateway.go
+++ b/pkg/common/cmd/msg_gateway.go
@@ -16,6 +16,8 @@ package cmd
 
 import (
 	"github.com/openimsdk/open-im-server/v3/internal/msggateway"
+	config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
+
 	//"github.com/openimsdk/open-im-server/internal/msggateway".
 	"github.com/spf13/cobra"
 
@@ -26,8 +28,10 @@ type MsgGatewayCmd struct {
 	*RootCmd
 }
 
-func NewMsgGatewayCmd() MsgGatewayCmd {
-	return MsgGatewayCmd{NewRootCmd("msgGateway")}
+func NewMsgGatewayCmd() *MsgGatewayCmd {
+	ret := &MsgGatewayCmd{NewRootCmd("msgGateway")}
+	ret.SetRootCmdPt(ret)
+	return ret
 }
 
 func (m *MsgGatewayCmd) AddWsPortFlag() {
@@ -36,6 +40,9 @@ func (m *MsgGatewayCmd) AddWsPortFlag() {
 
 func (m *MsgGatewayCmd) getWsPortFlag(cmd *cobra.Command) int {
 	port, _ := cmd.Flags().GetInt(constant.FlagWsPort)
+	if port == 0 {
+		port = m.PortFromConfig(constant.FlagWsPort)
+	}
 	return port
 }
 
@@ -49,3 +56,14 @@ func (m *MsgGatewayCmd) Exec() error {
 	m.addRunE()
 	return m.Execute()
 }
+func (m *MsgGatewayCmd) GetPortFromConfig(portType string) int {
+	if portType == constant.FlagWsPort {
+		return config2.Config.LongConnSvr.OpenImWsPort[0]
+	} else if portType == constant.FlagPort {
+		return config2.Config.LongConnSvr.OpenImMessageGatewayPort[0]
+	} else if portType == constant.FlagPrometheusPort {
+		return 0
+	} else {
+		return 0
+	}
+}
diff --git a/pkg/common/cmd/msg_transfer.go b/pkg/common/cmd/msg_transfer.go
index ae67ee9f7..20349ebbb 100644
--- a/pkg/common/cmd/msg_transfer.go
+++ b/pkg/common/cmd/msg_transfer.go
@@ -24,8 +24,10 @@ type MsgTransferCmd struct {
 	*RootCmd
 }
 
-func NewMsgTransferCmd() MsgTransferCmd {
-	return MsgTransferCmd{NewRootCmd("msgTransfer")}
+func NewMsgTransferCmd() *MsgTransferCmd {
+	ret := &MsgTransferCmd{NewRootCmd("msgTransfer")}
+	ret.SetRootCmdPt(ret)
+	return ret
 }
 
 func (m *MsgTransferCmd) addRunE() {
diff --git a/pkg/common/cmd/root.go b/pkg/common/cmd/root.go
index 508ef8377..6973da9d6 100644
--- a/pkg/common/cmd/root.go
+++ b/pkg/common/cmd/root.go
@@ -26,11 +26,15 @@ import (
 	"github.com/openimsdk/open-im-server/v3/pkg/common/config"
 )
 
+type RootCmdPt interface {
+	GetPortFromConfig(portType string) int
+}
 type RootCmd struct {
 	Command        cobra.Command
 	Name           string
 	port           int
 	prometheusPort int
+	cmdItf         RootCmdPt
 }
 
 type CmdOpts struct {
@@ -76,7 +80,9 @@ func NewRootCmd(name string, opts ...func(*CmdOpts)) (rootCmd *RootCmd) {
 	rootCmd.addConfFlag()
 	return rootCmd
 }
-
+func (r *RootCmd) SetRootCmdPt(cmdItf RootCmdPt) {
+	r.cmdItf = cmdItf
+}
 func (r *RootCmd) addConfFlag() {
 	r.Command.Flags().StringP(constant.FlagConf, "c", "", "Path to config file folder")
 }
@@ -87,6 +93,9 @@ func (r *RootCmd) AddPortFlag() {
 
 func (r *RootCmd) getPortFlag(cmd *cobra.Command) int {
 	port, _ := cmd.Flags().GetInt(constant.FlagPort)
+	if port == 0 {
+		port = r.PortFromConfig(constant.FlagPort)
+	}
 	return port
 }
 
@@ -100,6 +109,9 @@ func (r *RootCmd) AddPrometheusPortFlag() {
 
 func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) int {
 	port, _ := cmd.Flags().GetInt(constant.FlagPrometheusPort)
+	if port == 0 {
+		port = r.PortFromConfig(constant.FlagPrometheusPort)
+	}
 	return port
 }
 
@@ -120,3 +132,12 @@ func (r *RootCmd) Execute() error {
 func (r *RootCmd) AddCommand(cmds ...*cobra.Command) {
 	r.Command.AddCommand(cmds...)
 }
+
+func (r *RootCmd) GetPortFromConfig(portType string) int {
+	fmt.Println("RootCmd.GetPortFromConfig:", portType)
+	return 0
+}
+func (r *RootCmd) PortFromConfig(portType string) int {
+	fmt.Println("PortFromConfig:", portType)
+	return r.cmdItf.GetPortFromConfig(portType)
+}
diff --git a/pkg/common/cmd/rpc.go b/pkg/common/cmd/rpc.go
index a5fc1164c..224edc0a0 100644
--- a/pkg/common/cmd/rpc.go
+++ b/pkg/common/cmd/rpc.go
@@ -16,7 +16,8 @@ package cmd
 
 import (
 	"errors"
-
+	"github.com/OpenIMSDK/protocol/constant"
+	config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
 	"github.com/spf13/cobra"
 	"google.golang.org/grpc"
 
@@ -30,8 +31,9 @@ type RpcCmd struct {
 }
 
 func NewRpcCmd(name string) *RpcCmd {
-	authCmd := &RpcCmd{NewRootCmd(name)}
-	return authCmd
+	ret := &RpcCmd{NewRootCmd(name)}
+	ret.SetRootCmdPt(ret)
+	return ret
 }
 
 func (a *RpcCmd) Exec() error {
@@ -51,3 +53,40 @@ func (a *RpcCmd) StartSvr(
 	}
 	return startrpc.Start(a.GetPortFlag(), name, a.GetPrometheusPortFlag(), rpcFn)
 }
+func (a *RpcCmd) GetPortFromConfig(portType string) int {
+	switch a.Name {
+	case RpcPushServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImPushPort[0]
+		}
+	case RpcAuthServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImAuthPort[0]
+		}
+	case RpcConversationServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImConversationPort[0]
+		}
+	case RpcFriendServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImFriendPort[0]
+		}
+	case RpcGroupServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImGroupPort[0]
+		}
+	case RpcMsgServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImMessagePort[0]
+		}
+	case RpcThirdServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImThirdPort[0]
+		}
+	case RpcUserServer:
+		if portType == constant.FlagPort {
+			return config2.Config.RpcPort.OpenImUserPort[0]
+		}
+	}
+	return 0
+}
diff --git a/pkg/common/config/config.go b/pkg/common/config/config.go
index 966033247..95f4a864e 100644
--- a/pkg/common/config/config.go
+++ b/pkg/common/config/config.go
@@ -46,6 +46,9 @@ type POfflinePush struct {
 }
 
 type configStruct struct {
+	Envs struct {
+		Discovery string `yaml:"discovery"`
+	}
 	Zookeeper struct {
 		Schema   string   `yaml:"schema"`
 		ZkAddr   []string `yaml:"address"`
@@ -185,10 +188,11 @@ type configStruct struct {
 	} `yaml:"log"`
 
 	LongConnSvr struct {
-		OpenImWsPort        []int `yaml:"openImWsPort"`
-		WebsocketMaxConnNum int   `yaml:"websocketMaxConnNum"`
-		WebsocketMaxMsgLen  int   `yaml:"websocketMaxMsgLen"`
-		WebsocketTimeout    int   `yaml:"websocketTimeout"`
+		OpenImMessageGatewayPort []int `yaml:"openImMessageGatewayPort"`
+		OpenImWsPort             []int `yaml:"openImWsPort"`
+		WebsocketMaxConnNum      int   `yaml:"websocketMaxConnNum"`
+		WebsocketMaxMsgLen       int   `yaml:"websocketMaxMsgLen"`
+		WebsocketTimeout         int   `yaml:"websocketTimeout"`
 	} `yaml:"longConnSvr"`
 
 	Push struct {
diff --git a/pkg/common/discovery_register/k8s_discovery_register.go b/pkg/common/discovery_register/k8s_discovery_register.go
new file mode 100644
index 000000000..70f9f39f3
--- /dev/null
+++ b/pkg/common/discovery_register/k8s_discovery_register.go
@@ -0,0 +1,88 @@
+package discovery_register
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"github.com/OpenIMSDK/tools/discoveryregistry"
+	openkeeper "github.com/OpenIMSDK/tools/discoveryregistry/zookeeper"
+	"github.com/OpenIMSDK/tools/log"
+	"github.com/openimsdk/open-im-server/v3/pkg/common/config"
+	"google.golang.org/grpc"
+	"time"
+)
+
+func NewDiscoveryRegister(envType string) (discoveryregistry.SvcDiscoveryRegistry, error) {
+	var client discoveryregistry.SvcDiscoveryRegistry
+	var err error
+	switch envType {
+	case "zookeeper":
+		client, err = openkeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
+			openkeeper.WithFreq(time.Hour), openkeeper.WithUserNameAndPassword(
+				config.Config.Zookeeper.Username,
+				config.Config.Zookeeper.Password,
+			), openkeeper.WithRoundRobin(), openkeeper.WithTimeout(10), openkeeper.WithLogger(log.NewZkLogger()))
+	case "k8s":
+		client, err = NewK8sDiscoveryRegister()
+	default:
+		client = nil
+		err = errors.New("envType not correct")
+	}
+	return client, err
+}
+
+type K8sDR struct {
+	options         []grpc.DialOption
+	rpcRegisterAddr string
+}
+
+func NewK8sDiscoveryRegister() (discoveryregistry.SvcDiscoveryRegistry, error) {
+	return &K8sDR{}, nil
+}
+
+func (cli *K8sDR) Register(serviceName, host string, port int, opts ...grpc.DialOption) error {
+	cli.rpcRegisterAddr = serviceName
+	return nil
+}
+func (cli *K8sDR) UnRegister() error {
+
+	return nil
+}
+func (cli *K8sDR) CreateRpcRootNodes(serviceNames []string) error {
+
+	return nil
+}
+func (cli *K8sDR) RegisterConf2Registry(key string, conf []byte) error {
+
+	return nil
+}
+
+func (cli *K8sDR) GetConfFromRegistry(key string) ([]byte, error) {
+
+	return nil, nil
+}
+func (cli *K8sDR) GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error) {
+
+	conn, err := grpc.DialContext(ctx, serviceName, append(cli.options, opts...)...)
+	return []*grpc.ClientConn{conn}, err
+}
+func (cli *K8sDR) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
+
+	return grpc.DialContext(ctx, serviceName, append(cli.options, opts...)...)
+}
+func (cli *K8sDR) GetSelfConnTarget() string {
+
+	return cli.rpcRegisterAddr
+}
+func (cli *K8sDR) AddOption(opts ...grpc.DialOption) {
+	cli.options = append(cli.options, opts...)
+}
+func (cli *K8sDR) CloseConn(conn *grpc.ClientConn) {
+	conn.Close()
+}
+
+// do not use this method for call rpc
+func (cli *K8sDR) GetClientLocalConns() map[string][]*grpc.ClientConn {
+	fmt.Println("should not call this function!!!!!!!!!!!!!!!!!!!!!!!!!")
+	return nil
+}
diff --git a/pkg/common/startrpc/start.go b/pkg/common/startrpc/start.go
index 3ef6e569d..19da8a586 100644
--- a/pkg/common/startrpc/start.go
+++ b/pkg/common/startrpc/start.go
@@ -16,19 +16,16 @@ package startrpc
 
 import (
 	"fmt"
+	"github.com/openimsdk/open-im-server/v3/pkg/common/config"
+	"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
 	"net"
 	"strconv"
-	"time"
-
-	"github.com/openimsdk/open-im-server/v3/pkg/common/config"
 
 	grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
 
 	"github.com/OpenIMSDK/tools/discoveryregistry"
-	"github.com/OpenIMSDK/tools/discoveryregistry/zookeeper"
-	"github.com/OpenIMSDK/tools/log"
 	"github.com/OpenIMSDK/tools/mw"
 	"github.com/OpenIMSDK/tools/network"
 	"github.com/OpenIMSDK/tools/prome"
@@ -60,15 +57,17 @@ func Start(
 		return err
 	}
 	defer listener.Close()
-	zkClient, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
-		zookeeper.WithFreq(time.Hour), zookeeper.WithUserNameAndPassword(
-			config.Config.Zookeeper.Username,
-			config.Config.Zookeeper.Password,
-		), zookeeper.WithRoundRobin(), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))
+	zkClient, err := discovery_register.NewDiscoveryRegister(config.Config.Envs.Discovery)
+	/*
+		zkClient, err := zookeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
+			zookeeper.WithFreq(time.Hour), zookeeper.WithUserNameAndPassword(
+				config.Config.Zookeeper.Username,
+				config.Config.Zookeeper.Password,
+			), zookeeper.WithRoundRobin(), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))*/
 	if err != nil {
 		return utils.Wrap1(err)
 	}
-	defer zkClient.CloseZK()
+	//defer zkClient.CloseZK()
 	zkClient.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
 	registerIP, err := network.GetRpcRegisterIP(config.Config.Rpc.RegisterIP)
 	if err != nil {
diff --git a/scripts/install/environment.sh b/scripts/install/environment.sh
index ce8eb56ec..c5407f5e3 100755
--- a/scripts/install/environment.sh
+++ b/scripts/install/environment.sh
@@ -150,6 +150,8 @@ def "OPENIM_CHAT_NAME" "chat"                      # openim-chat chat用户名
 # TODO 注意: 一般的配置都可以使用 def 函数来定义,如果是包含特殊字符,比如说:
 # TODO readonly MSG_DESTRUCT_TIME=${MSG_DESTRUCT_TIME:-'0 2 * * *'}
 # TODO 使用 readonly 来定义合适,负责无法正常解析, 并且 yaml 模板需要加 "" 来包裹
+###################### Env 配置信息 ######################
+def "ENVS_DISCOVERY" "zookeeper"
 
 ###################### Zookeeper 配置信息 ######################
 def "ZOOKEEPER_SCHEMA" "openim"                    # Zookeeper的模式