設定Jenkins伺服器構建Spring Boot應用程式 - Marcus

banq發表於2022-03-05

在本教程中,我們將完成使用 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配置點選標題見原文
 

相關文章