在本教程中,我们将完成使用 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:
- jenkins是服务器的一般配置,比如我们需要多少个执行器等等。
- tools是关于我们需要安装什么样的额外软件,以便能够构建我们的软件。我加入了OpenJDK16,因为Jenkins使用的OpenJDK11不能工作。
- 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配置点击标题见原文