基于Docker + Jenkins + GitLab CI 的DevOps自动化流水线搭建指南

Luna60
Luna60 2026-03-04T00:15:13+08:00
0 0 0

ather# 基于Docker + Jenkins + GitLab CI 的DevOps自动化流水线搭建指南

引言

在现代软件开发中,DevOps已经成为提升团队交付效率和产品质量的关键实践。一个完整的CI/CD流水线能够自动化代码构建、测试、部署等环节,显著减少人工干预,提高开发效率。本文将详细介绍如何基于Docker容器化技术、Jenkins持续集成平台和GitLab CI流程管理工具,构建一个完整的DevOps自动化流水线。

一、环境准备与架构概述

1.1 环境要求

在开始搭建之前,我们需要准备以下环境:

  • 操作系统:Ubuntu 20.04 LTS 或 CentOS 7+
  • Docker版本:Docker 20.10+
  • Jenkins版本:Jenkins 2.346+
  • GitLab CI:GitLab 15.0+
  • 内存:至少4GB RAM
  • 存储:至少20GB可用空间

1.2 架构设计

我们的自动化流水线架构包含以下组件:

[代码仓库] → [GitLab CI] → [Jenkins] → [Docker容器] → [部署环境]

该架构的优势在于:

  • GitLab CI负责代码变更触发
  • Jenkins处理复杂的构建和测试流程
  • Docker提供一致的部署环境
  • 自动化测试确保代码质量

二、Docker容器化部署环境搭建

2.1 Docker基础环境配置

首先,我们需要在服务器上安装Docker:

# 更新系统包
sudo apt update

# 安装Docker依赖
sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release

# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 添加Docker仓库
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.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 update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 启动并启用Docker服务
sudo systemctl start docker
sudo systemctl enable docker

# 将当前用户添加到docker组
sudo usermod -aG docker $USER

2.2 创建Docker镜像构建脚本

为了实现容器化部署,我们需要创建一个Dockerfile:

# Dockerfile
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

# 复制package.json和package-lock.json
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# 更改文件所有者
USER nextjs

# 启动应用
CMD ["npm", "start"]

2.3 构建和推送Docker镜像

创建一个自动化构建脚本:

#!/bin/bash
# build.sh

# 设置变量
IMAGE_NAME="myapp"
IMAGE_TAG="latest"
REGISTRY="registry.example.com"

# 构建镜像
docker build -t $IMAGE_NAME:$IMAGE_TAG .

# 标记镜像
docker tag $IMAGE_NAME:$IMAGE_TAG $REGISTRY/$IMAGE_NAME:$IMAGE_TAG

# 推送镜像到仓库
docker push $REGISTRY/$IMAGE_NAME:$IMAGE_TAG

echo "Docker镜像构建并推送完成"

三、Jenkins持续集成环境配置

3.1 Jenkins安装与初始化

# 安装Jenkins
sudo apt update
sudo apt install openjdk-11-jdk
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt update
sudo apt install jenkins

# 启动Jenkins服务
sudo systemctl start jenkins
sudo systemctl enable jenkins

# 查看Jenkins初始密码
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

3.2 Jenkins插件安装

Jenkins需要安装以下关键插件:

# 通过Jenkins UI安装插件
# 1. 系统管理 -> 管理插件
# 2. 可选插件标签页
# 3. 搜索并安装以下插件:
#    - Git plugin
#    - Docker Pipeline
#    - Docker Commons
#    - Pipeline: Declarative Agent API
#    - Pipeline: Groovy
#    - Pipeline: Stage View
#    - GitHub
#    - GitLab

3.3 Jenkins Pipeline配置

创建一个Jenkinsfile来定义CI/CD流程:

// Jenkinsfile
pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = 'registry.example.com'
        IMAGE_NAME = 'myapp'
        IMAGE_TAG = "${env.BUILD_NUMBER}"
        NODE_VERSION = '16'
    }
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://gitlab.example.com/myproject.git'
            }
        }
        
        stage('Setup Node.js') {
            steps {
                sh '''
                    npm install -g npm@latest
                    npm install -g yarn
                '''
            }
        }
        
        stage('Install Dependencies') {
            steps {
                sh 'yarn install'
            }
        }
        
        stage('Run Tests') {
            steps {
                sh 'yarn test'
            }
            post {
                always {
                    publishTestResults(testResults: '**/test-results.xml')
                }
            }
        }
        
        stage('Build Docker Image') {
            steps {
                script {
                    docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}")
                }
            }
        }
        
        stage('Push Docker Image') {
            steps {
                script {
                    docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-registry-credentials') {
                        docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push()
                    }
                }
            }
        }
        
        stage('Deploy to Staging') {
            steps {
                script {
                    // 部署到测试环境
                    sh '''
                        docker stop myapp-staging || true
                        docker rm myapp-staging || true
                        docker run -d --name myapp-staging \
                            -p 3001:3000 \
                            ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
                    '''
                }
            }
        }
        
        stage('Deploy to Production') {
            when {
                branch 'main'
            }
            steps {
                script {
                    // 部署到生产环境
                    sh '''
                        docker stop myapp-prod || true
                        docker rm myapp-prod || true
                        docker run -d --name myapp-prod \
                            -p 3000:3000 \
                            ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
                    '''
                }
            }
        }
    }
    
    post {
        success {
            echo 'Pipeline completed successfully!'
            slackSend channel: '#deployments', message: "✅ Build ${env.BUILD_NUMBER} successful for ${env.JOB_NAME}"
        }
        failure {
            echo 'Pipeline failed!'
            slackSend channel: '#deployments', message: "❌ Build ${env.BUILD_NUMBER} failed for ${env.JOB_NAME}"
        }
    }
}

四、GitLab CI流程管理

4.1 GitLab CI配置文件

在项目根目录创建.gitlab-ci.yml文件:

# .gitlab-ci.yml
stages:
  - test
  - build
  - deploy

variables:
  DOCKER_REGISTRY: registry.example.com
  IMAGE_NAME: myapp
  DOCKER_IMAGE: $DOCKER_REGISTRY/$IMAGE_NAME
  NODE_VERSION: 16

before_script:
  - echo "Starting GitLab CI pipeline"
  - npm install -g npm@latest
  - npm install -g yarn

test:
  stage: test
  image: node:$NODE_VERSION
  script:
    - yarn install
    - yarn test
    - yarn lint
  artifacts:
    reports:
      junit: test-results.xml
    paths:
      - coverage/
  only:
    - main
    - develop

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $DOCKER_IMAGE:$CI_COMMIT_SHA .
    - docker push $DOCKER_IMAGE:$CI_COMMIT_SHA
  only:
    - main

deploy_staging:
  stage: deploy
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker stop myapp-staging || true
    - docker rm myapp-staging || true
    - docker run -d --name myapp-staging -p 3001:3000 $DOCKER_IMAGE:$CI_COMMIT_SHA
  environment:
    name: staging
    url: https://staging.example.com
  only:
    - main

deploy_production:
  stage: deploy
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker stop myapp-prod || true
    - docker rm myapp-prod || true
    - docker run -d --name myapp-prod -p 3000:3000 $DOCKER_IMAGE:$CI_COMMIT_SHA
  environment:
    name: production
    url: https://prod.example.com
  only:
    - main
  when: manual

4.2 GitLab CI环境变量配置

在GitLab项目设置中配置以下环境变量:

# 环境变量配置
CI_REGISTRY_USER=gitlab-ci-token
CI_REGISTRY_PASSWORD=your-gitlab-token
DOCKER_REGISTRY=registry.example.com

五、自动化测试集成

5.1 测试框架配置

配置Jest测试框架:

// package.json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "lint": "eslint src/**/*.js"
  },
  "devDependencies": {
    "jest": "^29.0.0",
    "eslint": "^8.0.0",
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0"
  }
}

5.2 Jest配置文件

// jest.config.js
module.exports = {
  testEnvironment: 'node',
  collectCoverageFrom: [
    'src/**/*.{js,jsx}',
    '!src/**/*.test.{js,jsx}',
    '!src/index.js'
  ],
  coverageDirectory: 'coverage',
  coverageReporters: ['text', 'lcov'],
  testMatch: [
    '**/__tests__/**/*.{js,jsx}',
    '**/test/**/*.{js,jsx}',
    '**/?(*.)+(spec|test).{js,jsx}'
  ],
  setupFilesAfterEnv: ['<rootDir>/src/test/setup.js'],
  verbose: true
};

5.3 测试示例

// src/__tests__/app.test.js
const request = require('supertest');
const app = require('../app');

describe('API Tests', () => {
  test('should return hello world', async () => {
    const response = await request(app).get('/');
    expect(response.status).toBe(200);
    expect(response.text).toBe('Hello World!');
  });

  test('should handle POST request', async () => {
    const response = await request(app)
      .post('/users')
      .send({ name: 'John Doe', email: 'john@example.com' });
    
    expect(response.status).toBe(201);
    expect(response.body).toHaveProperty('name', 'John Doe');
  });
});

六、安全性和最佳实践

6.1 安全配置

# 配置Docker安全设置
sudo nano /etc/docker/daemon.json

{
  "userland-proxy": false,
  "iptables": true,
  "ip-forward": false,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

# 重启Docker服务
sudo systemctl restart docker

6.2 密钥管理

使用Jenkins Credentials插件管理敏感信息:

pipeline {
    agent any
    environment {
        DOCKER_REGISTRY_CREDENTIALS = credentials('docker-registry-credentials')
    }
    stages {
        stage('Deploy') {
            steps {
                script {
                    docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-registry-credentials') {
                        docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push()
                    }
                }
            }
        }
    }
}

6.3 监控和日志

配置日志收集和监控:

# 创建日志收集脚本
#!/bin/bash
# monitor.sh

# 收集Docker容器日志
docker logs myapp-staging > /var/log/myapp-staging.log 2>&1 &

# 监控容器资源使用情况
docker stats --no-stream myapp-staging > /var/log/container-stats.log 2>&1 &

# 设置日志轮转
sudo nano /etc/logrotate.d/myapp

/var/log/myapp-staging.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
}

七、性能优化和故障排除

7.1 构建优化

# 优化Docker构建
# Dockerfile优化版本
FROM node:16-alpine

# 使用多阶段构建
FROM node:16-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# 复制构建产物
COPY . .
RUN npm run build

# 生产环境镜像
FROM node:16-alpine AS production
WORKDIR /app

# 复制依赖和构建产物
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist

EXPOSE 3000
CMD ["npm", "start"]

7.2 故障排除

常见问题及解决方案:

# 检查Docker服务状态
sudo systemctl status docker

# 查看Docker容器日志
docker logs myapp-staging

# 检查网络连接
docker network ls
docker network inspect bridge

# 清理Docker资源
docker system prune -a
docker volume prune
docker image prune

八、监控和告警

8.1 Jenkins监控

// 添加监控脚本
pipeline {
    agent any
    stages {
        stage('Health Check') {
            steps {
                script {
                    def healthCheck = sh(
                        script: 'curl -f http://localhost:3000/health || exit 1',
                        returnStatus: true
                    )
                    if (healthCheck != 0) {
                        error 'Health check failed'
                    }
                }
            }
        }
    }
}

8.2 集成监控工具

# 配置Prometheus监控
# prometheus.yml
scrape_configs:
  - job_name: 'jenkins'
    static_configs:
      - targets: ['localhost:8080']
  - job_name: 'docker'
    static_configs:
      - targets: ['localhost:9323']

结论

通过本文的详细介绍,我们成功搭建了一个完整的基于Docker + Jenkins + GitLab CI的DevOps自动化流水线。这个流水线具备以下特点:

  1. 自动化程度高:从代码提交到部署的全流程自动化
  2. 环境一致性:使用Docker确保开发、测试、生产环境的一致性
  3. 质量保障:集成自动化测试确保代码质量
  4. 安全可靠:包含安全配置和密钥管理
  5. 易于维护:清晰的架构设计和文档化

这个自动化流水线能够显著提升团队的交付效率,减少人为错误,提高软件质量和发布频率。在实际使用中,可以根据具体需求进一步优化和扩展功能。

通过持续改进和迭代,这个DevOps流水线将成为团队数字化转型的重要基础设施,为业务发展提供强有力的技术支撑。

相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000