docker 中 nginx 容器的初始化配置和日志切割处理
docker 中 nginx 容器的初始化配置和日志切割处理
此内容年代久远,谨慎参考

这里使用 openresty/openresty:1.19.9.1-buster-fat 镜像为示例。

容器产生的日志文件,形如 /logs/site-domain/access.log 可以使用卷,也可以直接挂到宿主机,没有影响;这里使用 openresty-log 卷演示。

宿主机编辑 /etc/logrotate.d/docker-openresty 文件,写入如下内容

nginx/var/lib/docker/volumes/openresty-log/_data/*.log
/var/lib/docker/volumes/openresty-log/_data/*/*.log
{
  daily
  missingok
  # 保留 7 份
  rotate 7
  # 压缩
  compress
  # 隔天的不压缩
  delaycompress
  notifempty
  # 和容器一致的用户组和权限
  create 644 root root
  sharedscripts
  postrotate
    # openresty 是容器名
    docker exec openresty nginx -s reload
  endscript
}

起一个名为 openresty 的容器

shelldocker run \
--name openresty \
--detach \
--publish 80:80 \
--publish 443:443 \
--volume openresty-conf:/usr/local/openresty/nginx/conf:ro \
--volume openresty-site:/etc/nginx/conf.d:ro \
--volume openresty-log:/logs:rw \
--volume /var/certificates:/certificates:ro \
--volume /var/www:/www:ro \
openresty/openresty:1.19.9.1-buster-fat

修改 /var/lib/docker/volumes/openresty-conf/_data/nginx.conf 为如下内容(自己按需调整)

nginxuser root;
worker_processes 4;
pcre_jit on;
error_log  /logs/error.log;

events {
    worker_connections  4096;
}

http {
    include                        mime.types;
    default_type                   application/octet-stream;
    log_format                     json '{"time_local":"$time_local","remote_addr":"$remote_addr","http_x_real_ip":"$http_x_real_ip","http_x_forwarded_for":"$http_x_forwarded_for","status":"$status","http_referer":"$http_referer","http_user_agent":"$http_user_agent","request":"$request"}';
    access_log                     /logs/access.log json;
    client_body_temp_path          /var/run/openresty/nginx-client-body;
    proxy_temp_path                /var/run/openresty/nginx-proxy;
    fastcgi_temp_path              /var/run/openresty/nginx-fastcgi;
    uwsgi_temp_path                /var/run/openresty/nginx-uwsgi;
    scgi_temp_path                 /var/run/openresty/nginx-scgi;
    sendfile                       on;
    keepalive_timeout              65;
    server_tokens                  off;
    gzip                           off;
    gzip_disable                   msie6;
    gzip_min_length                3k;
    gzip_comp_level                1;
    gzip_buffers                   4 16k;
    gzip_http_version              1.1;
    gzip_proxied                   any;
    gzip_vary                      on;
    gzip_types                     text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/x-font-ttf font/opentype image/svg+xml;
    fastcgi_buffer_size            64k;
    fastcgi_buffers                4 64k;
    fastcgi_busy_buffers_size      128k;
    fastcgi_temp_file_write_size   256k;
    include                        /etc/nginx/conf.d/*.conf;
}

修改 /var/lib/docker/volumes/openresty-site/_data/default.conf 为如下内容(自己按需调整)

nginxserver {
    listen             80 default_server;
    server_name        _;
#    root              /usr/local/openresty/nginx/html;
#    index             index.html;
    return             200 '{"time_local":"$time_local","remote_addr":"$remote_addr","http_x_real_ip":"$http_x_real_ip","http_x_forwarded_for":"$http_x_forwarded_for","status":"$status","http_referer":"$http_referer","http_user_agent":"$http_user_agent","request":"$request"}';

#    location /sysguard_loadlimit {
#        charset       utf-8;
#        default_type  text/plain;
#        return        418 服务器繁忙,请稍后再试;
#    }
#    sysguard           on;
#    sysguard_interval  5s;
#    sysguard_load      load=1 action=/sysguard_loadlimit;
}

链接到容器中执行 nginx -t,可能有类似输出

plainroot@openresty1:~# nginx -t
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: [emerg] open() "/logs/error.log" failed (2: No such file or directory)
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test failed

此输出意为 /logs/error.log 文件不存在,自行创建即可。

在不考虑防火墙和网络的情况下,此时访问容器应该可以看到 openresty 的欢迎页面,且 /var/lib/docker/volumes/openresty-log/_data/access.log 也有记录了。

执行 logrotate -dfv /etc/logrotate.d/docker-openresty 查看输出,应该类似

plain[root@centos ~]# logrotate -dfv /etc/logrotate.d/docker-openresty 
reading config file /etc/logrotate.d/docker-openresty
Allocating hash table for state file, size 15360 B

Handling 1 logs

rotating pattern: /var/lib/docker/volumes/openresty-log/_data/*.log
/var/lib/docker/volumes/openresty-log/_data/*/*.log
 forced from command line (7 rotations)
empty log files are not rotated, old logs are removed
considering log /var/lib/docker/volumes/openresty-log/_data/*.log
  log /var/lib/docker/volumes/openresty-log/_data/*.log does not exist -- skipping
considering log /var/lib/docker/volumes/openresty-log/_data/access.log
  log needs rotating
considering log /var/lib/docker/volumes/openresty-log/_data/error.log
  log needs rotating
rotating log /var/lib/docker/volumes/openresty-log/_data/access.log, log->rotateCount is 7
dateext suffix '-20211028'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
previous log /var/lib/docker/volumes/openresty-log/_data/access.log.1 does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.7.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.8.gz (rotatecount 7, logstart 1, i 7), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.6.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.7.gz (rotatecount 7, logstart 1, i 6), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.5.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.6.gz (rotatecount 7, logstart 1, i 5), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.4.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.5.gz (rotatecount 7, logstart 1, i 4), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.3.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.4.gz (rotatecount 7, logstart 1, i 3), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.2.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.3.gz (rotatecount 7, logstart 1, i 2), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.1.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.2.gz (rotatecount 7, logstart 1, i 1), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.0.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.1.gz (rotatecount 7, logstart 1, i 0), 
rotating log /var/lib/docker/volumes/openresty-log/_data/error.log, log->rotateCount is 7
dateext suffix '-20211028'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
previous log /var/lib/docker/volumes/openresty-log/_data/error.log.1 does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.7.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.8.gz (rotatecount 7, logstart 1, i 7), 
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.6.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.7.gz (rotatecount 7, logstart 1, i 6), 
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.5.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.6.gz (rotatecount 7, logstart 1, i 5), 
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.4.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.5.gz (rotatecount 7, logstart 1, i 4), 
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.3.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.4.gz (rotatecount 7, logstart 1, i 3), 
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.2.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.3.gz (rotatecount 7, logstart 1, i 2), 
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.1.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.2.gz (rotatecount 7, logstart 1, i 1), 
renaming /var/lib/docker/volumes/openresty-log/_data/error.log.0.gz to /var/lib/docker/volumes/openresty-log/_data/error.log.1.gz (rotatecount 7, logstart 1, i 0), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log to /var/lib/docker/volumes/openresty-log/_data/access.log.1
creating new /var/lib/docker/volumes/openresty-log/_data/access.log mode = 0644 uid = 0 gid = 0
renaming /var/lib/docker/volumes/openresty-log/_data/error.log to /var/lib/docker/volumes/openresty-log/_data/error.log.1
creating new /var/lib/docker/volumes/openresty-log/_data/error.log mode = 0644 uid = 0 gid = 0
running postrotate script
running script with arg /var/lib/docker/volumes/openresty-log/_data/*.log
/var/lib/docker/volumes/openresty-log/_data/*/*.log
: "
                docker exec openresty nginx -s reload
"
removing old log /var/lib/docker/volumes/openresty-log/_data/access.log.8.gz
error: error opening /var/lib/docker/volumes/openresty-log/_data/access.log.8.gz: 没有那个文件或目录

虽然有很多报错,但实际上执行成功,以上输出意为创建新的切割文件,并改名旧的文件,再将最老的那个删除,由于当前只有一个最新的 access.log 文件,所以脚本没有体现出效果。将 access.log 和 error.log 手动复制一份为 access.log.1、error.log.1、access.log.2、error.log.2,再去掉 -d 参数执行 logrotate -fv /etc/logrotate.d/docker-openresty 应该会产生如下输出

plain[root@centos ~]# logrotate -fv /etc/logrotate.d/docker-openresty 
reading config file /etc/logrotate.d/docker-openresty
Allocating hash table for state file, size 15360 B

Handling 1 logs

rotating pattern: /var/lib/docker/volumes/openresty-log/_data/*.log
/var/lib/docker/volumes/openresty-log/_data/*/*.log
 forced from command line (7 rotations)
empty log files are not rotated, old logs are removed
considering log /var/lib/docker/volumes/openresty-log/_data/*.log
  log /var/lib/docker/volumes/openresty-log/_data/*.log does not exist -- skipping
considering log /var/lib/docker/volumes/openresty-log/_data/access.log
  log needs rotating
considering log /var/lib/docker/volumes/openresty-log/_data/error.log
  log does not need rotating (log is empty)rotating log /var/lib/docker/volumes/openresty-log/_data/access.log, log->rotateCount is 7
dateext suffix '-20211028'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
compressing log with: /bin/gzip
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.7.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.8.gz (rotatecount 7, logstart 1, i 7), 
old log /var/lib/docker/volumes/openresty-log/_data/access.log.7.gz does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.6.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.7.gz (rotatecount 7, logstart 1, i 6), 
old log /var/lib/docker/volumes/openresty-log/_data/access.log.6.gz does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.5.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.6.gz (rotatecount 7, logstart 1, i 5), 
old log /var/lib/docker/volumes/openresty-log/_data/access.log.5.gz does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.4.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.5.gz (rotatecount 7, logstart 1, i 4), 
old log /var/lib/docker/volumes/openresty-log/_data/access.log.4.gz does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.3.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.4.gz (rotatecount 7, logstart 1, i 3), 
old log /var/lib/docker/volumes/openresty-log/_data/access.log.3.gz does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.2.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.3.gz (rotatecount 7, logstart 1, i 2), 
old log /var/lib/docker/volumes/openresty-log/_data/access.log.2.gz does not exist
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.1.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.2.gz (rotatecount 7, logstart 1, i 1), 
renaming /var/lib/docker/volumes/openresty-log/_data/access.log.0.gz to /var/lib/docker/volumes/openresty-log/_data/access.log.1.gz (rotatecount 7, logstart 1, i 0), 
old log /var/lib/docker/volumes/openresty-log/_data/access.log.0.gz does not exist
log /var/lib/docker/volumes/openresty-log/_data/access.log.8.gz doesn't exist -- won't try to dispose of it
renaming /var/lib/docker/volumes/openresty-log/_data/access.log to /var/lib/docker/volumes/openresty-log/_data/access.log.1
creating new /var/lib/docker/volumes/openresty-log/_data/access.log mode = 0644 uid = 0 gid = 0
running postrotate script
Error: No such container: openresty1
error: error running shared postrotate script for '/var/lib/docker/volumes/openresty-log/_data/*.log
/var/lib/docker/volumes/openresty-log/_data/*/*.log
'
Removing /var/log/wtmp from state file, because it does not exist and has not been rotated for one year
Removing /var/log/spooler from state file, because it does not exist and has not been rotated for one year
Removing /var/log/maillog from state file, because it does not exist and has not been rotated for one year
Removing /var/log/secure from state file, because it does not exist and has not been rotated for one year
Removing /var/log/messages from state file, because it does not exist and has not been rotated for one year
Removing /var/log/cron from state file, because it does not exist and has not been rotated for one year

此时再查看日志文件夹,应该已经有相应的分割压缩文件了,至此配置就算完成了。

如果有下面这样的输出,说明 /etc/logrotate.d/docker-openresty 这个文件的权限不对,应该是 0644。

plain[root@centos ~]# logrotate -dfv /etc/logrotate.d/docker-openresty 
error: Ignoring /etc/logrotate.d/docker-openresty because of bad file mode - must be 0644 or 0444.
Allocating hash table for state file, size 15360 B

Handling 0 logs
作者
ragnaroks
发布时间
2021-10-27
创作协议