从Nginx背后的Docker暴露Grafana

irlmq6kh  于 2023-05-06  发布在  Nginx
关注(0)|答案(1)|浏览(217)

背景

我的应用堆栈使用了几个由docker compose管理的Docker容器:

  • PostgreSQL端口5433
  • FastAPI(Python)后端端口8000
  • NodeJS前端在端口8090并暴露于80(通过Nginx,请参阅进一步)
  • pgAdmin端口5050
  • Prometheus在9090端口记录
  • 3090端口的Grafana

查看docker-compose ps返回的容器信息:

Docker compose配置

容器在docker-compose.override.yml配置中公开如下:

version: "3.8"

services:

  pgadmin:
    ports:
      - "5050:5050"

  frontend:
    ports:
      - "8090:80"

  prometheus:
    ports:
      - "9090:9090"

  grafana:    
    ports:
      - "3090:3090"

内部代理配置

在前端容器内,有一个Nginx代理,用于管理应用堆栈内的端口路由。它的配置是这样的:

server {
        listen 80;
        server_name     example.com;

        gzip            on;
        gzip_types      text/plain application/xml text/css application/javascript application/json;
        gzip_min_length 1000;

        charset                                   utf-8;     
        include                                   /etc/nginx/mime.types;
        client_max_body_size                      20M;

        root                                      /usr/share/nginx/html;

        location / {
            expires                               $expires;
            index                                 index.html index.htm;
            try_files                             $uri $uri/ /index.html;
        }

        location /api/ {
            proxy_pass                          http://backend:8000/;
            proxy_http_version                  1.1;
            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_read_timeout                  1800;
            proxy_connect_timeout               1800;
        }
}

主机代理配置

主机本身有一个运行的Nginx代理,配置简单如下:

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name     _;

        location / {
            proxy_pass                          http://127.0.0.1:8090/;
            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;
        }
}

问题

我希望能够从http://<myip>:3090http://<myip>:5050的pgAdmin查看Grafana Jmeter 板,但目前浏览器返回“Page Not Found(404)”(没有任何Nginx头)。当我尝试http://<myip>:3000时(看到Grafana也运行在3000,尽管我显式地将其设置为3090),我得到了相同的错误。
与此同时,我可以以某种方式访问http://<myip>:9090上的Prometheus ...但不是Grafana或pgAdmin。我错过了什么?

kq0g1dla

kq0g1dla1#

我对你的目标有点困惑;你的标题是“从Nginx背后的Docker中暴露Grafana”,但看起来你计划通过在主机上发布端口并直接访问它来以 * 绕过 * nginx的方式访问Grafana。
我在这里看到的一个直接问题是:

grafana:
    ports:
      - "3090:3090"

Grafana默认监听端口3000;如果没有明确的配置,相反,如果你想在 host 端口3090上暴露Grafana,你会写:

grafana:
    ports:
      - "3090:3000"

类似地,pgadmin监听端口80,所以除非你显式设置PGADMIN_LISTEN_PORT,否则你应该这样写:

pgadmin:
      ports:
        - "5050:80"

把所有这些放在一起,下面的docker-compose.yaml将暴露:

  • 普罗米修斯号在9090端口
  • 端口3090上的Grafana
  • 端口5050上的Pgadmin

Postgres不会在主机上公开(但可以供您的compose中的其他服务使用)。

volumes:
  prometheus_data: {}
  grafana_data: {}
  postgres_data: {}

services:
  prometheus:
    image: docker.io/prom/prometheus:latest
    restart: unless-stopped
    volumes:
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
    ports:
      - 9090:9090

  grafana:
    image: docker.io/grafana/grafana:latest
    restart: unless-stopped
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - 3090:3000

  postgres:
    image: docker.io/postgres:15
    environment:
      POSTGRES_PASSWORD: "secret"
    volumes:
      - postgres_data:/var/lib/postgresql/data

  pgadmin:
    image: docker.io/dpage/pgadmin4:latest
    environment:
      PGADMIN_DISABLE_POSTFIX: "1"
      PGADMIN_DEFAULT_EMAIL: admin@example.com
      PGADMIN_DEFAULT_PASSWORD: secret
    ports:
      - 5050:80

这是一个可运行的示例--您可以在本地复制并粘贴它,然后运行docker compose up;它不依赖于本地文件。
请注意,您可以从上述所有服务中删除端口发布,而是添加一个nginx代理,该代理将发布单个端口,然后在特定路径(如http://localhost:8090/prometheus/http://localhost:8090/grafana/http://localhost:8090/pgadmin/等)访问服务。
该配置可能如下所示:

volumes:
  prometheus_data: {}
  grafana_data: {}
  postgres_data: {}

services:
  prometheus:
    image: docker.io/prom/prometheus:latest
    restart: unless-stopped
    volumes:
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
      - '--web.external-url=/prometheus/'

  grafana:
    image: docker.io/grafana/grafana:latest
    restart: unless-stopped
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
        GF_SERVER_ROOT_URL: "%(protocol)s://%(domain)s:%(http_port)s/grafana/"
        GF_SERVER_SERVE_FROM_SUB_PATH: "true"

  postgres:
    image: docker.io/postgres:15
    environment:
      POSTGRES_PASSWORD: "secret"
    volumes:
      - postgres_data:/var/lib/postgresql/data

  pgadmin:
    image: docker.io/dpage/pgadmin4:latest
    environment:
      PGADMIN_DISABLE_POSTFIX: "1"
      PGADMIN_DEFAULT_EMAIL: admin@example.com
      PGADMIN_DEFAULT_PASSWORD: secret

  nginx:
    image: docker.io/nginx:mainline
    volumes:
      - ./nginx:/etc/nginx/conf.d
    ports:
      - 8090:80

nginx/default.conf看起来像:

server {
  listen 80;
  server_name     localhost;

  location /grafana/ {
    proxy_pass http://grafana:3000/;
  }

  location /prometheus/ {
    proxy_pass http://prometheus:9090/prometheus/;
  }

  location /pgadmin/ {
    proxy_pass http://pgadmin:80/;
    proxy_set_header X-Script-Name /pgadmin/;
  }
}

相关问题