为什么当我的应用部署到 Azure 应用服务时看不到我的 NGINX 日志,但它在本地工作正常?



我有一个Dockerized Django应用程序,我正在与Supervisor协调,它不是最佳的,但在Azure应用程序服务上托管时需要,因为它们对docker compose的多应用程序支持仍处于预览模式(又名测试版(。

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

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

编辑:我还尝试将NGINX应用程序记录到系统中的日志文件中,该文件在本地也可以正常工作,但在Azure应用程序服务中不行。我尝试停用";用户nginx";作为nginx.conf的一部分,我认为它可能与权限有关,但这也没有帮助。

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

Dockerfile

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,因此没有创建任何日志。简单地删除设置就解决了问题。

最新更新