# Nginx：向外代理暴露Web服务

> 如何在使用 Nginx 对外代理、转发、暴露 Web 服务？
---

Pigsty 在 [**INFRA节点**](/zh/docs/node#infra节点)上默认会安装 [**Nginx**](/zh/docs/infra#nginx) 作为 Web 服务代理。（单机安装时，本机默认也是一个 INFRA节点 ）

Nginx 是 Pigsty 所有 WebUI 类服务的访问入口，默认使用管理节点 `80/443` 端口。

Pigsty 提供了一个全局配置变量 [`infra_portal`](/zh/docs/reference/param#infra_portal)，用于配置 Nginx 的代理规则，以及对应的上游服务。

如果您直接通过端口访问 Nginx，默认访问的是 `h.pigsty`，即 Pigsty 文件系统首页。（`/www/` 目录）。
因为 Nginx 通过同一个端口对外提供多个服务，因此必须通过域名进行区分（浏览器的 `HOST` 首部），所以在默认情况下，Nginx 只会对外暴露 `带有 `domain` 参数的

默认情况下，Nginx 除了 `home` （文件系统，软件源）之外，还对外暴露 `grafana`，`prometheus`，`alertmanager` 三项可观测性服务：

```yaml
infra_portal:  # domain names and upstream servers
  home         : { domain: h.pigsty }
  grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
  prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9090" }
  alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9093" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }
  #minio        : { domain: sss.pigsty  ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
```


------

## 如何配置 Nginx 代理？

Pigsty 自带的配置模板 [`demo.yml`](https://github.com/Vonng/pigsty/blob/v2.7.0/files/pigsty/demo.yml) 配置文件，作为一个参考，额外对外部暴露了一些 Web 服务：

```yaml
    infra_portal:                     # domain names and upstream servers
      home         : { domain: h.pigsty }
      grafana      : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
      prometheus   : { domain: p.pigsty ,endpoint: "${admin_ip}:9090" }
      alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9093" }
      blackbox     : { endpoint: "${admin_ip}:9115" }
      loki         : { endpoint: "${admin_ip}:3100" }

      minio        : { domain: sss.pigsty  ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
      postgrest    : { domain: api.pigsty  ,endpoint: "127.0.0.1:8884" }
      pgadmin      : { domain: adm.pigsty  ,endpoint: "127.0.0.1:8885" }
      pgweb        : { domain: cli.pigsty  ,endpoint: "127.0.0.1:8886" }
      bytebase     : { domain: ddl.pigsty  ,endpoint: "127.0.0.1:8887" }
      jupyter      : { domain: lab.pigsty  ,endpoint: "127.0.0.1:8888", websocket: true }
      gitea        : { domain: git.pigsty  ,endpoint: "127.0.0.1:8889" }
      wiki         : { domain: wiki.pigsty ,endpoint: "127.0.0.1:9002" }
      noco         : { domain: noco.pigsty ,endpoint: "127.0.0.1:9003" }
      supa         : { domain: supa.pigsty ,endpoint: "10.10.10.10:8000", websocket: true }
```

这里不难看出，每一条记录都有一个独一无二的 `name` 作为 `key`，一个配置字典作为 `value`。在配置字典中，目前有以下四个可用配置项：
- `endpoint`：必填，指定上游服务的地址，可以是 `IP:PORT` 或者 `DOMAIN:PORT`。
  - 在此参数中，可以使用 `${admin_ip}` 占位符，Pigsty会填入 [`admin_ip`](/zh/docs/reference/param#admin_ip) 的值。
- `domain`：可选，指定代理的域名，如果不填写，则 Nginx 不会对外暴露此服务。
  - 对于那些需要知道 endpoint 地址，但不想对外暴露的服务（例如 Loki, Blackbox Exporter），可以不填写 `domain`。
- `scheme`：可选，指定转发时的协议（`http`/`https`），留空则默认使用 http
  - 对于那些强制要求 HTTPS 访问的上游 Web 服务（例如 MinIO 管理界面），需要指定 `scheme: https`。
- `websocket`：可选，指定是否开启 WebSocket，留空则默认关闭。
  - 类似 Grafana、Jupyter 等需要 WebSocket 的服务需要设置为 `true` 方能正常工作。

因此，如果您需要新增一个通过 Nginx 暴露的 Web 服务，首先需要在 `infra_portal` 中添加相应地记录，然后执行剧本生效：

```bash
./infra.yml -t nginx_config    # 重新生成 Nginx 配置文件
./infra.yml -t nginx_cert      # 重新签发自签名 HTTPS 证书，囊括新增的域名
./infra.yml -t nginx_launch    # 重启 Nginx 以使配置生效（如果您不希望出现中断，手动使用 nginx -s reload）
```

如果您始终通过 Pigsty 管理 Nginx 配置，也可以直接使用以下任务重新初始化 Nginx 配置：

```bash
./infra.yml -t nginx           # 直接重新初始化 Nginx 至描述的状态
```

Nginx相关配置参数位于：[配置：INFRA - NGINX](/zh/docs/reference/param#nginx)



-------

## 如何通过域名访问 Nginx 代理的服务？

Nginx 通过浏览器设置的 `HOST` 首部中的域名，来区分不同的服务，所以默认除了软件仓库之外服务，都的您需要通过域名访问。

您可以通过 IP地址 + 端口的方式直接访问这些服务。但我们更推荐您使用域名通过 Nginx 80/443 端口代理访问所有组件。

使用域名访问 Pigsty WebUI 时，您需要配置 **DNS** 解析，或者修改本地的 `/etc/hosts` 静态解析文件，有几种典型的方式

* 如果您的服务需要直接暴露在公网上，那么应当通过 DNS 服务商（Cloudflare，Aliyun DNS 等）解析互联网域名。注意，在这种情况下，通常您还需要修改 Pigsty 的 [`infra_portal`](/zh/docs/reference/param#infra_portal) 参数，因为默认的 `*.pigsty` 并不是一个适合公网使用的域名。

* 如果您的服务需要在办公网共享访问，那么应当通过内网 DNS 服务商（公司内部 DNS 服务器）解析内网域名，并将其指向 Nginx 服务器所在的 IP。您可以要求网络管理员在公司内部 DNS 服务器中添加相应的解析记录，也可以要求系统的用户手工配置静态的 DNS 解析记录。

* 如果您的服务仅供自己，或少数用户使用（例如 DBA），那么您可以要求这些用户使用静态域名解析记录。在 Linux / MacOS 系统上，修改 `/etc/hosts` 文件（需要 sudo 权限）或 `C:\Windows\System32\drivers\etc\hosts`（Windows）文件。

我们建议普通单机用户使用第三种方式，在 **使用浏览器访问 Web 系统的机器上** ，添加以下解析记录：

```bash
<your_public_ip_address>  h.pigsty a.pigsty p.pigsty g.pigsty
```

这里的 IP 地址是安装 Pigsty 服务的 **对外IP地址**，然后您就可以在浏览器中通过： http://g.pigsty  这样的域名网址，访问 Pigsty 的子系统了。

其他的 Web 服务与自定义域名，也可以通过同样的方式添加。例如以下是 Pigsty 沙箱 Demo 可能用到的域名解析记录：

```bash
10.10.10.10 h.pigsty a.pigsty p.pigsty g.pigsty
10.10.10.10 api.pigsty ddl.pigsty adm.pigsty cli.pigsty lab.pigsty
10.10.10.10 supa.pigsty noco.pigsty odoo.pigsty
```


-------

## 如何使用 HTTPS 访问 Nginx 代理的服务？

Pigsty默认使用自动生成的自签名的 CA 证书为 Nginx 启用 SSL，如果您希望使用 HTTPS 访问这些页面，而不弹窗提示"不安全"，通常有三个选择：

* 在您的浏览器或操作系统中信任 Pigsty 自签名的 CA 证书： `files/pki/ca/ca.crt`
* 如果您使用 Chrome，可以在提示不安全的窗口键入 `thisisunsafe` 跳过提示
* 您可以考虑使用 Let's Encrypt 或其他免费的 CA 证书服务，为 Pigsty Nginx 生成正式的 SSL证书。
