从零搭建 Windows + WSL2 + Docker + GitLab CI/CD 完整手册

从零搭建 Windows + WSL2 + Docker + GitLab CI/CD 完整手册

本手册主要用于初学者自行搭建,适用于在 Windows 环境下(通过 WSL2)搭建一套完整的 DevOps 实验环境,包括 GitLab 代码仓库、GitLab Runner 以及 CI/CD 流水线配置。所有步骤均经过实践验证,避开了常见陷阱(如 localhost 配置、端口冲突、DNS 问题等)。


目录

  1. 环境概览与准备工作
  2. [安装 WSL2 与 Ubuntu](#安装 WSL2 与 Ubuntu)
  3. [在 WSL Ubuntu 中安装 Docker](#在 WSL Ubuntu 中安装 Docker)
  4. [部署 GitLab CE(使用自定义域名)](#部署 GitLab CE(使用自定义域名))
  5. [安装并注册 GitLab Runner](#安装并注册 GitLab Runner)
  6. [创建示例项目与 CI/CD 流水线](#创建示例项目与 CI/CD 流水线)
  7. [高级:使用 Jib 构建 Java 镜像并部署到远程服务器](#高级:使用 Jib 构建 Java 镜像并部署到远程服务器)
  8. 常见问题与解决方案

1. 环境概览与准备工作

🎯 目标

在 Windows + WSL+ Ubuntu 环境下搭建完整的 DevOps 环境,包括:

  1. WSL Ubuntu 环境配置 - 在 Windows 上运行 Linux
  2. Docker 和 Docker Compose 安装 - 容器化技术基础
  3. GitLab 私有部署 - 自建代码仓库和 CI/CD 平台
  4. CI/CD 管道配置 - 自动化构建、测试、部署
  5. 完整开发工作流实践 - 从编码到部署的全流程

✅ 预期成果

  • ✅ 本地开发环境(Windows VS Code + WSL)
  • ✅ WSL Ubuntu 中的 Docker 环境
  • ✅ GitLab CE 私有仓库
  • ✅ 自动化的 CI/CD 管道
  • ✅ 可重复的部署流程

1.2 系统要求

  • Windows 版本: Windows 10 版本 2004 或更高(推荐 Windows 11)
  • 内存: 至少 8GB(推荐 16GB,GitLab 至少需要 4GB)
  • 磁盘空间: 至少 50GB 可用空间
  • CPU: 支持虚拟化技术(VT-x/AMD-V)
  • 网络: 稳定的互联网连接

1.3 前置软件

  1. Windows 终端(Windows Terminal)或 PowerShell
  2. Git for Windows(可选,如果使用 WSL 内的 Git 则不需要)

1.4 重要说明

  • 本手册使用 WSL2 而不是 Docker Desktop ,原因:
    • WSL2 性能更好,资源占用更少
    • 避免 Docker Desktop 许可证问题
    • 更接近生产环境(Linux 原生 Docker)
  • 所有操作均在 WSL2 Ubuntu 中完成,Windows 仅作为宿主系统
  • 使用自定义域名(如 gitlab.local)

2. 安装 WSL2 与 Ubuntu

🔄 两种安装方式选择

选项A:快速安装(推荐初学者)

powershell 复制代码
# 以管理员身份运行 PowerShell,执行:
wsl --install

# 命令执行后会:
# 1. 自动启用所需功能
# 2. 下载并安装 WSL 2 内核
# 3. 安装最新 Ubuntu LTS
# 4. 提示重启系统

# 重启后,从开始菜单启动 "Ubuntu"
# 设置用户名和密码

选项B:手动安装(深入了解)

如果你想深入了解每个步骤,请按照以下手动安装:

2.1 安装 WSL(Windows Subsystem for Linux)
步骤 2.1.1:启用 WSL 功能
powershell 复制代码
# 以管理员身份运行 PowerShell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
步骤 2.1.2:启用虚拟机平台
powershell 复制代码
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
步骤 2.1.3:重启计算机
powershell 复制代码
# 重启后继续
Restart-Computer -Force
2.2 安装 Ubuntu 发行版
2.2.1:设置 WSL 2 为默认版本
powershell 复制代码
wsl --set-default-version 2
2.2.2 安装 WSL2 内核更新包
  1. 下载 WSL2 Linux 内核更新包
  2. 安装并重启
2.2.3 安装 Ubuntu
powershell 复制代码
# 查看可用发行版

wsl --list --online


# 安装 Ubuntu 22.04 LTS(推荐)

wsl --install -d Ubuntu-22.04


# 或者安装 Ubuntu 24.04 LTS

wsl --install -d Ubuntu-24.04
2.2.4 初始化 Ubuntu
  1. 首次启动会提示创建用户名和密码
  2. 建议使用非 root 用户,避免权限问题
2.3 配置 WSL Ubuntu 环境
步骤 2.3.1:更新软件包列表

在 Ubuntu 终端中:

bash 复制代码
# 更新包列表
sudo apt update

# 升级现有包
sudo apt upgrade -y

# 安装基础工具
sudo apt install -y \
  curl \
  wget \
  git \
  unzip \
  zip \
  vim \
  net-tools \
  htop \
  tree \
  ca-certificates \
  apt-transport-https \
  software-properties-common \
  gnupg \
  lsb-release
步骤 2.3.2:配置 WSL 内存和交换空间

创建 WSL 配置文件:

powershell 复制代码
# 在 Windows PowerShell 中执行
notepad "$env:USERPROFILE/.wslconfig"

添加以下内容:

ini 复制代码
[wsl2]
memory=8GB        # 限制 WSL 内存使用
swap=4GB          # 交换空间大小
processors=4      # CPU 核心数
localhostForwarding=true
步骤 2.3.3:重启 WSL
powershell 复制代码
wsl --shutdown
# 等待几秒后重新启动 Ubuntu

3. 在 WSL Ubuntu 中安装 Docker

3.1 更新系统

bash 复制代码
# 进入 WSL Ubuntu
wsl -d Ubuntu-22.04

# 更新包列表
sudo apt update && sudo apt upgrade -y

# 安装基础工具
sudo apt install -y curl wget vim git

3.2 卸载旧版本 Docker(如有)

bash 复制代码
sudo apt remove docker docker-engine docker.io containerd runc

3.3 安装 Docker

bash 复制代码
# 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /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 \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker Engine
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 验证安装
docker --version
docker compose version

3.4 配置 Docker 用户组

bash 复制代码
# 将当前用户加入 docker 组
sudo usermod -aG docker $USER

# 生效组更改
newgrp docker

# 验证无需 sudo 运行 Docker
docker run hello-world

3.5 配置 Docker 守护进程

bash 复制代码
# 创建配置文件
sudo tee /etc/docker/daemon.json <<EOF
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ],
  "storage-driver": "overlay2"
}
EOF
bash 复制代码
# 重启 Docker 服务
sudo systemctl restart docker

# 设置 Docker 开机自启
sudo systemctl enable docker

# 检查 Docker 状态
sudo systemctl status docker

# 验证镜像加速配置
docker info | grep -A 5 "Registry Mirrors"

# 预期输出:
# Registry Mirrors:
# https://<你的ID>.mirror.aliyuncs.com/
# https://docker.mirrors.ustc.edu.cn/
# https://hub-mirror.c.163.com/

3.6 测试 Docker 安装(如果失败,检查上一步,替换其他配置)

bash 复制代码
# 运行测试容器
docker run -d -p 80:80 --name nginx-test nginx:alpine

# 访问测试
curl http://localhost

# 清理测试容器
docker stop nginx-test && docker rm nginx-test


## 4. 部署 GitLab CE(使用自定义域名)


> 💡 **部署前注意**:GitLab 对资源要求较高,建议系统至少有 8GB 内存。首次启动需要下载约 2GB 的镜像,使用 Docker 镜像加速可以显著提高下载速度。

### 4.1 创建部署目录

```bash
# 创建 GitLab 数据目录
mkdir -p ~/gitlab/{config,data,logs}
cd ~/gitlab

4.2 创建 docker-compose.yml

yaml 复制代码
version: '3.8'

services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    container_name: gitlab
    restart: always
    hostname: 'gitlab.local'  # 自定义域名
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.local'  # 使用自定义域名
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        # 监听端口配置
        nginx['listen_port'] = 80
        nginx['listen_https'] = false
        # 禁用 Let's Encrypt(内网环境不需要)
        letsencrypt['enable'] = false
        # 邮箱配置(可选)
        # gitlab_rails['gitlab_email_enabled'] = true
        # gitlab_rails['gitlab_email_from'] = 'gitlab@gitlab.local'
        # gitlab_rails['smtp_enable'] = true
        # gitlab_rails['smtp_address'] = "smtp.example.com"
        # gitlab_rails['smtp_port'] = 587
        # gitlab_rails['smtp_user_name'] = "user@example.com"
        # gitlab_rails['smtp_password'] = "password"
        # gitlab_rails['smtp_authentication'] = "login"
        # gitlab_rails['smtp_enable_starttls_auto'] = true
        # gitlab_rails['smtp_tls'] = false
        # 性能调优(根据内存调整)
        puma['worker_processes'] = 2
        sidekiq['max_concurrency'] = 10
        # 时区设置
        gitlab_rails['time_zone'] = 'Asia/Shanghai'
    ports:
      - "80:80"      # HTTP
      - "443:443"    # HTTPS(如需)
      - "2222:22"    # SSH
    volumes:
      - ./config:/etc/gitlab
      - ./logs:/var/log/gitlab
      - ./data:/var/opt/gitlab
    networks:
      - gitlab-network

networks:
  gitlab-network:
    driver: bridge

4.3 配置 Windows hosts 文件

由于使用自定义域名 gitlab.local,需要在 Windows 中添加 DNS 解析:

  1. 管理员身份打开 PowerShell
  2. 编辑 hosts 文件:
powershell 复制代码
# 获取 WSL2 IP 地址
$wsl_ip = (wsl hostname -I).Trim()

# 添加 hosts 记录
Add-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Value "`n$wsl_ip gitlab.local" -Force

或者手动编辑 C:\Windows\System32\drivers\etc\hosts,添加:

复制代码
# WSL2 GitLab
<WSL2_IP地址> gitlab.local

4.4 启动 GitLab

bash 复制代码
cd ~/gitlab

# 预拉取 GitLab 镜像 ,尝试原始镜像:
docker pull gitlab/gitlab-ce:latest

# 如果拉取失败(使用国内镜像源)
# docker pull registry.gitlab.cn/gitlab-org/build/cng/gitlab-ce:latest



# 查看已下载的镜像
docker images | grep gitlab

# 使用 Docker Compose 启动 GitLab
docker compose up -d

# 查看容器状态
docker-compose ps

# 预期输出:
# Name              Command               State                       Ports
# ------------------------------------------------------------------------------------
# gitlab   /assets/wrapper   Up (health: starting)   0.0.0.0:2222->22/tcp, 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp

重要提示:首次启动需要 5-10 分钟,GitLab 会进行初始化配置。

4.5 获取初始 root 密码

bash 复制代码
# 获取 root 密码
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

4.6:手动重置密码(备用方案)

bash 复制代码
# 如果无法获取自动生成的密码,可以手动重置
docker exec -it gitlab gitlab-rake "gitlab:password:reset[root]"

# 按照提示输入新密码两次
# 注意:密码长度至少 8 个字符

4.7 验证安装

bash 复制代码
# 查看容器状态
docker compose ps

# 查看启动日志
docker compose logs --tail=50 gitlab

# 检查服务状态
docker exec -it gitlab gitlab-ctl status

4.8 配置 GitLab

步骤 4.8.1:首次登录 GitLab
  1. 打开浏览器 :访问 http://localhost:8080
  2. 登录账号
    • 用户名:root
    • 密码:使用刚刚获取的初始密码
  3. 修改密码:登录后立即修改 root 密码(重要!)

⚠️ 安全提示:初始密码是随机生成的,请务必立即修改为强密码。

步骤 4.8.2:基本配置(优化中文体验)
  1. 个人资料设置

    • 点击右上角头像 → SettingsProfile
    • 更新姓名、用户名、邮箱
    • 上传头像(可选)
  2. 偏好设置

    • SettingsPreferences
    • 语言:简体中文(Chinese - 中文)
    • 时区:Asia/Shanghai
    • 主题:选择喜欢的颜色主题
    • 保存更改
  3. SSH 密钥配置 (重要):

    bash 复制代码
    # 在 WSL 中生成 SSH 密钥
    ssh-keygen -t ed25519 -C "your-email@example.com"
    # 查看公钥
    cat ~/.ssh/id_ed25519.pub

    在 GitLab 中添加 SSH 密钥:

    • SettingsSSH Keys
    • 粘贴公钥内容
    • 标题:WSL-Ubuntu-Dev
    • 点击 "Add key"
  4. 测试 SSH 连接

    bash 复制代码
    ssh -T git@localhost -p 2222
    # 预期输出:
    # Welcome to GitLab, @root!

5. 安装并注册 GitLab Runner

5.1 安装 GitLab Runner

bash 复制代码
# 添加 GitLab Runner 仓库
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash

# 安装 GitLab Runner
sudo apt install -y gitlab-runner

# 验证安装
gitlab-runner --version

5.2 获取注册令牌

  1. 登录 GitLab:http://gitlab.local
  2. 进入 Admin Area(管理员区域)
  3. 左侧菜单选择 CI/CDRunners
  4. 复制 注册令牌(Registration Token)

5.3 注册 Runner

bash 复制代码
# 注册 Runner
sudo gitlab-runner register \
  --non-interactive \
  --url "http://gitlab.local" \
  --registration-token "YOUR_REGISTRATION_TOKEN" \
  --executor "docker" \
  --docker-image "docker:latest" \
  --description "WSL2 Docker Runner" \
  --tag-list "docker,wsl2,linux" \
  --run-untagged="true" \
  --locked="false" \
  --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
  --docker-volumes "/cache"

5.4 配置 Runner

编辑配置文件 /etc/gitlab-runner/config.toml

toml 复制代码
concurrent = 4
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "WSL2 Docker Runner"
  url = "http://gitlab.local"
  token = "YOUR_RUNNER_TOKEN"
  executor = "docker"
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:latest"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
    shm_size = 0

5.5 启动并验证 Runner

bash 复制代码
# 重启 Runner 服务
sudo systemctl restart gitlab-runner
sudo systemctl enable gitlab-runner

# 验证 Runner
sudo gitlab-runner verify
sudo gitlab-runner list

# 查看 Runner 状态
sudo gitlab-runner status

5.6 测试 Runner 连接

  1. 在 GitLab 中创建一个测试项目
  2. 添加简单的 .gitlab-ci.yml 文件
  3. 推送代码,查看流水线是否执行

6. 创建示例项目与 CI/CD 流水线

6.1 创建示例项目

  1. 登录 GitLab
  2. 点击 New projectCreate blank project
  3. 项目名称:ci-cd-demo
  4. 可见性:Private 或 Internal
  5. 点击 Create project

6.2 项目结构

创建以下文件结构:

复制代码
ci-cd-demo/

├── .gitlab-ci.yml      # CI/CD 配置文件

├── Dockerfile          # Docker 构建文件

├── docker-compose.yml  # 本地开发配置

├── src/

│   ├── app.js

│   └── package.json

├── tests/

│   └── test.js

└── README.md

6.3 创建应用代码

src/package.json:

json 复制代码
{
  "name": "ci-cd-demo",
  "version": "1.0.0",
  "description": "CI/CD Demo Application",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.0"
  },
  "devDependencies": {
    "jest": "^29.0.0"
  }
}

src/app.js:

javascript 复制代码
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.json({
    message: 'Hello from CI/CD Demo!',
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV || 'development'
  });
});

app.get('/health', (req, res) => {
  res.json({ status: 'healthy' });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

tests/test.js:

javascript 复制代码
const request = require('supertest');
const express = require('express');

const app = express();
app.get('/', (req, res) => {
  res.json({ message: 'Hello from CI/CD Demo!' });
});

describe('GET /', () => {
  it('should return welcome message', async () => {
    const res = await request(app).get('/');
    expect(res.statusCode).toEqual(200);
    expect(res.body.message).toBe('Hello from CI/CD Demo!');
  });
});

6.4 创建 Dockerfile

dockerfile 复制代码
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY src/package*.json ./
RUN npm ci --only=production

# 运行阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY src/ ./
EXPOSE 3000
USER node
CMD ["node", "app.js"]

6.5 创建 docker-compose.yml(开发环境)

yaml 复制代码
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    volumes:
      - ./src:/app/src
    command: npm start

6.6 创建 CI/CD 配置文件

.gitlab-ci.yml:

yaml 复制代码
stages:
  - build
  - test
  - deploy

variables:
  DOCKER_TLS_CERTDIR: ""
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

# 缓存 node_modules 以提高构建速度
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/

# 构建阶段
build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  before_script:
    - docker info
  script:
    - docker build -t $IMAGE_TAG .
    - docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest
  after_script:
    - docker images | grep $CI_REGISTRY_IMAGE
  artifacts:
    paths:
      - Dockerfile
    expire_in: 1 week
  only:
    - main
    - develop

# 测试阶段
test:
  stage: test
  image: node:18-alpine
  before_script:
    - cd src
    - npm ci
  script:
    - npm test
  artifacts:
    when: always
    paths:
      - coverage/
    reports:
      junit: junit.xml
  only:
    - main
    - develop

# 代码质量检查
lint:
  stage: test
  image: node:18-alpine
  before_script:
    - cd src
    - npm ci
  script:
    - npx eslint . --ext .js
    - npx prettier --check .
  only:
    - main
    - develop

# 部署到开发环境
deploy_dev:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - echo "Deploying to development environment..."
    - curl -X POST http://dev-server:8080/deploy \
      -H "Content-Type: application/json" \
      -d '{"image": "'$IMAGE_TAG'", "environment": "dev"}'
  environment:
    name: development
    url: http://dev.example.com
  only:
    - develop

# 部署到生产环境
deploy_prod:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - echo "Deploying to production environment..."
    - curl -X POST http://prod-server:8080/deploy \
      -H "Content-Type: application/json" \
      -d '{"image": "'$IMAGE_TAG'", "environment": "prod"}'
  environment:
    name: production
    url: http://prod.example.com
  only:
    - main
  when: manual

6.7 推送代码并触发流水线

bash 复制代码
# 初始化 Git 仓库
git init
git add .
git commit -m "Initial commit with CI/CD pipeline"

# 添加远程仓库
git remote add origin http://gitlab.local/root/ci-cd-demo.git

# 推送代码
git push -u origin main

6.8 查看流水线执行

  1. 在 GitLab 中进入项目
  2. 点击 CI/CDPipelines
  3. 查看流水线执行状态
  4. 点击具体作业查看日志

7. 高级:使用 Jib 构建 Java 镜像并部署到远程服务器

7.1 准备 Java 项目

pom.xml(Maven 项目):

xml 复制代码
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>java-demo</artifactId>
  <version>1.0.0</version>
  
  <properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <jib-maven-plugin.version>3.4.0</jib-maven-plugin.version>
  </properties>
  
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.7.0</version>
    </dependency>
  </dependencies>
  
  <build>
    <plugins>
      <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>${jib-maven-plugin.version}</version>
        <configuration>
          <to>
            <image>${project.artifactId}:${project.version}</image>
          </to>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

7.2 创建 Java CI/CD 配置

.gitlab-ci-java.yml:

yaml 复制代码
variables:
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

# 缓存 Maven 依赖
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - .m2/repository/

stages:
  - build
  - test
  - package
  - deploy

# 构建项目
maven_build:
  stage: build
  image: maven:3.8-openjdk-11
  script:
    - mvn clean compile
  artifacts:
    paths:
      - target/classes
    expire_in: 1 week

# 运行测试
maven_test:
  stage: test
  image: maven:3.8-openjdk-11
  script:
    - mvn test
  artifacts:
    reports:
      junit: target/surefire-reports/TEST-*.xml

# 使用 Jib 构建镜像
jib_build:
  stage: package
  image: maven:3.8-openjdk-11
  script:
    - mvn compile jib:dockerBuild
  artifacts:
    paths:
      - target/*.jar
    expire_in: 1 week

# 部署到远程服务器
deploy_remote:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client rsync
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
  script:
    - |
      ssh -o StrictHostKeyChecking=no user@remote-server << 'EOF'
        # 在远程服务器上执行
        docker pull ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
        docker stop java-demo || true
        docker rm java-demo || true
        docker run -d \
          --name java-demo \
          -p 8080:8080 \
          --restart always \
          ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
      EOF
  only:
    - main
  when: manual

7.3 配置 SSH 密钥

  1. 在 GitLab 项目中添加部署密钥
  2. 在远程服务器上配置 authorized_keys
  3. 在 GitLab CI/CD 变量中添加 SSH_PRIVATE_KEY

8. 常见问题与解决方案

8.1 WSL2 网络问题

问题: WSL2 IP 地址每次重启都会变化

解决方案:

powershell 复制代码
# Windows PowerShell 脚本
$wslIp = (wsl hostname -I).Trim()
netsh interface portproxy reset
netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=80 connectaddress=$wslIp
netsh interface portproxy add v4tov4 listenport=443 listenaddress=0.0.0.0 connectport=443 connectaddress=$wslIp
netsh interface portproxy add v4tov4 listenport=2222 listenaddress=0.0.0.0 connectport=2222 connectaddress=$wslIp

8.2 Docker 权限问题

问题 : Got permission denied while trying to connect to the Docker daemon socket

解决方案:

bash 复制代码
# 将用户添加到 docker 组
sudo usermod -aG docker $USER
newgrp docker

# 或者修改 socket 权限(不推荐长期使用)
sudo chmod 666 /var/run/docker.sock

8.3 GitLab 启动缓慢

问题: GitLab 首次启动需要很长时间(5-10分钟)

解决方案:

  • 增加 WSL2 内存分配(.wslconfig 中设置 memory=8GB
  • 使用 SSD 硬盘
  • 耐心等待,首次启动确实较慢

8.4 Runner 连接失败

问题: Runner 无法连接到 GitLab

解决方案:

bash 复制代码
# 检查网络连通性
ping gitlab.local
curl -I http://gitlab.local

# 检查防火墙
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# 重新注册 Runner
sudo gitlab-runner unregister --all-runners
sudo gitlab-runner register

8.5 Docker in Docker (DinD) 问题

问题: 流水线中 Docker 命令失败

解决方案:

  1. 确保 Runner 配置中包含 Docker socket 挂载
  2. 使用特权模式
  3. 预拉取 DinD 镜像
bash 复制代码
docker pull docker:dind

8.6 磁盘空间不足

问题: Docker 镜像和容器占用过多空间

解决方案:

bash 复制代码
# 清理无用镜像
docker image prune -a -f

# 清理无用容器
docker container prune -f

# 清理无用卷
docker volume prune -f

# 清理构建缓存
docker builder prune -f

# 查看磁盘使用情况
docker system df

8.7 GitLab 服务异常

问题: GitLab 服务停止响应

解决方案:

bash 复制代码
# 重启 GitLab 容器
cd ~/gitlab
docker compose restart

# 查看日志
docker compose logs --tail=100 gitlab

# 进入容器检查
docker exec -it gitlab gitlab-ctl status
docker exec -it gitlab tail -f /var/log/gitlab/gitlab-rails/production.log

9. 学习资源与进阶建议

9.1 官方文档


附录:常用命令速查表

Docker 命令

命令 说明
docker compose up -d 启动服务
docker compose down 停止服务
docker compose logs -f 查看日志
docker compose ps 查看容器状态
docker exec -it <容器> bash 进入容器
docker system prune -a 清理所有无用资源

GitLab 命令

命令 说明
docker exec -it gitlab gitlab-ctl reconfigure 重新配置 GitLab
docker exec -it gitlab gitlab-ctl restart 重启 GitLab 服务
docker exec -it gitlab gitlab-rake gitlab:backup:create 创建备份
docker exec -it gitlab gitlab-rake gitlab:backup:restore 恢复备份

GitLab Runner 命令

命令 说明
sudo gitlab-runner register 注册 Runner
sudo gitlab-runner verify 验证 Runner
sudo gitlab-runner list 列出 Runner
sudo gitlab-runner restart 重启 Runner
sudo gitlab-runner status 查看 Runner 状态

系统监控命令

命令 说明
docker stats 查看容器资源使用
docker system df 查看 Docker 磁盘使用
df -h 查看磁盘空间
free -h 查看内存使用
htop 查看系统进程
相关推荐
风向决定发型丶2 小时前
K8S中Pod驱逐介绍
docker·容器·kubernetes
Zhu7582 小时前
【软件部署】用docker部署Apache Kafka 集群架构isolated模式带SSL
docker·kafka·apache
qq_396153452 小时前
docker ddns-go 忘记密码
docker·容器·golang
Zhu7582 小时前
【软件部署】用docker部署Apache Kafka 集群架构的isolated模式
docker·kafka·apache
AAA_搬砖达人小郝2 小时前
Docker常用命令(2026最新)
开发语言·docker
无效的名字2 小时前
windows下,怎么压缩Docker Desktop占用的磁盘空间
windows·docker·容器
功德+n11 小时前
Linux下安装与配置Docker完整详细步骤
linux·运维·服务器·开发语言·docker·centos
小敬爱吃饭12 小时前
Ragflow Docker部署及问题解决方案(界面为Welcome to nginx,ragflow上传文件失败,Docker中的ragflow-cpu-1一直重启)
人工智能·python·nginx·docker·语言模型·容器·数据挖掘
木子欢儿12 小时前
Docker Hub 镜像发布指南
java·spring cloud·docker·容器·eureka