Skip to main content

如何将 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 + XYEnter 键。

文件的第一部分控制 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)收到一个类似下面的警告。

所以,如果您遇到了这个错误,请仔细检查 Nginx 配置中的 proxy_pass 和 proxy_redirect 设置。

第二步:配置 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 URLAuthorization callback URL 来体现 HTTPS 的设置。这可能与下图类似:

结语

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