
后端微服务【免费下载链接】hyperf A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.项目地址https://gitcode.com/gh_mirrors/hy/hyperf点击查看免费下载导读本指南基于 Hyperf 开源仓库的官方教程 docs/zh-cn/tutorial/docker-swarm.md完整讲述如何从零搭建一套可落地的容器化微服务基础设施包括 Docker 环境安装、Gitlab gitlab-runner 的持续集成链路、Docker Swarm 集群初始化、Overlay 网络规划、镜像仓库对接、Portainer 可视化运维、KONG 网关部署以及 Hyperf 服务在集群内的滚动发布、定时任务执行与内核优化。读完本文你将掌握一条代码提交 → Gitlab CI 构建镜像 → 推送到镜像仓库 → Swarm 集群滚动部署 → KONG 网关对外暴露的完整 DevOps 流水线并能用同样的方法将 hyperf-skeleton 之类的 Hyperf 应用部署到多节点集群中。环境准备安装 Docker 并开放 TCP 连接集群中的每一台机器都需要先安装 Docker。官方推荐使用 Docker 官方安装脚本一次性完成 Docker 及其依赖的安装curl -sSL https://get.docker.com/ | sh安装完成后为了后续的远程运维与集群通信需要修改 Docker 的 systemd 启动文件/lib/systemd/system/docker.service允许通过TCP协议连接 Docker 守护进程ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock -H tcp://0.0.0.0:2375只需在原有的ExecStart行末尾追加-H tcp://0.0.0.0:2375即可2375 端口即 Docker 的 TCP API 端口。如果你当前不是root账户可以把当前用户加入docker用户组这样每次执行docker命令时就不需要再加sudousermod -aG docker $USER加入用户组后需要重新登录终端使配置生效。配置仓库镜像加速器考虑到跨国线路访问 Docker Hub 速度较慢建议为 Docker 配置仓库镜像加速地址如阿里云 Docker 镜像加速器需自行申请获得专属加速地址。将加速器地址写入/etc/docker/daemon.json{registry-mirrors: [https://xxxxx.mirror.aliyuncs.com]}上面的地址请替换为你自己申请到的加速器地址修改后需要重启 Docker 才能生效。搭建 Gitlab 代码托管与 CI 基础设施Hyperf 的容器化发布链路中Gitlab 承担代码托管与 CI 触发两个角色代码推送到指定分支或打 tag 时gitlab-runner 拉取代码、构建镜像并推送到镜像仓库。安装 Gitlab修改 sshd 默认端口号Gitlab 容器需要通过宿主机的22端口提供 SSH 克隆能力因此先把服务器的 sshd 默认端口从22改为2222或其他未被占用的端口$ vim /etc/ssh/sshd_config # 默认 Port 改为 2222 Port 2222 # 重启服务 $ systemctl restart sshd.service之后重新登录机器时需要显式指定端口ssh -p 2222 roothost通过 Docker 启动 Gitlab使用 Docker 直接启动一个 Gitlab 社区版容器sudo docker run -d --hostname gitlab.xxx.cn \ --publish 443:443 --publish 80:80 --publish 22:22 \ --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab \ --volume /srv/gitlab/logs:/var/log/gitlab \ --volume /srv/gitlab/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest--hostname一定要指定如果没有域名可以直接填服务器的外网地址。三个 volume 分别持久化 Gitlab 的配置、日志与数据--restart always保证容器随机器自动拉起。Gitlab 默认用户名为root初始密码保存在容器内部通过以下命令获取docker exec gitlab cat /etc/gitlab/initial_root_password配置 Gitlab 邮件发送如果希望 Gitlab 主动发送邮件例如用户注册确认邮件可以编辑挂载目录下的/srv/gitlab/config/gitlab.rb追加如下 SMTP 配置以腾讯企业邮为例gitlab_rails[smtp_enable] true gitlab_rails[smtp_address] smtp.exmail.qq.com gitlab_rails[smtp_port] 465 gitlab_rails[smtp_user_name] gitxxxx.com gitlab_rails[smtp_password] xxxx gitlab_rails[smtp_authentication] login gitlab_rails[smtp_enable_starttls_auto] true gitlab_rails[smtp_tls] true gitlab_rails[gitlab_email_from] gitxxxx.com gitlab_rails[smtp_domain] exmail.qq.com安装 gitlab-runner建议将 gitlab-runner 与 Gitlab 服务器分开部署单独提供一台 runner 机器避免构建任务抢占 Gitlab 自身资源。以CentOS的安装方式为例先添加 Gitlab 官方 rpm 源再安装gitlab-runnercurl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash yum install gitlab-runner也可以先更新 git 源再一并安装较新版本的 git 与 gitlab-runner较新的 git 可以规避后续提到的shallow list类错误$ curl https://setup.ius.io | sh $ yum -y install git2u $ git version $ yum install gitlab-runner注册 gitlab-runner使用gitlab-runner register --clone-url http://your-ip/命令把 runner 注册到 Gitlab注意把your-ip替换为 Gitlab 的内网 IP。注册过程是交互式的需要依次填写 Gitlab 的 coordinator URL、注册 token、描述、tag 与执行器类型$ sudo gitlab-runner register --clone-url http://your-ip/ Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): http://gitlab.xxx.cc/ Please enter the gitlab-ci token for this runner: xxxxx Please enter the gitlab-ci description for this runner: xxx Please enter the gitlab-ci tags for this runner (comma separated): builder Please enter the executor: docker-ssh, shell, dockermachine, docker-sshmachine, docker, parallels, ssh, virtualbox, kubernetes: shell注册时指定的 tag 会用于 CI 任务的路由选择构建类任务使用buildertag发布类任务建议使用独立的 tag如线上环境用tags、测试环境用test配置发布用的 runner 时除 tag 外其他步骤与 builder 完全一致。修改 gitlab-runner 并发执行个数编辑/etc/gitlab-runner/config.toml调整concurrent值即可控制 runner 同时执行的构建任务数$ vim /etc/gitlab-runner/config.toml concurrent 5为 gitlab-runner 增加权限runner 在构建过程中需要操作 Docker因此要授予它两组权限免 sudo 执行 docker 的权限sudo usermod -aG docker gitlab-runner推送镜像到私有仓库的权限切换到 gitlab-runner 用户后登录镜像仓库su gitlab-runner docker login -u username your-docker-repository初始化 Swarm 集群在另一台或多台机器上初始化 Swarm并以 A、B、C 三台机器为例默认将 A 作为集群 Leadermanager。初始化与创建自定义 Overlay 网络进入 A 机器执行初始化命令$ docker swarm init随后需要创建一个自定义的 Overlay 网络default-network容器之间将通过它实现跨主机互联、并通过服务名name互相调用。文档提供了三种建网方式只需执行其一直接创建自定义 Overlay 网络/8网段可容纳约 1677 万个 IP容量充足docker network create \ --driver overlay \ --subnet 10.0.0.1/8 \ --opt encrypted \ --attachable \ default-network若担心大网段与其他网络冲突可改用/16网段约 65535 个可用 IPdocker network create \ --driver overlay \ --subnet 10.1.0.1/16 \ --opt encrypted \ --attachable \ default-network大多数情况下冲突的根源在于ingress网络的默认网段与自定义网段重叠。此时可以先删除ingress网络再以指定网段重建然后再创建10.0.0.1/8的default-networkdocker network rm ingress docker network create --ingress --subnet 192.168.0.1/16 --driver overlay ingressdocker network create \ --driver overlay \ --subnet 10.0.0.1/8 \ --opt encrypted \ --attachable \ default-network关键参数说明--driver overlay指定跨主机网络驱动--opt encrypted开启数据加密--attachable允许普通docker run容器如后续部署的 MySQL、KONG 等独立容器附加到该网络这一选项对服务与普通容器混布的架构至关重要。将节点加入集群通过join-token命令获取加入集群的令牌再到目标机器上执行join# 显示manager节点的TOKEN $ docker swarm join-token manager # 加入manager节点到集群 $ docker swarm join --token token ip:2377 # 显示worker节点的TOKEN $ docker swarm join-token worker # 加入worker节点到集群 $ docker swarm join --token token ip:2377集群通信端口为2377。三台机器的场景下建议都声明为 manager既保证高可用也便于在任意一台机器上执行docker stack deploy等管理操作。节点加入完成后在 A 机器执行docker node ls能看到 B、C 两台机器即代表加入成功。在集群中安装应用以 MySQL 为例default-network网络创建后普通容器同样可以通过--network参数附加进来从而在容器内直接使用服务名name互相调用。以 MySQL 为例docker run --name mysql -v /srv/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORDxxxx -p 3306:3306 --rm --network default-network -d mysql:5.7注意这里演示的是独立容器的挂载方式-v /srv/mysql持久化数据目录-e MYSQL_ROOT_PASSWORD设置 root 密码--network default-network加入集群 Overlay 网络。这样部署在集群内的 Hyperf 服务即可通过mysql这个主机名访问数据库无需感知容器实际运行在哪台机器上。安装 Portainer 可视化运维面板Portainer 提供基于 Web 的 Swarm 集群管理界面通过docker service create以服务方式部署docker service create \ --name portainer \ --publish 9000:9000 \ --replicas1 \ --constraint node.role manager \ --mount typevolume,srcportainer_data,dst/data \ --mount typebind,src//var/run/docker.sock,dst/var/run/docker.sock \ portainer/portainer--constraint node.role manager将 Portainer 固定调度到 manager 节点挂载 Docker 的 socket 文件使其能直接管理集群src//var/run/docker.sock中的双斜杠用于避免 YAML/命令解析时被当作注释。备份与恢复 Portainer 数据Portainer 的配置数据存放在容器内的/data目录可通过--volumes-from方式打包备份portainer_container请替换为实际容器名docker run -it --volumes-from portainer_container -v $(pwd):/backup --name backup --rm nginx tar -cf /backup/data.tar /data/恢复时先用创建命令重新创建 portainer 服务再把备份解压回容器docker run -it --volumes-from portainer_container -v $(pwd):/backup --name importer --rm nginx bash cd /backup tar xf data.tar -C /解压完成后重启容器即可生效。配置镜像仓库与 Hyperf 项目的 CI 发布创建命名空间与镜像仓库以阿里云容器镜像服务为例先创建命名空间test_namespace再创建镜像仓库demo选择本地仓库模式。然后在打包用的服务器上登录阿里云 Docker Registryusermod -aG docker gitlab-runner su gitlab-runner docker login --usernameyour_name registry.cn-shanghai.aliyuncs.com本文档默认开发者已开通对应的镜像服务并默认使用阿里云上海节点registry.cn-shanghai.aliyuncs.com讲述。若使用其他云服务商的镜像服务登录方式类似。修改项目 CI 配置在 Hyperf 项目的.gitlab-ci.yml中配置项目名与镜像仓库地址variables: PROJECT_NAME: demo REGISTRY_URL: registry.cn-shanghai.aliyuncs.com/test_namespace在deploy.test.yml中定义测试环境的栈描述文件。这份文件需要与集群网络、配置项仔细比对完整内容如下version: 3.7 services: demo: image: $REGISTRY_URL/$PROJECT_NAME:test environment: - APP_PROJECTdemo - APP_ENVtest ports: - 9501:9501 deploy: replicas: 1 restart_policy: condition: on-failure delay: 5s max_attempts: 5 update_config: parallelism: 2 delay: 5s order: start-first networks: - default-network configs: - source: demo_v1.0 target: /opt/www/.env configs: demo_v1.0: external: true networks: default-network: external: true文件要点解读image: $REGISTRY_URL/$PROJECT_NAME:test引用 CI 变量镜像 tag 为test与 CI 流水线推送的 tag 保持一致deploy.update_config.order: start-first表示先启动新副本、成功后再停止旧副本实现滚动发布、服务不中断configs将集群内的配置对象demo_v1.0挂载为容器内的/opt/www/.env——这是 Hyperf 读取环境配置的标准位置运行时参数与代码镜像分离networks.default-network与configs均声明为external: true引用集群中已存在的 Overlay 网络与配置对象。在 Portainer 中创建 Config 并触发发布在 Portainer 中创建对应的 Configdemo_v1.0填入 Hyperf 应用的 .env 内容。Demo 项目本身没有 I/O 操作以下参数按默认即可实际项目请根据部署环境调整APP_NAMEdemo DB_DRIVERmysql DB_HOSTlocalhost DB_PORT3306 DB_DATABASEhyperf DB_USERNAMEroot DB_PASSWORD DB_CHARSETutf8mb4 DB_COLLATIONutf8mb4_unicode_ci DB_PREFIX REDIS_HOSTlocalhost REDIS_AUTH REDIS_PORT6379 REDIS_DB0注意在集群内多个容器通过 Overlay 网络互访的场景下DB_HOST、REDIS_HOST应填写 MySQL、Redis 等服务的容器名如mysql不要使用127.0.0.1否则无法触达其他节点上的服务。由于 CI 配置会检测test分支和 tags把修改内容合并到test分支并推送到 Gitlab流水线即会自动构建镜像、推送到镜像仓库并触发集群更新。发布完成后访问集群任意一台机器的9501端口即可验证curl http://127.0.0.1:9501/安装 KONG 网关Docker Swarm 集群通常不会直接把服务端口对外暴露而是在上层构建统一网关。文档推荐使用KONG原因有二Swarm 的Ingress 网络存在设计缺陷在连接不复用的情况下会有并发瓶颈详见 moby 仓库 Issue#35082KONG作为网关默认会复用后端连接能够极大缓解上述并发问题。安装数据库KONG 需要 PostgreSQL 存储配置。启动数据库容器并加入default-networkdocker run -d --name kong-database \ --networkdefault-network \ -p 5432:5432 \ -e POSTGRES_USERkong \ -e POSTGRES_DBkong \ -e POSTGRES_PASSWORDkong \ postgres:9.6安装网关先初始化数据库docker run --rm \ --networkdefault-network \ -e KONG_DATABASEpostgres \ -e KONG_PG_HOSTkong-database \ -e KONG_PG_PASSWORDkong \ -e KONG_CASSANDRA_CONTACT_POINTSkong-database \ kong:latest kong migrations bootstrap再启动 KONG 网关本体docker run -d --name kong \ --networkdefault-network \ -e KONG_DATABASEpostgres \ -e KONG_PG_HOSTkong-database \ -e KONG_PG_PASSWORDkong \ -e KONG_CASSANDRA_CONTACT_POINTSkong-database \ -e KONG_PROXY_ACCESS_LOG/dev/stdout \ -e KONG_ADMIN_ACCESS_LOG/dev/stdout \ -e KONG_PROXY_ERROR_LOG/dev/stderr \ -e KONG_ADMIN_ERROR_LOG/dev/stderr \ -e KONG_ADMIN_LISTEN0.0.0.0:8001, 0.0.0.0:8444 ssl \ -p 8000:8000 \ -p 8443:8443 \ -p 8001:8001 \ -p 8444:8444 \ kong:latest8000/8443为代理端口8001/8444为管理 API 端口。因为容器名即主机名KONG_PG_HOSTkong-database与--kong-url http://kong:8001这类配置都是通过 Overlay 网络内的服务名解析实现的。安装 KONG DashboardKONG Dashboard 提供可视化配置界面docker run --rm --networkdefault-network -p 8080:8080 -d --name kong-dashboard pgbi/kong-dashboard start \ --kong-url http://kong:8001 \ --basic-auth user1password1 user2password2文档特别提示当时 Docker 中尚未更新v3.6.0最新版 KONG 可能无法与 Dashboard 兼容可使用0.14.1版本的 KONG。--basic-auth可配置多个账号密码用于登录 Dashboard。配置 Service 对外暴露部署完成后把 KONG 所在机器的 IP 对外暴露并配置对应的 Service 路由即可。如果机器直接对外提供访问最好只开放80和443端口并把 KONG 容器的8000、8443端口映射到80、443上如果使用了 SLB 等负载均衡服务也通过负载均衡把80/443映射到 KONG 所在机器的8000/8443端口。使用 Linux Crontab 执行容器内命令Hyperf 提供了 crontab 定时任务组件秒级定时任务通过composer require hyperf/crontab安装但并不是所有场景都适合在应用内调度。如果需要用 Linux 系统级 crontab 来执行 Docker 容器内的 Hyperf 命令可以参考下面的脚本——它每次拉取最新镜像以临时容器方式运行bin/hyperf.php下的任意命令#!/usr/bin/env bash basepath$(cd dirname $0; pwd) docker pull registry-vpc.cn-shanghai.aliyuncs.com/namespace/project:latest docker run --rm -i -v $basepath/.env:/opt/www/.env \ --entrypoint php registry-vpc.cn-shanghai.aliyuncs.com/namespace/project:latest \ /opt/www/bin/hyperf.php your_command脚本要点docker pull确保每次执行都使用镜像仓库中的最新版本避免定时任务跑在旧代码上-v $basepath/.env:/opt/www/.env把宿主机上与应用代码分离的环境配置注入容器与 Swarm 的configs挂载思路一致--entrypoint php覆盖镜像默认入口直接执行/opt/www/bin/hyperf.php your_commandyour_command替换为实际命令名请将镜像地址替换为你自己的命名空间与项目名。需要把脚本加入 crontab 时直接在/etc/crontab或crontab -e中按分 时 日 月 周 脚本路径的格式编写计划即可。内核优化本小节内容有待验证请谨慎使用。前面提到 KONG 网关部分介绍了Ingress 网络的设计缺陷这一问题也可以通过优化内核的方式缓解。步骤如下指定 TLinux 源腾讯 TLinux 仓库提供经过优化、带 LVS 连接复用等特性的内核tee /etc/yum.repos.d/CentOS-TLinux.repo -EOF [Tlinux] nameTlinux for redhat/centos $releasever - $basearch failovermethodpriority gpgcheck0 gpgkeyhttp://mirrors.tencentyun.com/epel/RPM-GPG-KEY-EPEL-7 enabled1 baseurlhttps://mirrors.tencent.com/tlinux/2.4/tlinux/x86_64/ EOF安装指定版本内核yum -y install kernel-devel-4.14.105-19.0012.tl2.x86_64 kernel-4.14.105-19.0013.tl2.x86_64 kernel-headers-4.14.105-19.0013.tl2.x86_64使新内核生效查看启动项序号并设置为默认启动项sudo awk -F\ $1menuentry {print i : $2} /etc/grub2.cfg grub2-set-default 0 grub2-mkconfig -o /boot/grub2/grub.cfg重启机器reboot容器参数优化需要 Docker 19.09.0 以上版本支持与image配置同级。在 stack 文件的服务定义中为容器注入内核参数优化 LVS 转发下的连接行为sysctls: # 网络连接复用模式的选择 - net.ipv4.vs.conn_reuse_mode0 # 当LVS转发数据包发现目的RS无效删除时会丢弃该数据包但不删除相应连接。值为1时则马上释放相应连接 - net.ipv4.vs.expire_nodest_conn1常见问题排查fatal: git fetch-pack: expected shallow list这是gitlab-runner使用的 git 版本过低导致的问题更新 git 版本并重新安装、注册 runner 即可$ curl https://setup.ius.io | sh $ yum remove -y git $ yum -y install git2u $ git version # 重新安装 gitlab-runner 并重新注册 gitlab-runner $ yum install gitlab-runnerService 重启后内网出现偶发的容器无法触达Connection refused多容器互相访问时偶发Connection refused通常是 Overlay 网段的可用 IP 不足导致。解决思路是扩大网段、迁移网络创建网段更大的新 Networkdocker network create \ --driver overlay \ --subnet 10.0.0.0/8 \ --opt encrypted \ --attachable \ default-network为服务添加新 Network、再删除旧 Networkdocker service update --network-add default-network service_namedocker service update --network-rm old-network service_name为 Service 增加节点发现一直卡在 create 阶段原因与解决办法同上——同样是因为网段 IP 资源不足按上面的方式扩大网段并迁移网络即可。在 Portainer 中修改了仓库密码后更新 Service 失败Portainer 中修改的仓库凭证不会自动作用于已创建的服务手动触发一次带仓库认证的更新即可docker service update --with-registry-auth service_name附录只安装 Docker Swarm 的最小化流程如果你只需要 Docker Swarm 本身不引入 Gitlab CI可以参考本节流程。假设有三台机器 A、B、CA 作为 Leader。安装 Docker三台机器一致curl -sSL https://get.docker.com/ | sh修改/lib/systemd/system/docker.service允许 TCP 连接仅需追加末尾的-H tcp://0.0.0.0:2375ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock -H tcp://0.0.0.0:2375非 root 账户可执行usermod -aG docker $USER免去 sudo。初始化 Docker Swarm进入 A 机器初始化$ docker swarm init重建ingress网络以避开网段冲突并创建10.0.0.1/8的default-networkdocker network rm ingress docker network create --ingress --subnet 192.168.0.1/16 --driver overlay ingressdocker network create \ --driver overlay \ --subnet 10.0.0.1/8 \ --opt encrypted \ --attachable \ default-network获取加入集群的命令$ docker swarm join-token manager后期需要加入新的 worker 节点时执行$ docker swarm join-token worker将另外两台节点加入集群到 B、C 两台机器执行刚才生成的命令docker swarm join --token xxxx ip:2377回到 A 机器执行docker node ls能看到 B 和 C 的节点即代表加入成功。登录镜像仓库三台机器均执行docker login --usernamexxxx registry.cn-shanghai.aliyuncs.com打包并推送镜像可在集群任意一台机器或开发环境打包非集群机器需先docker logindocker build . -t registry.cn-shanghai.aliyuncs.com/your_namespace/your_project:latest docker push registry.cn-shanghai.aliyuncs.com/your_namespace/your_project:latest编写 stack 文件并启动服务回到 A 机器在/opt/www/your_project目录下编辑deploy.ymlversion: 3.7 services: your_project: image: registry.cn-shanghai.aliyuncs.com/your_namespace/your_project:latest ports: - 9501:9501 deploy: replicas: 3 restart_policy: condition: on-failure delay: 5s max_attempts: 5 update_config: parallelism: 2 delay: 5s order: start-first networks: - default-network configs: - source: your_project_v1.1 target: /opt/www/.env configs: your_project_v1.1: file: /opt/www/your_project/.env networks: default-network: external: trueconfigs使用file:方式直接引用宿主机上的/opt/www/your_project/.env文件其内容即为 Hyperf 的环境配置。同样注意不要使用127.0.0.1连接 MySQL 等服务应填写 Overlay 网络中对应容器的服务名。启动服务并携带仓库认证信息docker pull registry.cn-shanghai.aliyuncs.com/your_namespace/your_project:latest docker stack deploy -c /opt/www/your_project/deploy.yml --with-registry-auth your_project通过以下三个命令确认服务正常运行都应有对应数据docker stack ls docker service ls docker ps测试服务是否可用到三台机器上分别执行 curl 测试如果都能返回对应数据代表服务启动成功curl http://127.0.0.1:9501/更新服务开发机重新打包并推送镜像docker build . -t registry.cn-shanghai.aliyuncs.com/your_namespace/your_project:latest docker push registry.cn-shanghai.aliyuncs.com/your_namespace/your_project:latest回到 A 机器拉取新镜像并重新执行 stack 部署docker stack deploy会按照update_config中定义的滚动策略平滑更新副本docker pull registry.cn-shanghai.aliyuncs.com/your_namespace/your_project:latest docker stack deploy -c /opt/www/your_project/deploy.yml --with-registry-auth your_project总结整套方案在 Hyperf 生态中的落地路径非常清晰Hyperf 应用以 Docker 镜像作为交付单元gitlab-runner 负责在代码提交/打 tag 时自动构建镜像Swarm 集群通过default-networkOverlay 网络与configs配置对象实现了代码、配置、运行环境三者分离deploy.update_config.order: start-first等参数让 Hyperf 服务可以零中断滚动升级而 KONG 网关与内核优化则解决了集群入口并发与 Ingress 网络的先天瓶颈。无论你的团队规模如何这套组合都能以较低成本获得一套接近生产标准的容器化微服务基础设施。赞分享后端微服务【免费下载链接】hyperf A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.项目地址https://gitcode.com/gh_mirrors/hy/hyperf点击查看免费下载相关推荐Hyperf 基于 Docker Swarm 的微服务集群搭建与 CI/CD 部署实践Hyperf 基于 Docker Swarm 的微服务集群搭建与 CI/CD 部署实践 本文是一份面向中小型团队与个人开发者的完整实战指南讲解如何基于 Git后端Web框架微服务RPC框架异步编程Hyperf 项目 Docker Swarm 集群搭建实战指南从 GitLab CI 到镜像化部署Hyperf 项目 Docker Swarm 集群搭建实战指南从 GitLab CI 到镜像化部署 本文是一份面向 Hyperf 项目的 Docker Swa后端微服务Hyperf 基于 Docker Swarm 的集群部署实战从 Gitlab CI 到镜像发布的完整流水线Hyperf 基于 Docker Swarm 的集群部署实战从 Gitlab CI 到镜像发布的完整流水线 本教程围绕 Hyperf 项目的生产级容器化部署场后端微服务上一篇postgres-language-server 数据库安全规则解析rlsDisabledInPublic 检测公开 Schema 中未启用行级安全RLS的表下一篇es-toolkit 兼容层 intersectionBy 详解多数组交集与 Lodash 全形态 iteratee 支持创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考