香港服务器怎么搭建 CI/CD?从代码提交到自动上线完整实战

传统的网站更新,往往需要开发人员先在本地打包,再通过 FTP、SSH 或服务器面板上传文件。项目规模较小时,这种方式看起来简单,但随着更新频率提高,很容易出现漏传文件、依赖版本不一致、数据库迁移遗漏以及上线后无法快速回滚等问题。
CI/CD 自动化部署流水线的作用,就是把代码检查、测试、构建、发布和回滚串成一套固定流程。开发人员提交代码后,服务器按照预设规则自动执行任务,减少人工操作带来的不确定性。
本文以 GitLab Runner、Docker 和 Docker Compose 为例,介绍如何在香港服务器上搭建一套适合企业网站、Laravel 项目、API 服务和前后端分离项目的 CI/CD 流水线。
一、为什么选择香港服务器运行 CI/CD
CI/CD 服务器需要频繁拉取代码、下载依赖、构建镜像并向业务节点传输文件,因此对处理器并发能力、硬盘随机读写和网络稳定性都有一定要求。
香港服务器距离中国大陆及亚洲主要业务区域较近,适合作为代码仓库、构建节点和海外业务服务器之间的中间节点。对于同时使用 GitLab、GitHub、Docker Hub、npm、Composer 等开发资源的团队,也能减少跨区域传输带来的等待时间。
需要注意的是,CI/CD 对带宽峰值的要求通常没有下载站那么高,但对网络持续稳定性和硬盘 I/O 更敏感。尤其是 Docker 镜像分层、Composer 缓存、Node.js 依赖和构建产物较多时,普通机械硬盘很容易成为瓶颈。
二、案例服务器配置如何选择
本次案例采用下面这款香港服务器配置:
-
CPU:Intel Xeon Gold 6138,20核40线程
-
内存:128GB DDR4
-
硬盘:2×960GB U.2 NVMe SSD
-
网络:100Mbps 混合带宽,包含25Mbps CN2直连
-
系统:Ubuntu Server 22.04 LTS
这套配置并不是为了运行一个普通网站,而是为了同时承载 GitLab、容器镜像、多个 Runner、测试环境和部分业务容器。
在实际规划中,可以大致按照以下方式分配资源:
-
GitLab、Redis及容器镜像仓库:4核、16GB内存
-
两至三个并行构建 Runner:12核、64GB内存
-
测试环境或小型生产容器:4核、32GB内存
-
剩余内存作为系统缓存和峰值缓冲
两块 NVMe 硬盘建议配置 RAID 1。虽然可用容量会下降,但代码仓库、流水线配置和镜像数据比单纯追求容量更需要可靠性。
如果团队只有两三个人,每天构建次数较少,并不一定需要128GB内存;8核、16GB至32GB内存也可以搭建基础流水线。配置应根据并发任务数量选择,而不是单纯追求参数。
三、CI/CD 流水线的基本结构
一套完整的自动部署流程通常包含以下环节:
开发人员提交代码后,GitLab 检测到新的提交并创建流水线。Runner 随后拉取代码,安装依赖并执行自动化测试。测试通过后构建 Docker 镜像,将镜像推送至私有仓库,最后由部署节点拉取新镜像并重启应用。
整个过程可以概括为:
代码提交 → 自动测试 → 构建镜像 → 推送仓库 → 部署应用 → 健康检查 → 保留回滚版本
对于中小型项目,可以将 GitLab、Runner 和测试环境部署在同一台物理服务器中,但应通过 Docker 网络、资源限制和独立用户进行隔离。
业务规模扩大后,建议把生产应用部署到单独服务器。CI/CD 节点只负责测试和构建,再通过 SSH、Ansible 或容器镜像仓库将版本发布到生产节点,避免构建任务占用线上业务资源。
四、初始化香港服务器环境
首先更新系统并安装基础工具:
sudo apt update
sudo apt upgrade -y
sudo apt install -y \
ca-certificates \
curl \
git \
ufw \
fail2ban
创建专门用于部署的普通用户:
sudo adduser deploy
sudo usermod -aG sudo deploy
开启必要端口:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Runner 主动连接 GitLab 获取任务,通常不需要额外开放公网端口。服务器也不应直接开放数据库、Redis和Docker API端口。
五、安装 Docker 与 GitLab Runner
安装 Docker:
curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable docker
sudo systemctl start docker
将部署用户加入 Docker 用户组:
sudo usermod -aG docker deploy
安装 GitLab Runner:
curl -L \
"https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" \
| sudo bash
sudo apt install -y gitlab-runner
然后在 GitLab 项目的 Runner 设置中获取服务器地址和认证令牌,执行注册:
sudo gitlab-runner register
注册时可以设置:
Runner名称:hk-build-runner
Runner标签:hk-runner
Executor:shell 或 docker
对于可信的内部项目,Shell Executor 配置简单,可以直接使用宿主机中的 Docker、PHP、Composer和Node.js环境。
如果Runner需要服务多个项目,建议使用Docker Executor,让每个任务运行在独立容器中,减少不同项目之间的依赖冲突。
六、编写自动部署流水线
下面以 Laravel 和 Docker 项目为例,在项目根目录创建 .gitlab-ci.yml:
stages:
- test
- build
- deploy
variables:
IMAGE_NAME: "$CI_REGISTRY_IMAGE/app:$CI_COMMIT_SHORT_SHA"
test:
stage: test
tags:
- hk-runner
script:
- composer install --no-interaction --prefer-dist
- php artisan test
- npm ci
- npm run build
build:
stage: build
tags:
- hk-runner
script:
- echo "$CI_REGISTRY_PASSWORD" |
docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
- docker build --pull -t "$IMAGE_NAME" .
- docker push "$IMAGE_NAME"
deploy:
stage: deploy
tags:
- hk-deploy
resource_group: production
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
script:
- export APP_IMAGE="$IMAGE_NAME"
- docker compose -f deploy/docker-compose.yml pull
- docker compose -f deploy/docker-compose.yml up -d --remove-orphans
- curl -fsS https://example.com/health
environment:
name: production
url: https://example.com
这套配置完成了三个核心阶段。
test 阶段安装项目依赖并运行自动化测试;build 阶段生成带有提交编号的Docker镜像;deploy 阶段只允许主分支触发生产发布。
resource_group: production 可以避免两个生产部署任务同时运行。如果开发人员连续提交多次代码,后一个部署任务会等待前一个任务完成,降低容器版本互相覆盖的风险。
七、敏感信息不能写进代码仓库
数据库密码、SSH私钥、镜像仓库密码和第三方接口密钥,都不应该直接写入 .gitlab-ci.yml、Dockerfile或者代码仓库。
正确做法是在 GitLab 的 CI/CD Variables 中保存,例如:
DEPLOY_HOST
DEPLOY_USER
DEPLOY_PRIVATE_KEY
DB_PASSWORD
REGISTRY_PASSWORD
生产环境使用的变量应设置为 Protected,只允许受保护分支和受保护标签调用。日志中可能出现的密码还应设置为 Masked,防止敏感内容直接显示在任务日志中。
应用的 .env 文件也不应打包进Docker镜像,可以在部署时通过服务器环境变量、只读配置文件或密钥管理工具注入。
八、限制并行构建,避免影响线上业务
Gold 6138拥有较多核心,但Runner数量并不是越多越好。Composer安装、前端打包和Docker镜像压缩都可能在短时间内占满CPU、内存和磁盘读写。
可以在 /etc/gitlab-runner/config.toml 中控制最大并发任务数量:
concurrent = 3
对于同时承载生产应用的服务器,建议先将并发数设置为2,再根据CPU负载和构建时间逐步调整。
还可以为构建容器设置资源上限,确保CI任务不会挤占数据库和Web服务所需资源。正常情况下,至少应为业务应用保留约25%的处理器和内存余量。
九、健康检查与失败回滚
自动部署不能只判断容器是否启动,还需要确认应用是否真正可用。
可以在项目中增加健康检查接口:
https://example.com/health
接口应检查应用进程、数据库连接和必要的缓存服务。部署完成后,流水线通过 curl 请求健康检查地址,只有返回正常状态码才判定发布成功。
每个镜像使用提交编号作为版本标签,例如:
app:8f3a921c
如果新版本出现问题,可以立即切换到上一个稳定版本:
export APP_IMAGE="registry.example.com/project/app:上一版本编号"
docker compose -f deploy/docker-compose.yml up -d
相比直接覆盖网站文件,镜像版本回滚更加清晰,也不会出现旧文件残留或依赖不完整的问题。
十、日常维护最容易忽略的问题
CI/CD服务器长期运行后,最常见的问题不是CPU不足,而是Docker镜像、构建缓存和流水线产物不断占用磁盘。
建议定期检查:
docker system df
df -h
du -sh /var/lib/docker
镜像仓库应设置保留策略,只保留最近若干个正式版本和必要的回滚版本。GitLab流水线产物也应设置过期时间,避免日志、测试报告和压缩包永久保存。
同时需要备份GitLab配置、代码仓库、Runner配置和部署脚本。备份文件应同步到另一台服务器或对象存储中,而不是只保存在当前物理机的另一块硬盘上。
结语
在香港服务器上搭建CI/CD流水线,真正的价值并不是“自动上传代码”,而是建立一套可重复、可检查、可回滚的发布标准。
对于中小型团队,可以先从自动测试、Docker构建和主分支自动部署开始;业务稳定后,再逐步加入代码质量检查、人工审批、灰度发布、数据库备份和多节点部署。
服务器配置只是基础。合理限制Runner资源、保护部署密钥、保留历史镜像并设置健康检查,才是让自动化部署长期稳定运行的关键