当我的应用程序部署到 Azure 应用程序服务时,为什么我看不到我的 NGINX 日志,但它在本地运行良好?

Why can't I see my NGINX log's when my app is deployed to Azure app services, but it works fine locally?

我有一个 Docker 化的 Django 应用程序,我正在与 Supervisor 协调,这不是最佳选择,但在托管在 Azure 应用程序服务上时需要,因为它们支持 docker- compose 仍处于预览模式(也称为测试版)。

根据最佳实践,我已将 supervisord 中的每个应用程序配置为将日志发送到 STDOUT。当我在本地创建 Docker 图像时它工作正常,运行 它并检查 docker 日志。但是,当我将它部署到 Azure 应用程序服务并检查日志时,我的 Web 应用程序 (Gunicorn) 正在按预期进行记录,但是,来自 NGINX 的日志根本没有出现。

我在我的 Docker 文件中尝试了不同的配置来链接 NGINX 生成的日志文件(例如链接到 /dev/stdout 和 /dev/fd/1)并且我也进入了nginx.conf 配置并尝试直接注销到 /dev/stdout。但无论我做什么,它在本地都运行良好,但在 Azure 上,日志不显示任何 NGINX 日志。我已经粘贴了相关的配置文件,您可以在其中看到带有我尝试过的选项的注释行。希望有人能帮我解决这个问题。

编辑: 我还尝试将 NGINX 应用程序记录到系统中的日志文件中,这在本地也能正常工作,但在 Azure 应用程序服务中却不行。我尝试停用 nginx.conf 中的“user nginx”部分,因为我认为它可能与权限有关,但这也无济于事。

编辑 2: 我还尝试在 Azure 的 Web 应用程序的主目录中创建日志文件,认为这可能与无法在其他目录中创建日志有关——同样,它在本地工作,但 Azure 中的日志是空的.

Docker文件

FROM python:3.8
ENV PYTHONUNBUFFERED 1

###################
# PACKAGE INSTALLS
###################

RUN apt-get update 
RUN apt-get install -y pgbouncer
RUN apt-get update && apt-get install -y supervisor
RUN apt-get install nano
RUN apt-get install -y git 
RUN apt-get install curl

# Supervisor-stdout for consolidating logs
RUN pip install git+https://github.com/coderanger/supervisor-stdout 


###################
# AZURE SSH SETUP
###################

# Install OpenSSH and set the password for root to "Docker!". In this example, "apk add" is the install instruction for an Alpine Linux-based image.
RUN apt-get install -y --no-install-recommends openssh-server \
     && echo "root:Docker!" | chpasswd 

# Copy the sshd_config file to the /etc/ssh/ directory
COPY ./bin/staging/sshd_config /etc/ssh/

# Copy and configure the ssh_setup file
RUN mkdir -p /tmp
COPY ./bin/staging/ssh_setup.sh /tmp
RUN chmod +x /tmp/ssh_setup.sh \
    && (sleep 1;/tmp/ssh_setup.sh 2>&1 > /dev/null)


##############
# NGINX SETUP
##############

ENV NGINX_VERSION 1.15.12-1~stretch
ENV NJS_VERSION   1.15.12.0.3.1-1~stretch
RUN set -x \
    && \
    NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
    found=''; \
    for server in \
        hkp://keyserver.ubuntu.com:80 \
        hkp://p80.pool.sks-keyservers.net:80 \
        pgp.mit.edu \
    ; do \
        echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
        apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \
    done; \
    test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \
    apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \
    && dpkgArch="$(dpkg --print-architecture)" \
    && nginxPackages=" \
        nginx=${NGINX_VERSION} \
        nginx-module-xslt=${NGINX_VERSION} \
        nginx-module-geoip=${NGINX_VERSION} \
        nginx-module-image-filter=${NGINX_VERSION} \
        nginx-module-njs=${NJS_VERSION} \
    " \
    && echo "deb https://nginx.org/packages/mainline/debian/ stretch nginx" >> /etc/apt/sources.list.d/nginx.list \
    && apt-get update \
    && apt-get install --no-install-recommends --no-install-suggests -y \
                        $nginxPackages \
                        gettext-base \
    && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list

COPY ./conf/nginx/staging.conf /etc/nginx/conf.d/default.conf
COPY ./conf/nginx/nginx.conf /etc/nginx/nginx.conf

# Linking logs to be able to print errors and logs to STDOUT
#RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
RUN ln -sf /dev/fd/1 /var/log/nginx/access.log && ln -sf /dev/fd/2 /var/log/nginx/error.log

##########################
# DJANGO APPLICATION SETUP
##########################

# install app
RUN mkdir /var/app && chown www-data:www-data /var/app
WORKDIR /var/app
COPY ./requirements.txt /var/app/
RUN pip install -r requirements.txt
COPY . /var/app/

#############
# SUPERVISORD
#############

COPY ./bin/staging/supervisord_main.conf /etc/supervisor/conf.d/supervisord_main.conf
COPY ./bin/staging/prefix-log /usr/local/bin/prefix-log


##########
# VOLUMES
##########

VOLUME /var/logs

########
# PORTS
########

# Expose ports (Added from previous dockerfile)
EXPOSE 80 2222 

#########################
# SUPERCRONIC (CRON-TABS)
#########################

ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.1.12/supercronic-linux-amd64 \
    SUPERCRONIC=supercronic-linux-amd64 \
    SUPERCRONIC_SHA1SUM=048b95b48b708983effb2e5c935a1ef8483d9e3e

RUN curl -fsSLO "$SUPERCRONIC_URL" \
 && echo "${SUPERCRONIC_SHA1SUM}  ${SUPERCRONIC}" | sha1sum -c - \
 && chmod +x "$SUPERCRONIC" \
 && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
 && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic

#############
# PERMISSIONS
#############

RUN ["chmod", "+x", "/var/app/bin/staging/entrypoint_main.sh"]
RUN ["chmod", "+x", "/usr/local/bin/prefix-log"]

############
# ENTRYPOINT
############

ENTRYPOINT ["/var/app/bin/staging/entrypoint_main.sh"]

supervisord_main.conf

[supervisord]
logfile=/var/logs/supervisord.log   ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB               ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10                  ; # of main logfile backups; 0 means none, default 10
loglevel=info                       ; log level; default info; others: debug,warn,trace
pidfile=/var/logs/supervisord.pid
nodaemon=true                       ; Run interactivelly instead of deamonizing
# user=www-data

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[inet_http_server]
port = 127.0.0.1:9001

[supervisorctl]
serverurl = http://127.0.0.1:9001
#serverurl=unix:///var/run/supervisor.sock

[program:nginx]
#command=/usr/local/bin/prefix-log /usr/sbin/nginx -g "daemon off;"
command=/usr/sbin/nginx -g "daemon off;"
directory=./projectile/
autostart=true
autorestart=true
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes=0

[program:ssh]
command=/usr/local/bin/prefix-log  /usr/sbin/sshd -D
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes=0

[program:web]
user=www-data
command=/usr/local/bin/prefix-log gunicorn --bind 0.0.0.0:8000 projectile.wsgi:application # Run each app trough a SH script to prepend logs with the application name
#command=gunicorn --workers=%(ENV_WORKER_COUNT)s --bind 0.0.0.0:8000 myapp_project.wsgi:application
directory=./projectile/
autostart=true
autorestart=true
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile = /dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile = /dev/fd/2
stderr_logfile_maxbytes=0

nginx.conf

user  nginx;
worker_processes  2; # Set to number of CPU cores, 2 cores under Azure plan P1v3

error_log  /var/log/nginx/error.log warn;
#error_log  /dev/stdout warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    #access_log  /dev/stdout main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

staging.conf

server {
    listen 80 default_server;

    error_log /dev/stdout info;
    access_log /dev/stdout;

    client_max_body_size 100M;

    location /static {
        root /var/app/ui/build;
    }

    location /site-static {
        root /var;
    }

    location /media {
        root /var;
    }

    location / {
        root /var/app/ui/build; # try react build directory first, if file doesn't exist, route requests to django app
        try_files $uri $uri/index.html $uri.html @app;
    }

    location @app {
        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 "https"; # assumes https already terminated by the load balancer in front of us

        proxy_pass          http://127.0.0.1:8000;
        proxy_read_timeout  300;
        proxy_buffering    off;
    }

}

解决了。问题是 Azure 应用服务设置了配置设置 WEBSITES_PORT=8000,这使得该应用直接进入 gunicorn 并绕过 NGINX,因此不会创建任何日志。只需删除设置即可解决问题。