基于Agent架构的轻量级自托管部署工具Ship实战指南
1. 项目概述一个为开发者而生的轻量级部署工具最近在折腾一个前后端分离的小项目从本地开发到服务器部署中间那套流程真是让人头大。代码提交、构建、测试、再到服务器上拉取、重启服务一套组合拳下来少说也得十几分钟还容易出错。就在我琢磨着怎么把这套流程自动化的时候一个叫Ship的工具进入了我的视野。它来自 heliohq 这个组织定位非常清晰一个极简、自托管的部署平台。简单来说Ship 的核心目标就是帮你把代码从 Git 仓库比如 GitHub, GitLab, Gitea自动、安全地部署到你的服务器上。它不像 Jenkins 那样庞大复杂也不像某些 SaaS 服务那样有使用限制和隐私顾虑。Ship 追求的是“开箱即用”和“掌控在自己手中”。你只需要在服务器上运行一个轻量的 Ship 服务然后通过 Web 界面配置好项目仓库和部署命令剩下的“代码推送 - 自动部署”的魔法就交给它了。这对于个人开发者、小团队或者那些需要频繁迭代、追求部署效率的项目来说吸引力巨大。它解决的痛点非常直接简化部署流程实现持续交付的自动化同时保持对数据和流程的完全控制。2. 核心设计思路与架构拆解Ship 的设计哲学深深烙印着“简单至上”和“专注核心”的理念。我们拆开来看它的架构并不复杂但每个环节都经过了深思熟虑。2.1 为什么选择 Agent-Based 架构市面上部署工具很多有需要在服务器上安装完整运行时的也有完全通过 SSH 远程执行命令的。Ship 采用了Agent-Based基于代理的架构。这意味着你需要在目标部署服务器上运行一个 Ship 的“代理”也就是 Ship 服务本身。这个设计有几个关键考量环境一致性Agent 运行在目标服务器上它执行部署命令时所处的环境就是你的应用最终运行的环境。这避免了因构建环境与运行环境差异导致的“在我机器上是好的”这类经典问题。依赖、路径、权限问题在部署阶段就能提前暴露。安全性Ship 的 Web 界面控制面板和 Agent 通常部署在同一内网或者通过安全的反向代理暴露。部署所需的 SSH 密钥、服务器密码等敏感信息完全不需要存储在 Ship 的配置数据库里。Agent 在本地执行命令天然拥有访问本地资源的权限消除了远程认证信息泄露的风险。网络简化Agent 主动连接或监听控制面板对于部署服务器位于复杂内网、没有固定公网 IP 的场景特别友好。你只需要让 Agent 能访问到控制面板的地址即可无需在防火墙上为控制面板开一大堆反向的入站端口。职责分离控制面板只负责管理项目配置、触发部署任务、展示日志具体的脏活累活拉取代码、执行脚本、重启服务由 Agent 在目标服务器完成。这种分离使得系统更易于维护和扩展。注意这里的“Agent”并不是一个独立的轻量级常驻进程在 Ship 的语境下运行在部署服务器上的整个 Ship 二进制程序就是它的 Agent。它包含了接收任务、执行任务的能力。2.2 核心工作流程解析一次完整的 Ship 自动部署其内部流程可以清晰地分为以下几个阶段触发阶段你在 Git 仓库配置了 Webhook指向 Ship 控制面板的 API 地址。当你向特定分支如main推送代码时Git 服务商会向这个地址发送一个 POST 请求。任务创建阶段Ship 控制面板接收到 Webhook 请求验证其签名如果配置了密钥以确保请求来源合法。然后它根据请求中的仓库信息匹配到预先配置好的项目并立即为此项目创建一个新的“部署任务”。这个任务处于“待处理”状态。任务分发阶段部署服务器上运行的 Ship Agent 会通过长轮询或 WebSocket 等方式持续向控制面板询问“有没有给我的新任务”。当它发现有属于自己的待处理任务时便会“领取”这个任务。执行阶段这是最核心的一步。Agent 开始按顺序执行你在项目中配置的“部署脚本”。拉取代码Agent 会使用配置好的 Git 认证方式如 SSH 私钥切换到项目指定的目录执行git pull或git fetch git reset --hard origin/分支名来获取最新代码。执行自定义脚本这是你大展拳脚的地方。脚本通常是一系列 shell 命令例如npm install或yarn安装 Node.js 依赖go build -o app编译 Go 项目docker-compose build --pull docker-compose up -d重建并启动 Docker 容器systemctl restart my-service重启系统服务状态上报每一个步骤执行时Agent 都会将实时日志流式地发送回控制面板让你能在网页上看到部署的实时进展。执行成功后任务状态更新为“成功”如果任何一步命令返回非零退出码则状态更新为“失败”并停止后续步骤。反馈阶段部署完成后Ship 控制面板可以配置通知例如通过邮件、Slack、钉钉等渠道将部署结果成功/失败告知相关人员。这个流程将复杂的部署自动化浓缩成了一个可配置、可观察的闭环极大地提升了效率。3. 从零开始Ship 的安装与初始化配置理论说得再多不如动手实践。下面我将以一台干净的 Ubuntu 22.04 服务器为例带你一步步搭建起属于你自己的 Ship 部署平台。3.1 服务器环境准备首先确保你的服务器具备基本条件一个非 root 的 sudo 用户。安装了 Docker 和 Docker Compose。这是 Ship 官方推荐的运行方式能解决依赖问题并方便更新。开放了必要的防火墙端口例如用于 Web 界面的 8080 端口。安装 Docker 和 Docker Compose 的步骤如果尚未安装# 更新包索引 sudo apt-get update # 安装依赖包允许 apt 通过 HTTPS 使用仓库 sudo apt-get install -y ca-certificates curl gnupg lsb-release # 添加 Docker 官方 GPG 密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 设置 Docker 稳定版仓库 echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装 Docker 引擎 sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 验证安装 sudo docker run hello-world3.2 使用 Docker Compose 部署 ShipShip 的部署非常简洁。我们创建一个docker-compose.yml文件来定义服务。version: 3.8 services: ship: image: heliohq/ship:latest container_name: ship restart: unless-stopped ports: - 8080:8080 # 将容器内 8080 端口映射到宿主机 volumes: - ./data:/app/data # 持久化存储配置和数据库 - /var/run/docker.sock:/var/run/docker.sock:ro # 允许 Ship 容器控制宿主机 Docker可选用于执行 Docker 命令 - ~/.ssh:/root/.ssh:ro # 挂载 SSH 密钥用于 Git 认证关键 environment: - SHIP_SERVER_ADDR:8080 # 服务监听地址 # - SHIP_DATABASE_DRIVERsqlite3 # 默认使用 SQLite无需配置 # - SHIP_DATABASE_URL/app/data/ship.db # 数据库路径默认在持久化卷中重要提示挂载~/.ssh目录是让 Ship 能够通过 SSH 协议克隆私有仓库的关键。请确保该目录下的私钥文件如id_rsa权限为600并且对应的公钥已添加到你的 Git 仓库服务GitHub/GitLab的部署密钥中。接下来启动 Ship 服务# 创建数据目录 mkdir -p data # 启动服务 docker-compose up -d # 查看日志确认启动无误 docker-compose logs -f ship看到服务正常启动的日志后打开浏览器访问http://你的服务器IP:8080。你应该能看到 Ship 的登录界面。首次使用你需要注册一个管理员账户。3.3 基础配置与项目创建登录后首先进行一些基础配置配置 Git 提供商在设置中添加你的 Git 服务商如 GitHub。对于私有仓库你需要提供一个具有仓库访问权限的Personal Access Token (PAT)。将 Token 填入 Ship它就能代表你与 Git 服务商 API 交互列出你的仓库、处理 Webhook。添加服务器这里的概念有点特殊。在 Ship 中“服务器”指的是运行了 Ship Agent 的部署目标机。因为我们目前是“All-in-One”安装控制面板和 Agent 在同一台机器所以我们需要添加本机。在“Servers”页面点击“Add Server”。给它起个名字比如 “Production-Server”。关键点Ship 会生成一个唯一的Server Token。这个 Token 用于 Agent 向控制面板认证身份。请妥善保存这个 Token我们下一步会用到。以 Agent 模式运行 Ship我们需要在同一个服务器上再启动一个 Ship 容器实例但这次它以 Agent 模式运行连接我们刚才创建的控制面板。创建一个新的docker-compose.agent.yml文件version: 3.8 services: ship-agent: image: heliohq/ship:latest container_name: ship-agent restart: unless-stopped command: agent # 指定以 agent 模式运行 environment: - SHIP_AGENT_SERVER_URLhttp://ship:8080 # 控制面板的地址。因为都在 Docker 网络可以用服务名。 - SHIP_AGENT_TOKENYOUR_SERVER_TOKEN_HERE # 替换为上一步保存的 Token - SHIP_AGENT_NAMEProduction-Server # 与之前添加的服务器名对应 volumes: - /home/your-user/workspace:/workspace # 挂载一个工作目录代码将拉取到这里 - ~/.ssh:/root/.ssh:ro # 同样需要 SSH 密钥来拉代码 - /var/run/docker.sock:/var/run/docker.sock:ro # 如果你需要在部署脚本中使用 docker 命令 network_mode: service:ship # 与 ship 服务共享网络方便访问注意network_mode: service:ship是一种让两个容器共享网络命名空间的简便方法这样 Agent 容器就能通过http://ship:8080直接访问到控制面板容器。在生产环境中你可能需要更精细的网络规划。启动 Agentdocker-compose -f docker-compose.agent.yml up -d回到 Ship 控制面板的“Servers”页面稍等片刻你应该能看到 “Production-Server” 的状态从“离线”变为“在线”。这表明 Agent 已经成功连接。创建你的第一个项目点击“Projects” - “New Project”。选择你配置好的 Git 提供商并选择你要部署的仓库。选择部署的服务器我们刚添加的 “Production-Server”。配置部署路径这是 Agent 服务器上的绝对路径代码将被拉取到这个目录。例如/workspace/my-app。确保挂载的卷/workspace存在且 Agent 容器有写入权限。配置部署脚本这是灵魂所在。例如对于一个简单的 Node.js 静态网站#!/bin/bash set -e # 遇到错误立即停止 echo 1. 拉取最新代码... git pull origin main echo 2. 安装依赖... npm install --production echo 3. 构建项目... npm run build echo 4. 将构建产物同步到 Nginx 目录... rsync -avz --delete ./dist/ /var/www/html/my-app/ echo 部署成功配置 Webhook 分支通常设置为main或master。这样向这个分支推送代码时才会触发自动部署。保存项目后Ship 会为你生成一个 Webhook URL。你需要将这个 URL 和可能的 Secret 密钥配置到你的 Git 仓库设置中。4. 深入核心部署脚本的编写艺术与最佳实践部署脚本是 Ship 发挥威力的地方。写得好部署行云流水写得不好就是灾难现场。下面分享一些编写稳健部署脚本的实战经验。4.1 脚本设计的基本原则原子性与幂等性每次部署脚本执行都应该力求将环境从一个稳定状态带到另一个稳定状态。脚本应该可以安全地重复执行幂等。例如使用git fetch git reset --hard origin/main比单纯的git pull更幂等因为它强制将本地状态重置为远程状态避免了合并冲突导致的问题。快速失败Fail Fast在脚本开头加上set -e这样任何命令失败返回非零状态都会立即终止脚本避免在错误的状态下继续执行造成更严重的问题。详细日志输出多用echo输出当前步骤。Ship 会捕获所有标准输出和错误输出清晰的日志是事后排查问题的生命线。环境隔离尽量不要在部署脚本中修改全局环境。对于不同项目使用独立的工作目录。考虑使用虚拟环境Pythonvenv、Node.js 的node_modules本地安装、Docker 容器等来实现环境隔离。4.2 不同技术栈的部署脚本示例示例一Python Django 应用使用 Gunicorn 和 Nginx#!/bin/bash set -e PROJECT_DIR/workspace/my-django-app VENV_PATH$PROJECT_DIR/venv BRANCHmain cd $PROJECT_DIR echo 激活虚拟环境... source $VENV_PATH/bin/activate echo 更新代码... git fetch origin git reset --hard origin/$BRANCH echo 安装依赖... pip install -r requirements.txt echo 执行数据库迁移... python manage.py migrate --no-input echo 收集静态文件... python manage.py collectstatic --no-input --clear echo 重启 Gunicorn 服务... sudo systemctl restart gunicorn-myapp echo Django 应用部署完成。心得这里使用了系统的systemctl来重启服务。确保运行 Ship Agent 的用户在容器内是 root有权限执行这个 sudo 命令。更安全的做法是通过visudo配置一个无需密码的特定命令权限。示例二Docker Compose 应用#!/bin/bash set -e PROJECT_DIR/workspace/my-docker-app COMPOSE_FILEdocker-compose.prod.yml cd $PROJECT_DIR echo 拉取最新代码和 Docker 镜像... git pull origin main docker-compose -f $COMPOSE_FILE pull echo 停止旧容器并启动新容器... docker-compose -f $COMPOSE_FILE down docker-compose -f $COMPOSE_FILE up -d echo 清理旧的 Docker 镜像可选... docker image prune -f echo Docker Compose 应用部署完成。注意docker-compose down会停止并删除容器。如果你的应用有需要持久化的数据卷请确保在docker-compose.yml中正确定义了volumes避免数据丢失。使用docker-compose stop和docker-compose start可能更安全但无法应用配置文件的变更。示例三前端静态资源React/Vue#!/bin/bash set -e PROJECT_DIR/workspace/my-frontend DEPLOY_DIR/var/www/html/my-frontend BRANCHmain cd $PROJECT_DIR echo 更新代码... git fetch origin git reset --hard origin/$BRANCH echo 安装依赖并构建... npm install npm run build echo 同步构建产物到 Web 目录... rsync -avz --delete --chownwww-data:www-data ./dist/ $DEPLOY_DIR/ echo 前端静态资源部署完成。技巧使用rsync的--delete选项可以确保目标目录是构建产物的精确镜像删除了旧版本中可能残留的无用文件。--chown可以直接在同步时修改文件属主避免权限问题。4.3 高级技巧回滚与健康检查一个成熟的部署流程必须考虑回滚。基于 Git Tag 的部署不要在脚本里总是拉取main分支的最新代码。可以在 Ship 的项目配置中将部署触发条件设置为“创建了新的 Tag”如v1.2.3。在部署脚本中通过环境变量获取这个 Tag 名然后拉取指定 Tag 的代码。回滚时只需重新推送旧的稳定 Tag 即可触发部署。Ship 的 Webhook 负载中通常包含ref字段表示触发此次部署的 Git 引用如refs/tags/v1.0.1。你可以在部署脚本中通过$SHIP_DEPLOY_REF之类的环境变量获取它具体变量名需查看 Ship 文档或源码。在脚本中实现备份与快速回滚#!/bin/bash set -e APP_DIR/var/myapp BACKUP_DIR/var/myapp-backups TIMESTAMP$(date %Y%m%d-%H%M%S) # 部署前备份当前版本 if [ -d $APP_DIR/current ]; then cp -r $APP_DIR/current $BACKUP_DIR/backup-$TIMESTAMP echo 已备份当前版本至: $BACKUP_DIR/backup-$TIMESTAMP fi # ... (执行拉取代码、构建等步骤) ... # 将新版本链接到 current ln -sfn $NEW_BUILD_DIR $APP_DIR/current # 健康检查例如检查应用端口是否响应 if curl -f http://localhost:3000/health /dev/null 21; then echo 健康检查通过部署成功。 # 可选清理过旧的备份 find $BACKUP_DIR -type d -mtime 7 | xargs rm -rf else echo 健康检查失败开始回滚... # 回滚到上一个备份 if [ -d $BACKUP_DIR/backup-$TIMESTAMP ]; then rm -f $APP_DIR/current ln -sfn $BACKUP_DIR/backup-$TIMESTAMP $APP_DIR/current # 重启服务... echo 已回滚至备份版本。 else echo 回滚失败未找到有效备份。 exit 1 fi fi5. 实战中遇到的典型问题与排查指南即使设计再完善在实际使用中也会遇到各种问题。下面是我在长期使用 Ship 过程中积累的一些常见问题及其解决方法。5.1 Webhook 触发失败症状代码推送到仓库后Ship 控制面板没有任何反应没有创建新的部署任务。排查步骤检查 Webhook 配置登录你的 GitHub/GitLab进入仓库设置下的 Webhook 页面查看 Ship 提供的 URL 是否配置正确。确保没有多余的斜杠或拼写错误。检查 Webhook 交付DeliveryGit 服务商通常会记录每次 Webhook 请求的发送记录和响应。查看最近的交付记录如果状态码不是2xx如 404, 502说明请求没有成功到达 Ship 或 Ship 处理出错。查看响应体有助于定位问题。检查 Ship 服务日志docker-compose logs -f ship。查看收到 Webhook 请求时控制面板容器是否有相关日志输出是否有错误信息。检查网络连通性确保你的 Git 服务商可以访问到 Ship 控制面板的公网 IP 和端口http://your-server-ip:8080。如果服务器在防火墙或云服务商安全组后请确保 8080 端口已放行。检查 Secret Token如果你在 Ship 和 Git 仓库都配置了 Webhook Secret请确保两者完全一致包括大小写。5.2 部署任务执行失败症状任务创建了但执行状态很快变为“失败”。这是最常见的问题。排查步骤查看任务日志这是首要操作。在 Ship 控制面板上点击失败的任务仔细阅读其完整日志。错误信息通常非常直接比如git clone失败权限问题、npm install失败网络问题、命令找不到环境问题。SSH 密钥权限问题如果日志显示gitgithub.com: Permission denied (publickey).说明 Agent 容器的 SSH 密钥未生效。进入 Agent 容器检查docker exec -it ship-agent sh然后运行ssh -T gitgithub.com测试连接。确保~/.ssh目录已正确挂载且私钥文件权限为600。确保公钥已添加到 Git 仓库的部署密钥中。路径与权限问题脚本中指定的工作目录/workspace/...在 Agent 容器内是否存在运行 Agent 的用户通常是 root是否有读写权限你可以在部署脚本开头加上pwd和ls -la来调试。环境变量缺失部署脚本中可能依赖某些环境变量如数据库连接字符串DATABASE_URL。这些变量需要在 Ship 的项目配置中或者 Agent 容器的环境变量中预先设置。Ship 项目配置通常支持添加自定义环境变量它们会在执行脚本时注入。命令超时某些操作如安装大量 npm 包或编译大型项目可能耗时很长。Ship 可能有默认的任务执行超时时间。如果超时任务会被标记为失败。检查 Ship 的配置或文档看是否可以调整超时时间或者优化你的构建流程。5.3 Agent 无法连接控制面板症状在“Servers”页面服务器状态一直显示为“离线”。排查步骤检查 Agent 容器日志docker-compose -f docker-compose.agent.yml logs -f ship-agent。查看是否有连接错误如connection refused或timeout。检查SHIP_AGENT_SERVER_URL确保 Agent 配置中的控制面板 URL 是正确的。在 All-in-One 部署中如果使用 Docker Compose 的服务名要确保两个容器在同一个 Docker 网络中。你也可以尝试使用宿主机的内网 IP 地址。检查SHIP_AGENT_TOKEN确认 Token 是否正确无误没有多余的空格或换行符。这个 Token 是在控制面板添加服务器时生成的。检查网络模式如果 Agent 容器使用了network_mode: “service:ship”确保ship服务正在运行。你也可以尝试改用自定义的 Docker 网络让两个容器都加入同一个网络。5.4 部署后服务未更新症状部署任务显示“成功”但访问网站或服务发现还是旧版本。排查步骤检查脚本是否真正重启了服务你的部署脚本最后一步是重启应用服务吗是systemctl restart还是发送信号查看脚本日志确认重启命令确实执行了。检查服务状态登录部署服务器手动检查应用服务的状态如systemctl status your-servicedocker ps。确认它是否真的重启了以及重启后是否正常运行。检查缓存如果是 Web 应用可能是浏览器或 CDN 缓存了旧资源。尝试强制刷新浏览器CtrlF5或清理 CDN 缓存。检查构建产物路径确认你的部署脚本将新的构建产物正确放置到了 Web 服务器如 Nginx配置的根目录下没有放错位置。6. 进阶应用多环境、多服务器与监控集成当你的项目从单机测试走向多环境、多服务器部署时Ship 也能很好地应对。6.1 管理多环境开发、测试、生产最佳实践是为每个环境创建独立的 Ship 项目。不同的 Git 分支为develop,staging,main分支分别创建 Ship 项目。每个项目配置不同的 Webhook 分支触发器。不同的部署服务器/路径将开发环境部署到测试服务器 A 的/var/www/dev路径生产环境部署到服务器 B 的/var/www/prod路径。不同的环境变量在 Ship 的项目设置中为每个环境注入不同的环境变量如API_BASE_URL,DATABASE_URL等。审批流程手动触发对于生产环境你可能不希望每次推送都自动部署。可以在 Ship 的项目设置中禁用自动部署。当需要上线时手动在 Ship 控制面板上点击“Deploy”按钮选择要部署的分支或 Tag。这相当于一个简单的人工审批环节。6.2 部署到多台服务器负载均衡场景假设你的应用运行在多台负载均衡器后端的服务器上。在 Ship 中添加所有服务器在“Servers”页面为每台后端服务器如web-01,web-02,web-03都添加一个记录并分别运行对应的 Agent。创建项目组或使用相同脚本你可以为这个应用创建一个 Ship 项目然后在部署脚本中通过判断当前服务器的 hostname 或 IP 来执行略微不同的操作如果需要。更常见的做法是所有后端服务器的部署脚本完全一致。串行与并行部署Ship 目前版本通常是一个项目关联一台服务器。要实现多服务器部署你需要为每台服务器创建一个项目但指向同一个 Git 仓库。部署时需要手动或通过脚本依次触发这些项目的部署。对于需要“零停机”更新的场景你需要在脚本中实现“从负载均衡器摘除 - 部署 - 健康检查 - 重新加入负载均衡器”的复杂逻辑这可能超出了 Ship 的范畴需要结合 Ansible、自定义脚本或更专业的部署工具来协作完成。6.3 与监控和通知系统集成让部署过程可观测。通知集成Ship 支持配置通知渠道。在项目设置或全局设置中可以添加 Slack、Discord、邮件等通知。这样每次部署开始、成功或失败时相关团队都能及时收到消息。与监控系统联动部署完成后可以主动触发一个 HTTP 请求到你的监控系统如 Prometheus Pushgateway、Health Check Endpoint告知一次新的部署已经发生。或者在你的部署脚本最后调用监控系统的 API 记录一个“部署事件”。日志聚合Ship 的任务日志虽然可以在界面查看但长期存储和检索不便。可以考虑将容器日志docker logs导出到 ELKElasticsearch, Logstash, Kibana或 Loki 等日志聚合系统方便集中管理和分析历史部署记录。7. 安全加固与维护建议将部署自动化工具暴露在公网上安全不容忽视。使用 HTTPS绝对不要在生产环境通过 HTTP 访问 Ship 控制面板。使用 Nginx 或 Caddy 作为反向代理配置 SSL/TLS 证书可以使用 Let‘s Encrypt 免费证书将http://your-ip:8080变为https://ship.yourdomain.com。强化认证除了 Ship 自带的账号密码考虑在反向代理层增加一层 HTTP 基本认证或者使用 OAuth2 代理增加一道安全屏障。限制 Webhook IP如果可能在你的 Git 服务商如 GitHub的 Webhook 设置中限制触发 Webhook 的 IP 地址为 Ship 服务器的公网 IPGitHub 提供了 IP 范围列表。这可以防止来自未知源的回调请求。使用 Webhook Secret务必为每个项目的 Webhook 配置一个强密钥Secret并在 Ship 中填写相同的密钥。这样 Ship 会验证请求的签名确保 Webhook 来自合法的 Git 服务商。最小权限原则为 Ship Agent 挂载的 SSH 密钥应该是专用于部署的、权限受限的密钥对不要使用个人主密钥。在 Git 仓库中给部署密钥只读Pull权限即可。谨慎处理部署脚本中的sudo命令尽量通过配置系统服务的方式让 Ship 以非 root 用户运行 Agent并通过精细的 sudoers 配置授予其重启特定服务的最小权限。定期更新关注 heliohq/ship 的 GitHub 仓库定期更新 Docker 镜像到新版本以获取安全补丁和功能更新。更新前请备份好data目录下的数据库文件。经过这样一番从理论到实践从入门到进阶的梳理相信你已经对 Ship 这个轻量而强大的部署工具有了全面的认识。它可能不是功能最全的但它在简单性、可控性和“够用”之间找到了一个非常好的平衡点。对于追求效率、注重隐私、希望将部署流程掌握在自己手中的开发者和团队来说Ship 是一个非常值得尝试的解决方案。我最深的体会是自动化部署带来的不仅仅是时间上的节省更是一种心理上的解脱——你再也不用担心深夜上线时敲错命令因为整个过程都已被清晰、可重复的脚本所定义。剩下的就是享受代码推送后服务自动更新的那份从容了。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2605657.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!