如何在 Docker 容器中使用 Apache 并且不向磁盘写入任何内容(所有日志都写入 STDIO / STDERR)?
How does one use Apache in a Docker Container and write nothing to disk (all logs to STDIO / STDERR)?
我 运行 Apache2 在 docker 容器中,不想向磁盘写入任何内容,将日志写入 stdout 和 stderr。我见过几种不同的方法来做到这一点(Supervisord 和 stdout/stderr,Apache 访问日志到 stdout)但这些看起来像是 hack。默认情况下没有办法做到这一点吗?
明确地说,我不想拖尾日志,因为这会导致将内容写入容器中的磁盘。
已签入 Docker 集线器 (https://hub.docker.com/_/httpd/) 的 "official" 版本仍写入磁盘。
另外,当 Apache 尝试滚动日志时,我需要做什么来阻止它失败?
另一件事 - 理想情况下,我真的很想在没有其他附加组件的情况下做到这一点。 nginx 可以轻松做到这一点。
您可以将错误日志直接发送到系统日志,也可以将任何自定义日志(访问日志)发送到从标准输入读取的任何可执行文件。有日志聚合工具,或者您可以再次使用 syslog w/ 例如/usr/bin/logger.
您可以尝试使用 dockerize
工具。有了它,您可以包装 httpd-foreground
命令并将其日志文件重定向到 stdout/stderr(不知道确切的 httpd 日志文件路径,只需根据您的需要调整它们):
CMD ["dockerize", "-stdout", "/var/log/httpd.log", "-stderr", "/var/log/httpd.err", "httpd-foreground"]
除此之外,您还可以获取容器 stdout/stderr,然后通过指定 syslog log driver 并将它们重定向到 /var/log/syslog
日志docker 主机上的文件:
docker run -d --log-driver=syslog ...
我不确定这不会干扰 httpd 的日志记录(例如,如果它试图在文件中查找),但您可以设置从日志路径到 /dev/stdout 的符号链接,并且/dev/stderr,像这样:
ln -sf /dev/stdout /path/to/access.log
ln -sf /dev/stderr /path/to/error.log
从 Docker Hub 到 vanilla httpd 容器的入口命令可以像
ln -sf /dev/stdout /path/to/access.log && ln -sf /dev/stderr /path/to/error.log && /path/to/httpd
根据 apache 邮件列表,您可以直接写入 /dev/stdio(在类似 Unix 的系统上),因为那只是一个普通的 ol' 文件句柄。简单!正在粘贴...
The most efficient answer depends on your operating system. If you're
on a UNIX like system which provides /dev/stdout and /dev/stderr (or
perhaps /dev/fd/1 and /dev/fd/2) then use those file names. If that
isn't an option use the piped output feature. For example, from my
config:
CustomLog "|/usr/sbin/rotatelogs -c -f -l -L
/private/var/log/apache2/test-access.log
/private/var/log/apache2/test-access.log.%Y-%m-%d 86400 "
krader_custom ErrorLog "|/usr/sbin/rotatelogs -c -f -l -L
/private/var/log/apache2/test-error.log
/private/var/log/apache2/test-error.log.%Y-%m-%d 86400"
Obviously you'll want to substitute another program for
/usr/sbin/rotatelogs in the example above that writes the data where
you want it to go.
我调整了config,从httpd的Dockerfile recipe,他们使用sed调整config,更改ErrorLog和CustomLog如下:
sed -ri ' \
s!^(\s*CustomLog)\s+\S+! /proc/self/fd/1!g; \
s!^(\s*ErrorLog)\s+\S+! /proc/self/fd/2!g; \
' /usr/local/apache2/conf/httpd.conf \
参见 https://github.com/docker-library/httpd/blob/master/2.4/Dockerfile(接近文件末尾)
我知道这是一个老问题,但我今天有这个需要。
在 Alpine 3.6 上,httpd.conf
中的以下说明有效:
Errorlog /dev/stderr
Transferlog /dev/stdout
我以这种方式将它们添加到我的容器中:
FROM alpine:3.6
RUN apk --update add apache2
RUN sed -i -r 's@Errorlog .*@Errorlog /dev/stderr@i' /etc/apache2/httpd.conf
RUN echo "Transferlog /dev/stdout" >> /etc/apache2/httpd.conf
...
我 运行 Apache2 在 docker 容器中,不想向磁盘写入任何内容,将日志写入 stdout 和 stderr。我见过几种不同的方法来做到这一点(Supervisord 和 stdout/stderr,Apache 访问日志到 stdout)但这些看起来像是 hack。默认情况下没有办法做到这一点吗?
明确地说,我不想拖尾日志,因为这会导致将内容写入容器中的磁盘。
已签入 Docker 集线器 (https://hub.docker.com/_/httpd/) 的 "official" 版本仍写入磁盘。
另外,当 Apache 尝试滚动日志时,我需要做什么来阻止它失败?
另一件事 - 理想情况下,我真的很想在没有其他附加组件的情况下做到这一点。 nginx 可以轻松做到这一点。
您可以将错误日志直接发送到系统日志,也可以将任何自定义日志(访问日志)发送到从标准输入读取的任何可执行文件。有日志聚合工具,或者您可以再次使用 syslog w/ 例如/usr/bin/logger.
您可以尝试使用 dockerize
工具。有了它,您可以包装 httpd-foreground
命令并将其日志文件重定向到 stdout/stderr(不知道确切的 httpd 日志文件路径,只需根据您的需要调整它们):
CMD ["dockerize", "-stdout", "/var/log/httpd.log", "-stderr", "/var/log/httpd.err", "httpd-foreground"]
除此之外,您还可以获取容器 stdout/stderr,然后通过指定 syslog log driver 并将它们重定向到 /var/log/syslog
日志docker 主机上的文件:
docker run -d --log-driver=syslog ...
我不确定这不会干扰 httpd 的日志记录(例如,如果它试图在文件中查找),但您可以设置从日志路径到 /dev/stdout 的符号链接,并且/dev/stderr,像这样:
ln -sf /dev/stdout /path/to/access.log
ln -sf /dev/stderr /path/to/error.log
从 Docker Hub 到 vanilla httpd 容器的入口命令可以像
ln -sf /dev/stdout /path/to/access.log && ln -sf /dev/stderr /path/to/error.log && /path/to/httpd
根据 apache 邮件列表,您可以直接写入 /dev/stdio(在类似 Unix 的系统上),因为那只是一个普通的 ol' 文件句柄。简单!正在粘贴...
The most efficient answer depends on your operating system. If you're on a UNIX like system which provides /dev/stdout and /dev/stderr (or perhaps /dev/fd/1 and /dev/fd/2) then use those file names. If that isn't an option use the piped output feature. For example, from my config:
CustomLog "|/usr/sbin/rotatelogs -c -f -l -L /private/var/log/apache2/test-access.log /private/var/log/apache2/test-access.log.%Y-%m-%d 86400 " krader_custom ErrorLog "|/usr/sbin/rotatelogs -c -f -l -L /private/var/log/apache2/test-error.log /private/var/log/apache2/test-error.log.%Y-%m-%d 86400"
Obviously you'll want to substitute another program for /usr/sbin/rotatelogs in the example above that writes the data where you want it to go.
我调整了config,从httpd的Dockerfile recipe,他们使用sed调整config,更改ErrorLog和CustomLog如下:
sed -ri ' \
s!^(\s*CustomLog)\s+\S+! /proc/self/fd/1!g; \
s!^(\s*ErrorLog)\s+\S+! /proc/self/fd/2!g; \
' /usr/local/apache2/conf/httpd.conf \
参见 https://github.com/docker-library/httpd/blob/master/2.4/Dockerfile(接近文件末尾)
我知道这是一个老问题,但我今天有这个需要。
在 Alpine 3.6 上,httpd.conf
中的以下说明有效:
Errorlog /dev/stderr
Transferlog /dev/stdout
我以这种方式将它们添加到我的容器中:
FROM alpine:3.6
RUN apk --update add apache2
RUN sed -i -r 's@Errorlog .*@Errorlog /dev/stderr@i' /etc/apache2/httpd.conf
RUN echo "Transferlog /dev/stdout" >> /etc/apache2/httpd.conf
...