将 Docker 镜像推送到 GitLab Container Registry 的完整步骤

发布于:2025-05-23 ⋅ 阅读:(12) ⋅ 点赞:(0)

一、前提准备

  1. GitLab 项目:

    • 在 GitLab 上拥有一个项目,例如 your-group/your-project-name
    • 重要: 确保项目路径(尤其是项目名称部分)全部使用小写字母。例如,如果初始是 Your-Project,请在项目设置中将其路径修改为 your-project
    • 在项目中启用 Container Registry 功能 (通常默认启用)。可以在项目的 Settings -> Packages & Registries 中查看。
  2. GitLab Personal Access Token (PAT):

    • 登录 GitLab。
    • 进入用户设置 (右上角头像 -> Edit profile -> Access Tokens)。
    • 创建一个新的 Personal Access Token。
    • 关键权限 (Scopes): 授予该 PAT read_registrywrite_registry 权限。
    • 复制生成的 PAT 字符串并妥善保管,它只显示一次。
  3. 本地 Docker 环境:

    • 安装并运行 Docker Desktop 或 Docker Engine。
  4. 项目代码和 Dockerfile:

    • 你的应用程序代码(例如 Spring Boot 后端、Vue 前端)。
    • 为每个需要构建镜像的应用准备好 Dockerfile(例如 Dockerfile.backend, Dockerfile.frontend)。

二、配置项目 .env 文件

在你的项目(通常在 docker/ 目录下或项目根目录)创建一个 .env 文件,用于存储配置变量。核心内容如下:

# --- GitLab Container Registry 配置 ---
# 1. DOCKER_REGISTRY: GitLab Registry 的完整路径
#    格式: registry.gitlab.com/<你的组名>/<你的项目名全小写>
DOCKER_REGISTRY=registry.gitlab.com/your-group/your-project-name

# 2. COMPOSE_PROJECT_NAME: 用于构成镜像名称的一部分 (可选, 但脚本中使用了)
#    例如 'xsgl', 最终镜像名会是 .../your-project-name/xsgl-backend
COMPOSE_PROJECT_NAME=myapp

# 3. 镜像标签 (可选, 默认为 latest)
BACKEND_IMAGE_TAG=v1.0
FRONTEND_IMAGE_TAG=v1.0

# --- GitLab 凭据 (用于脚本,如果选择硬编码或从 .env 加载) ---
# 警告: 直接在 .env 中存储 PAT 有安全风险,更好的方式是运行时输入或使用更安全的凭据管理
# 如果脚本设计为提示输入,则这两项可以省略
# GITLAB_USERNAME="你的GitLab用户名"
# GITLAB_PAT="你的GitLab_PAT字符串"

# --- 其他应用相关配置 (例如数据库密码、API密钥等) ---
# MYSQL_ROOT_PASSWORD=your_strong_password
# ... 其他配置 ...

请将 registry.gitlab.com/your-group/your-project-name 替换为你的实际 GitLab Registry 路径,并确保项目名是小写的。

三、编写/修改构建和推送脚本 (build-push.sh)

这是一个 Bash 脚本,用于自动化构建应用、构建 Docker 镜像并将其推送到 GitLab Registry。

核心代码片段 (build-push.sh):

#!/bin/bash

# ... (脚本头部,加载 .env 等,见之前脚本) ...

# --- 定义镜像名称 --- #
# 使用 .env 中的 DOCKER_REGISTRY, COMPOSE_PROJECT_NAME, *_IMAGE_TAG
BACKEND_IMAGE_FULL_NAME="${DOCKER_REGISTRY}/${COMPOSE_PROJECT_NAME}-backend:${BACKEND_IMAGE_TAG:-latest}"
FRONTEND_IMAGE_FULL_NAME="${DOCKER_REGISTRY}/${COMPOSE_PROJECT_NAME}-frontend:${FRONTEND_IMAGE_TAG:-latest}"

echo "将要构建并推送以下镜像:"
echo "  后端: $BACKEND_IMAGE_FULL_NAME"
echo "  前端: $FRONTEND_IMAGE_FULL_NAME"

# --- 登录到 Docker Registry --- #
# 从 DOCKER_REGISTRY 变量中提取主机名 (registry.gitlab.com)
DOCKER_REGISTRY_HOST=$(echo "$DOCKER_REGISTRY" | awk -F/ '{print $1}') # 应为 registry.gitlab.com

if [ -z "$DOCKER_REGISTRY_HOST" ]; then
    echo "错误: 无法从 DOCKER_REGISTRY ($DOCKER_REGISTRY) 中提取主机名。"
    exit 1
fi

# --- Docker 登录方式选择 ---
# 方式1: 运行时提示输入 (更安全)
# echo "--- GitLab Docker Registry 登录 ---"
# read -p "请输入您的 GitLab 用户名: " GITLAB_USERNAME
# read -s -p "请输入您的 GitLab Personal Access Token (具有 read_registry 和 write_registry 权限): " GITLAB_PAT
# echo ""

# 方式2: 硬编码 (有安全风险,如之前讨论)
GITLAB_USERNAME="your-gitlab-username" # 替换为你的 GitLab 用户名
GITLAB_PAT="your-gitlab-pat-string"    # 替换为你的 PAT

if [ -z "$GITLAB_USERNAME" ] || [ -z "$GITLAB_PAT" ]; then
    echo "错误: GitLab 用户名或 PAT 未提供/设置。"
    exit 1
fi

echo "正在尝试登录到 $DOCKER_REGISTRY_HOST ..."
echo "$GITLAB_PAT" | docker login "$DOCKER_REGISTRY_HOST" -u "$GITLAB_USERNAME" --password-stdin
LOGIN_EXIT_CODE=$?
echo "Docker login 命令退出状态码: $LOGIN_EXIT_CODE"

if [ $LOGIN_EXIT_CODE -ne 0 ]; then
    echo "错误: Docker 登录到 $DOCKER_REGISTRY_HOST 失败 (退出码: $LOGIN_EXIT_CODE)。"
    # ... (添加详细的错误检查提示) ...
    exit 1
fi
echo "Docker 登录成功。"

# --- 构建应用程序 (示例: 后端 Maven, 前端 npm) --- #
# echo "\n>>> 开始构建后端项目..."
# cd "$PROJECT_ROOT"
# ./mvnw.cmd clean package -Dmaven.test.skip=true -f pom.xml # 或 ./mvnw ...
# echo "后端项目构建完成。"

# echo "\n>>> 开始构建前端项目..."
# cd "$PROJECT_ROOT/ruoyi-ui" # 假设前端项目在 ruoyi-ui
# npm install # 如果需要
# npm run build:prod # 或其他构建命令
# echo "前端项目构建完成。"
# cd "$PROJECT_ROOT"


# --- 构建 Docker 镜像 --- #
echo "\n>>> 开始构建后端 Docker 镜像..."
docker build -t "$BACKEND_IMAGE_FULL_NAME" -f "$DOCKER_DIR/Dockerfile.backend" "$PROJECT_ROOT"

echo "\n>>> 开始构建前端 Docker 镜像..."
docker build -t "$FRONTEND_IMAGE_FULL_NAME" -f "$DOCKER_DIR/Dockerfile.frontend" "$PROJECT_ROOT" # 假设前端 Dockerfile 和上下文

echo "Docker 镜像构建完成。"

# --- 推送 Docker 镜像 --- #
echo "\n>>> 开始推送后端镜像 $BACKEND_IMAGE_FULL_NAME ..."
docker push "$BACKEND_IMAGE_FULL_NAME"

echo "\n>>> 开始推送前端镜像 $FRONTEND_IMAGE_FULL_NAME ..."
docker push "$FRONTEND_IMAGE_FULL_NAME"

echo "\n>>> 镜像推送完成!"
# ... (脚本尾部) ...

关键点解释:

  • DOCKER_REGISTRY: 必须是 registry.gitlab.com/...
  • DOCKER_REGISTRY_HOST: 脚本应正确提取出 registry.gitlab.com 作为登录主机。
  • 登录方式: 使用 --password-stdin 配合 PAT,这是脚本化登录的推荐方式。避免将 PAT 直接作为 docker login 的密码参数(不安全)。
  • 镜像名称全小写: GitLab(和 Docker)要求仓库路径和镜像名称(除了标签)为全小写。BACKEND_IMAGE_FULL_NAMEFRONTEND_IMAGE_FULL_NAME 的构造必须符合此规则。
  • 构建步骤: 脚本中应包含实际编译/构建你的应用程序的命令(例如 mvn packagenpm run build),这些步骤在 docker build 之前执行,以确保 Dockerfile 能复制到最新的构建产物。

四、执行脚本

  1. 确保 .env 文件配置正确。
  2. 确保 build-push.sh 脚本具有执行权限 (chmod +x build-push.sh)。
  3. 在终端中运行脚本:./build-push.sh
  4. 如果脚本设计为提示输入凭据,则按提示输入 GitLab 用户名和 PAT。

五、验证

推送成功后,你可以:

  • 在 GitLab 项目的 Packages & Registries -> Container Registry 页面看到你推送的镜像。
  • 在其他机器或环境中使用 docker pull ${DOCKER_REGISTRY}/${COMPOSE_PROJECT_NAME}-backend:${BACKEND_IMAGE_TAG} 来拉取镜像(需要先 docker login registry.gitlab.com)。

六、Mermaid 流程图

开始
创建/配置 GitLab 项目
生成 GitLab PAT
配置本地.env 文件
编写/配置 build-push.sh脚本
执行 build-push.sh
脚本加载.env
脚本定义镜像全名
脚本提取 DOCKER_REGISTRY_HOST
脚本执行 docker login
登录成功?
脚本构建应用程序
脚本执行 docker build
脚本执行 docker push
推送成功?
错误:登录失败,退出
成功:镜像推送到GitLab Registry
错误:推送失败 (检查PAT权限/路径/网络),退出
结束

七、技术文档核心要点 (总结)

目标: 将本地构建的 Docker 镜像安全可靠地推送到 GitLab Container Registry。

  1. GitLab Registry 地址: 标准地址为 registry.gitlab.com。镜像的完整路径遵循 registry.gitlab.com/<group_name>/<project_name_lowercase>/<image_name>:<tag> 格式。
  2. 认证:
    • 使用 GitLab Personal Access Token (PAT)。
    • PAT 必须具有 read_registrywrite_registry 权限。
    • 在脚本中使用 docker login registry.gitlab.com -u <gitlab_username> --password-stdin,通过管道将 PAT 传递给 --password-stdin
  3. 命名规范:
    • GitLab 项目路径(尤其是在 Registry 中引用的部分)必须全小写
    • Docker 镜像名称(不含标签)也必须全小写。
  4. 脚本化:
    • 使用 .env 文件管理配置变量(如 DOCKER_REGISTRY, IMAGE_TAGS),将 .env 文件加入 .gitignore
    • Bash 脚本 (build-push.sh) 自动化以下流程:
      • 加载配置。
      • 执行 docker login
      • (可选但推荐) 构建应用程序(例如 mvn package, npm run build)。
      • 执行 docker build,使用正确的全名和标签为镜像打 Tag。
      • 执行 docker push 推送镜像。
      • 包含错误检查和清晰的日志输出。
  5. 关键命令片段:
    • .env 配置:
      DOCKER_REGISTRY=registry.gitlab.com/your-group/your-project-lowercase
      GITLAB_USERNAME="your_gitlab_username" # 或者脚本中提示输入
      # GITLAB_PAT="your_pat" # 更推荐脚本中提示输入或从安全位置读取
      
    • docker login (脚本中):
      echo "$GITLAB_PAT" | docker login "registry.gitlab.com" -u "$GITLAB_USERNAME" --password-stdin
      
    • docker build (脚本中):
      IMAGE_FULL_NAME="${DOCKER_REGISTRY}/myimage:${TAG}"
      docker build -t "$IMAGE_FULL_NAME" -f path/to/Dockerfile .
      
    • docker push (脚本中):
      docker push "$IMAGE_FULL_NAME"
      
  6. 常见问题与陷阱:
    • Registry 主机名错误: 使用 gitlab.com 而不是 registry.gitlab.com 进行登录/推送。
    • 大小写问题: GitLab 项目路径或镜像名中包含大写字母。
    • PAT 权限不足: PAT 未授予 write_registry 权限。
    • PAT 过期或无效
    • 非 TTY 环境下的交互式登录尝试: 应使用 --password-stdin
    • 网络/防火墙问题 阻止对 registry.gitlab.com 的访问。

这份文档应该能帮助你或其他开发者理解并成功配置 GitLab Registry 的推送流程!


网站公告

今日签到

点亮在社区的每一天
去签到