在使用Docker时,将Apache和Perl分别放置在不同的容器中运行
在业务中有时会接受 Movable Type 的开发项目,但在使用 Docker 环境进行开发时,我想通过将 Apache 和 Perl 分开来实现环境的轻量化。
这次我将介绍我为了实现轻量化而进行的各种调查和实践方法。
在这里,我们仅介绍了用于建立开发环境的方法。
由于安全考虑,有些方法并非最佳选择,请勿直接在商业环境中使用。
由于安全考虑,有些方法并非最佳选择,请勿直接在商业环境中使用。
本文仅涉及Apache和Perl部分,不包括涵盖Movable Type所需的设置、数据库和PHP容器等内容。
文件
docker-compose的配置文件是yaml格式的。
将 Perl 和 Apache 在不同的容器中运行。
另外,httpd 将使用基于最轻量级的 Alpine Linux 的版本。
version: '3'
services:
perl:
build:
context: ./docker/perl
volumes:
- type: bind
source: ./example
target: /usr/local/apache2/vhosts/localhost
httpd:
build:
context: ./docker/httpd
volumes:
- type: bind
source: ./docker/httpd/httpd-vhosts.conf
target: /usr/local/apache2/conf/extra/httpd-vhosts.conf
- type: bind
source: ./example
target: /usr/local/apache2/vhosts/localhost
ports:
- "80:80"
Perl 容器
我們將使用多階段的建造方法。
FROM perl:5.36.0-threaded-bullseye AS build
RUN apt update
COPY cpanfile cpanfile
RUN cpanm --notest --installdeps .
FROM perl:5.36.0-slim-threaded-bullseye AS deploy
RUN apt update \
&& apt install -y fcgiwrap spawn-fcgi
COPY --from=build /usr/local/lib/perl5 /usr/local/lib/perl5
ARG FCGI_PORT=9000
RUN sed -ie "s/^FCGI_SOCKET=.*$/FCGI_PORT=\"${FCGI_PORT}\"\nFCGI_ADDR=\"0.0.0.0\"/g" /etc/init.d/fcgiwrap
EXPOSE ${FCGI_PORT}
CMD ["bash", "-c", "service fcgiwrap start && tail -f /dev/null"]
在构建阶段,从 cpanfile 安装所需的模块。
在部署阶段,根据没有构建工具的轻量级 Perl 镜像,复制从构建阶段安装的模块,并进行将 Perl 设置为 CGI 以便运行的设置。
关于多阶段构建,我参考了这里的Gist。
我决定试着放一个模块进去看看。
requires 'HTML::Entities';
Apache 容器
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/usr/local/apache2/vhosts/localhost/htdocs"
Alias /cgi-bin/ "/usr/local/apache2/vhosts/localhost/cgi-bin/"
<Directory "/usr/local/apache2/vhosts/localhost/htdocs">
Options None
AllowOverride None
Require all granted
DirectoryIndex index.html
</Directory>
<Directory "/usr/local/apache2/vhosts/localhost/cgi-bin">
AllowOverride None
Options None
Require all granted
<FilesMatch "\.cgi$">
ProxyFCGIBackendType GENERIC
SetHandler "proxy:fcgi://perl:9000"
</FilesMatch>
</Directory>
</VirtualHost>
如果文件名以 .cgi 结尾,则设置代理,并使用 Perl 容器中的 Perl。
FROM httpd:2.4.54-alpine3.17
RUN sed -i -Ee 's/#(LoadModule proxy_module modules\/mod_proxy.so)/\1/g' /usr/local/apache2/conf/httpd.conf \
&& sed -i -Ee 's/#(LoadModule proxy_fcgi_module modules\/mod_proxy_fcgi.so)/\1/g' /usr/local/apache2/conf/httpd.conf \
&& sed -i -Ee 's/#(Include conf\/extra\/httpd-vhosts.conf)/\1/g' /usr/local/apache2/conf/httpd.conf
启用代理设置。
样本文件.
将显示Perl版本的文件放置在example/cgi-bin/index.cgi中。
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
print "Content-type: text/html\n\n";
print "Hello World!<br>";
print "Perl Version: $^V<br>";
如果您在WSL(Windows Subsystem for Linux)或其他Linux平台上放置文件,请授予执行权限。
chmod a+x example/cgi-bin/index.cgi
在example/htdocs/index.html中也放置一个样本文件。
Hello HTML!
确认行动
创建文件后,启动容器进行操作确认。
docker-compose up -d --build
http://localhost/index.html にアクセスして Hello HTML! と表示されることを確認します。
http://localhost/cgi-bin/index.cgi にアクセスして以下のように表示されることを確認します。
Hello World!
Perl Version: v5.36.0
确认操作后,将关闭容器。
docker-compose down --remove-orphans -v