Skip to content

Docker + Jenkins + Nginx实现前端自动化部署

本文将介绍如何使用 Docker、Jenkins 和 Nginx 搭建前端项目的自动化部署流程。

1. 基本概念

Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。

Jenkins

Jenkins 是一个开源的持续集成工具,可以自动化构建、测试和部署软件项目。

Nginx

Nginx 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。

2. 环境准备

2.1 安装 Docker

bash
# 安装 Docker (Ubuntu)
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 启动 Docker
sudo systemctl start docker
sudo systemctl enable docker

# 验证安装
docker --version

2.2 安装 Docker Compose

bash
# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# 验证安装
docker-compose --version

2.3 创建 Docker 网络

bash
# 创建自定义网络,用于容器之间的通信
docker network create frontend-network

3. 配置 Jenkins

3.1 创建 Jenkins 容器

创建 docker-compose.yml 文件:

yaml
version: '3'
services:
  jenkins:
    image: jenkins/jenkins:lts
    container_name: jenkins
    user: root
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - ./jenkins_data:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - frontend-network
    restart: always

networks:
  frontend-network:
    external: true

启动 Jenkins:

bash
docker-compose up -d

3.2 初始化 Jenkins

  1. 访问 http://your-server-ip:8080
  2. 获取初始密码:docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
  3. 安装推荐的插件
  4. 创建管理员账户
  5. 完成初始化

3.3 安装必要的 Jenkins 插件

在 Jenkins 中安装以下插件:

  1. Git Integration
  2. NodeJS Plugin
  3. Pipeline
  4. Docker Pipeline
  5. Blue Ocean (可选,提供更好的 Pipeline UI)

3.4 配置 Node.js 环境

  1. 进入 Jenkins 系统管理 -> 全局工具配置
  2. 找到 NodeJS 安装部分,点击"新增 NodeJS"
  3. 设置名称如 "NodeJS 16",选择对应版本
  4. 保存配置

4. 配置 Nginx

4.1 创建 Nginx 配置文件

创建 nginx.conf 文件:

nginx
server {
    listen 80;
    server_name your-domain.com;

    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

4.2 创建 Nginx 容器

docker-compose.yml 文件中添加 Nginx 服务:

yaml
services:
  # ... Jenkins service ...
  
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/html:/usr/share/nginx/html
      - ./nginx/logs:/var/log/nginx
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      - frontend-network
    restart: always

5. 配置 Jenkinsfile

在前端项目根目录创建 Jenkinsfile

groovy
pipeline {
    agent any
    
    tools {
        nodejs 'NodeJS 16'
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Install Dependencies') {
            steps {
                sh 'npm install'
            }
        }
        
        stage('Lint') {
            steps {
                sh 'npm run lint'
            }
        }
        
        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }
        
        stage('Deploy') {
            steps {
                // 将构建产物复制到 Nginx 目录
                sh 'rm -rf /var/jenkins_home/workspace/nginx/html/*'
                sh 'cp -r dist/* /var/jenkins_home/workspace/nginx/html/'
            }
        }
    }
    
    post {
        success {
            echo 'Build and deployment successful!'
        }
        failure {
            echo 'Build or deployment failed!'
        }
    }
}

6. 配置 GitHub Webhook

6.1 在 Jenkins 中配置

  1. 在 Jenkins 中创建一个新的流水线任务
  2. 配置 GitHub 项目 URL
  3. 勾选 "GitHub hook trigger for GITScm polling"
  4. 流水线定义选择 "Pipeline script from SCM"
  5. 设置 SCM 为 Git,输入仓库 URL
  6. 指定分支为 */main*/master
  7. 脚本路径填写 Jenkinsfile
  8. 保存配置

6.2 在 GitHub 中配置 Webhook

  1. 进入 GitHub 仓库设置 -> Webhooks
  2. 添加 webhook,URL 填写 http://your-server-ip:8080/github-webhook/
  3. 内容类型选择 application/json
  4. 选择触发事件,通常选择 "Just the push event"
  5. 保存 webhook

7. 完整的部署流程

7.1 流程说明

  1. 开发者提交代码到 GitHub 仓库
  2. GitHub 通过 webhook 触发 Jenkins 构建
  3. Jenkins 拉取最新代码
  4. Jenkins 安装依赖并构建项目
  5. Jenkins 将构建产物部署到 Nginx 目录
  6. Nginx 提供静态资源服务,用户可以访问最新的前端应用

7.2 手动触发部署

  1. 登录 Jenkins 控制台
  2. 找到对应的流水线任务
  3. 点击 "立即构建" 按钮
  4. 查看构建进度和结果

8. 进阶配置

8.1 多环境部署

修改 Jenkinsfile 支持不同环境的部署:

groovy
pipeline {
    agent any
    
    tools {
        nodejs 'NodeJS 16'
    }
    
    parameters {
        choice(name: 'ENVIRONMENT', choices: ['development', 'staging', 'production'], description: 'Deployment Environment')
    }
    
    stages {
        // ... previous stages ...
        
        stage('Build') {
            steps {
                script {
                    if (params.ENVIRONMENT == 'production') {
                        sh 'npm run build:prod'
                    } else if (params.ENVIRONMENT == 'staging') {
                        sh 'npm run build:staging'
                    } else {
                        sh 'npm run build:dev'
                    }
                }
            }
        }
        
        stage('Deploy') {
            steps {
                script {
                    def deployPath = "/var/jenkins_home/workspace/nginx/html/${params.ENVIRONMENT}"
                    sh "mkdir -p ${deployPath}"
                    sh "rm -rf ${deployPath}/*"
                    sh "cp -r dist/* ${deployPath}/"
                }
            }
        }
    }
}

8.2 Docker 镜像部署

创建 Dockerfile:

dockerfile
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

修改 Jenkinsfile:

groovy
stage('Build Docker Image') {
    steps {
        sh 'docker build -t frontend-app:${BUILD_NUMBER} .'
        sh 'docker tag frontend-app:${BUILD_NUMBER} frontend-app:latest'
    }
}

stage('Deploy Docker Container') {
    steps {
        sh 'docker stop frontend-container || true'
        sh 'docker rm frontend-container || true'
        sh 'docker run -d --name frontend-container -p 80:80 --network frontend-network frontend-app:latest'
    }
}

9. 常见问题及解决方案

9.1 Jenkins 权限问题

问题:Jenkins 无法访问 Docker 或文件系统 解决:确保 Jenkins 容器使用 root 用户或将 jenkins 用户添加到 docker 组

bash
# 添加 Jenkins 用户到 docker 组
sudo usermod -aG docker jenkins
# 重启 Jenkins
sudo systemctl restart jenkins

9.2 Nginx 配置问题

问题:网站无法访问或 404 错误 解决:检查 Nginx 配置文件和目录权限

bash
# 检查 Nginx 配置
docker exec nginx nginx -t
# 如果有错误,修复后重新加载配置
docker exec nginx nginx -s reload

9.3 构建失败问题

问题:前端构建失败 解决:检查 Node.js 版本、依赖和构建脚本

bash
# 在 Jenkins 构建环境中执行
node -v
npm -v
# 确保版本符合项目要求

10. 安全性考虑

  1. Jenkins 安全配置

    • 使用 HTTPS
    • 设置 Jenkins 安全域
    • 限制权限,遵循最小权限原则
  2. Docker 安全

    • 定期更新 Docker 和镜像
    • 不要在容器中运行特权操作
    • 使用非 root 用户运行容器
  3. Nginx 安全

    • 配置 HTTPS
    • 添加安全头信息
    • 关闭不必要的服务

总结

使用 Docker + Jenkins + Nginx 实现前端自动化部署,可以显著提高开发效率,减少人为错误,实现持续集成和持续部署。该方案具有灵活性和可扩展性,适用于中小型前端项目的自动化部署需求。