如何将 Nginx 配置为 Jenkins 的反向代理
作者:josh.reichardt
导语
默认情况下,Jenkins自带侦听端口8080的内置 Web 服务器。如果您想运行私人 Jenkins 实例,或您只想快速启动一些东西,并不在乎其安全性,使用内置服务器很方便。但是如果您需要将真实的生产数据发送至主机,最好使用更安全的 Web 服务器来处理流量,例如 Nginx。
本文将详细介绍如何使用 Nginx Web 服务器做 Jenkins 实例的反向代理,以此包装您的站点。本教程需要您熟悉 Linux 命令,且已安装了 Jenkins 和 Ubuntu 20.04。
如果您还没有安装 Jenkins,您可以在本教程之后的部分中安装。
前期准备
本教程为使用 Ubuntu 20.04 的用户准备。在开始前,您还需要在系统上设置一个具有 sudo 权限的非 root 用户账户。除此之外,让 SSL 保护您的 Jenkins 实例也十分重要。如果您的实例在网络中可见,您可以用 Let’s Encrypt 保护它。
第一步:配置 Nginx
近年来, Nginx 因其速度与灵活性成为了最受欢迎的 Web 服务器之一,也是我们应用程序的理想之选。
编辑配置
接下来,您需要编辑 Nginx 的配置文件。以下例子用到了 nano
。
$ sudo nano etc/nginx/sites-enabled/default
以下是一个最终配置文件的示例。各个部分都在接下来进行了细分,且配有简要说明。您可以直接更新或替换现有的配置文件,但您可能需要先备份它们。
server {23
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name jenkins.domain.com;
access_log /var/log/nginx/jenkins.access.log;
location / {
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_pass http://localhost:8080;
proxy_read_timeout 90;
proxy_redirect http://localhost:8080 https://jenkins.domain.com;
}
...
}
您需要将 server_name 和 proxy_redirect
这两行更新为您自己的域名。除此之外文件中还存在一些 Nginx 魔法,使 Nginx 读取请求并在响应端重写,以此确保反向代理在正常工作。
保存并关闭文件。如果您也使用 nano
,您可以按 Ctrl + X
,Y
和 Enter
键。
文件的第一部分控制 Nginx 服务器监听端口80(HTTP 默认)的所有请求,并将它们重定向至 HTTPS。
...
server {
listen 80;
return 301 https://$host$request_uri;
}
...
这样,代理就完成了。它基本上会接收所有传入的请求,将它们代理到绑定了端口8080或正在监听它的 Jenkins 实例中。
...
location / {
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_pass http://localhost:8080;
proxy_read_timeout 90;
proxy_redirect http://localhost:8080 https://jenkins.domain.com;
}
...
需指出的是,如果您没有解析到 Jenkins 服务器的域名,且不进行修改,以上 proxy_redirect 语句将无法正常发挥功能,请您记住这一点。同样,如果 proxy_pass 配置有误(如末尾多加了一道斜杠),您会在 Jenkins 配置界面(Configuration page)收到一个类似下面的警告。

第二步:配置 Jenkins
为了让 Jenkins 协同 Nginx 工作,我们需要更新 Jenkins 配置,让它只侦听 localhost 地址,而不是所有的(0.0.0.0),以此确保流量能被合理处理。这个步骤很重要,因为如果 Jenkins 还在侦听所有的地址,它就可以通过其原始端口(8080)被访问。我们将通过修改/etc/default/jenkins配置文件来进行调整。
$ sudo nano /etc/default/jenkins
找到 JENKINS\_ARGS
行,将它更新为如下所示:
JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpListenAddress=127.0.0.1 --httpPort=$HTTP_PORT -ajp13Port=$AJP_PORT"
注意,必须添加或修改 –httpListenAddress=127.0.0.1 设置。
然后重启 Jenkins 和 Nginx。
$ sudo service jenkins restart
$ sudo service nginx restart
现在,您应该能使用 HTTPS 访问您的域,并且 Jenkins 站点可以得到安全服务。
可选:更新 OAuth URL
如果您使用 GitHub 或其他 OAuth 插件进行身份验证,这时它可能已经失效。例如,当尝试访问某个 URL 时,您将收到一个 “无法打开页面(Failed to open page)”的提示。其 URL 类似于:http://jenkins.domain.com:8080/securityRealm/finishLogin?code=random-string
要解决此问题,您需要更新一些 Jenkins 以及 OAuth 插件中的设置。首先在 Jenkins GUI 中更新 Jenkins URL。您可以在 Jenkins -> Manage Jenkins -> Configure System -> Jenkins Location 菜单中找到它。
将 Jenkins URL 更新为 HTTPS - https://jenkins.domain.com/

然后,使用外部供应商更新您的 OAuth 设置。以下示例适用于 GitHub。在 Github中,您可以在站点的 Settings -> Applications -> Developer applications 下找到。
其中应该有一个 Jenkins 的条目。更新 Homepage URL 和 Authorization callback URL 来体现 HTTPS 的设置。这可能与下图类似:

结语
剩下要做的,就是验证一切是否能正常运行。如上所述,您现在应该能通过 HTTP 或 HTTPS 浏览到新配置的 URL - jenkins.domain.com,被重新定向到安全站点,并能看到一些站点信息。这些信息中包括您新更新的 SSL 设置。但如果您没有通过 DNS 使用主机名,重新定向可能无法正常按预期进行。在这种情况下,您需要修改 Nginx 配置文件中的 proxy_pass 部分。