设置Jenkins服务器构建Spring Boot应用程序 - Marcus


在本教程中,我们将完成使用 Docker 和 Docker Compose 设置 Jenkins 服务器的步骤,以便能够从 GitHub 存储库构建 Spring Boot 应用程序。
 
Jenkins 配置即代码 (JCasC)
我们将从查看 Jenkins 配置即代码 (JCasC) 部分开始,因此我们将克隆存储库https://github.com/mjovanc/medium-jenkins-casc
 
那么为什么我们需要一个叫做Jenkins配置为代码的东西呢?想象一下这样的场景:你需要手动安装Jenkins服务器,并且必须在Jenkins的Web UI中输入配置。如果服务器出了问题,我们需要用Jenkins复制一个新的服务器怎么办?那么我们就需要在Web UI中再次手动添加,并手动安装插件。如果你有一个较大的项目,这是需要很长时间的事情,并可能导致你正在构建的产品的交付出现很多问题。
实际上,我曾试图了解JCasC,但要找到好的教程是有问题的,要彻底了解做这件事所需的每一步。所以我的目标是以基本的方式向你展示你需要的东西。
 
所以在这个Git库中,我们将首先打开config/jenkins.yml文件:

jenkins:
  systemMessage: "Welcome to Jenkins for the Spring Project!"
  numExecutors: 4
  mode: NORMAL
  scmCheckoutRetryCount: 3
  labelString: "mjovanc"  # we need to specify something here that we will define in our pipeline jobs, choose whatever name you want

  primaryView:
    all:
      name: All

tool:
  jdk:
    installations:
    - name: "OpenJDK 16"
      properties:
      - installSource:
          installers:
          - zip:
              subdir: "/var/jenkins_home/tools/hudson.model.JDK/OpenJDK_16/jdk-16.0.1"
              url: "https://download.java.net/java/GA/jdk16.0.1/7147401fd7354114ac51ef3e1328291f/9/GPL/openjdk-16.0.1_linux-x64_bin.tar.gz"

jobs:
  - script: |
      job('seedjob-mjovanc') {
        description('Set up all jobs')
          
        scm {
          git {
            branches('*/master')
            remote {
              credentials('mjovanc-jenkins-key')
              url('git@github.com:mjovanc/medium-mjovanc-job-dsl.git')
            }
          }
        }
        steps {
          dsl {
            external('*.groovy')
            removeAction('DELETE')
            ignoreExisting(ignore = false)
            removeViewAction('DELETE')
          }
        }
        triggers {
          cron('@midnight')
        }
      }
 

 
这里有两个值得指出的主要部分。我们有Jenkins、tools和job:

  1. jenkins是服务器的一般配置,比如我们需要多少个执行器等等。
  2. tools是关于我们需要安装什么样的额外软件,以便能够构建我们的软件。我加入了OpenJDK16,因为Jenkins使用的OpenJDK11不能工作。
  3. jobs部分定义了在启动Jenkins时,最初应该存在什么样的作业。所以我们在这里添加了一个Groovy脚本来设置一个作业,这个作业将在每一个午夜从外部资源库中获取更多的Groovy DSL作业,你可以从这里克隆:https://github.com/mjovanc/medium-mjovanc-job-dsl。因此,如果你对外部仓库中的DSL作业做了任何改动,它就会在午夜时分改变。

  
现在看看Dockerfile:
FROM jenkins/jenkins:lts-jdk11
USER root

COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh << /usr/share/jenkins/ref/plugins.txt

RUN apt-get update -y
RUN apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common docker.io
RUN docker --version

RUN usermod -aG docker jenkins

USER jenkins

  

这里我们定义我们自己的Dockerfile,因为我们需要在我们的Docker容器内安装Docker,以便它能够在Jenkins上构建Docker镜像。
我们的docker-compose.yml文件:

version: '3.7'

services:
  jenkins:
    build: .
    privileged: true
    user: root
    restart: on-failure:10
    ports:
      - 8080:8080
    container_name: mjovanc-jenkins
    volumes:
      - ./:/jcasc
      - ~/apps/jenkins:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - CASC_JENKINS_CONFIG=/jcasc/configs/jenkins.yml
      - JENKINS_OPTS='--prefix=/'
    logging:
      driver: 'json-file'
      options:
        max-file: '3'
        max-size: '10m'

这个文件定义了我们将从我们自己的Docker文件中构建,并将服务名称设为jenkins。我们还映射了一些所需的卷,如所有的JCasC配置和来自主机操作系统的Docker UNIX套接字,以便能够在Docker容器内使用。
我们还设置了两个环境变量。CASC_JENKINS_CONFIG,它指向我们定义的jenkins.yml文件,所以Jenkins将知道它应该在启动时加载该文件。
我们还设置了一个前缀,Jenkins应该在URL上使用JENKINS_OPTS。所以URL将直接位于“/”。
在Jenkins的Web UI中,我们首先设置好Jenkins服务器后,需要运行一些代码。我们进入脚本控制台并输入:

def pluginList = new ArrayList(Jenkins.instance.pluginManager.plugins)
pluginList.sort { it.getShortName() }.each{
  plugin -> 
    println ("${plugin.getDisplayName()} (${plugin.getShortName()}): ${plugin.getVersion()}")
}

这将给我们一个已安装的插件的长列表,所以我们可以在plugins.txt文件中定义,这样下次我们需要设置一个新的Jenkins服务器时,我们就可以在运行docker-compose时从该文件中加载。
 
接下来你需要做的是把文件名your-domain.com改成你自己的。为了设置NGINX配置,需要有这个文件,因为我们的NGINX将充当Jenkins服务器的反向代理。该文件看起来是这样的。

upstream jenkins {
  keepalive 32; # keepalive connections
  server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
}

server {
    listen 80;
    listen [::]:80;
    return 301 https://$host$request_uri;
}

server {
    server_name your-domain.com; # managed by Certbot

   # this is the jenkins web root directory
    # (mentioned in the /etc/default/jenkins file)
    root            /root/apps/jenkins/war/;

    access_log      /var/log/nginx/jenkins.access.log;
    error_log       /var/log/nginx/jenkins.error.log;

    # pass through headers from Jenkins that Nginx considers invalid
    ignore_invalid_headers off;

    location ~
"^/static/[0-9a-fA-F]{8}\/(.*)$" {
        # rewrite all static files into requests to the root
        # E.g /static/12345678/css/something.css will become /css/something.css
        rewrite
"^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
    }

    location /userContent {
        # have nginx handle all the static requests to userContent folder
        # note : This is the $JENKINS_HOME dir
        root /root/apps/jenkins/;
        if (!-f $request_filename){
            # this file does not exist, might be a directory or a
/**view** url
            rewrite (.*) /$1 last;
            break;
        }
        sendfile on;
    }

   location / {
        sendfile off;
        proxy_pass         http://jenkins;
        proxy_redirect     default;
        proxy_http_version 1.1;

        # Required for Jenkins websocket agents
        proxy_set_header   Connection        $connection_upgrade;
        proxy_set_header   Upgrade           $http_upgrade;

        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_max_temp_file_size 0;

        this is the maximum upload size
        client_max_body_size       10m;
        client_body_buffer_size    128k;

        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;
        proxy_buffering            off;
        proxy_request_buffering    off; # Required for HTTP CLI commands
        proxy_set_header Connection ""; # Clear for keepalive
    }


    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

 
你需要在该文件中改成你自己的域名,我将演示的下一个文件将使用该文件在安装NGINX服务器后复制到其位置。这就是脚本setup_start.sh。

#!/bin/bash

# Use this file to setup the environment for Jenkins
# and run the server

# Variables
JENKINS_DOMAIN=<your domain> # this domain should be the name of your nginx configuration file as well
NGINX_SSL_EMAIL=<your email>

# Installing necessary dependencies
sudo apt-get update -y
sudo apt-get install -y \
    ca-certificates \
    curl \
    gnupg \
    lsb-release \
    nginx \
    certbot

apt-get install -y python3-certbot-nginx

# Setup NGINX
sudo mkdir -p /var/log/nginx/jenkins
sudo cp $JENKINS_DOMAIN /etc/nginx/sites-available/$JENKINS_DOMAIN
sudo ln -s /etc/nginx/sites-available/$JENKINS_DOMAIN /etc/nginx/sites-enabled/

# SSL
sudo certbot --nginx -d $JENKINS_DOMAIN --non-interactive --agree-tos -m $NGINX_SSL_EMAIL

# Reload
nginx -t && nginx -s reload

# Add Docker’s official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Setup the stable repository
echo \
  "deb [arch=$(dpkg --print-architecture) 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

# Install Docker Engine
sudo apt-get update -y
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose

# Start Docker and orchestrate
docker-compose up -d

这个脚本是为了安装NGINX、Certbot、Docker和Docker Compose的所有必要依赖,然后运行Jenkins。你需要在顶部编辑这个文件,将JENKINS_DOMAIN和NGINX_SSL_EMAIL的值改为你自己的域名和电子邮件地址。
 
我认为你已经建立了一个Linux实例(VM),并将你自己的域名用DNS A记录指向了它。
 
如果你想看到一些输出,你可以在docker-compose启动后删除-d标志。这在最初使用时可能很好,因为我们可以跟踪协调的过程,以发现我们是否犯了任何错误。然而,当你完成后,你可以再把它加回来。
 
现在我们已经准备好启动应用程序了,启动应用程序的方法是首先用以下命令为文件setup_start.sh设置可执行权限。

chmod +x ./setup_start.sh
./setup_start.sh

很好! 现在它已经启动并运行了!
  

现在我们只需要对Jenkins做最后的润色,使它与配置部分一起工作。我们首先需要生成一个我们将使用的SSH密钥。使用下面的命令来生成一个。
ssh-keygen -t rsa
按照CLI的指示,选择一个合适的名字,也许是jenkins-github?然后我们就需要把这个密钥添加到我们电脑上的ssh代理中。

eval "$(ssh-agent -s)"
ssh-add <path to your ssh key>

现在我们要去GitHub账户,在这里添加我们的公共(.pub)SSH密钥的内容https://github.com/settings/keys。
最后,对于JCasC部分,我们需要在Jenkins Web UI中做一个手动步骤,添加作业加载到Jenkins时需要的SSH凭证。如果资源库是公开的,你可以跳过这一步,删除DSL作业中的credential()方法。需要注意的是,我们需要在配置文件中添加相应的凭证名称,请看jenkins.yml里面的作业是怎样的。
 
有关Jenkins DSL jobs配置点击标题见原文