docker用alpine搭建php+apache2/nginx环境,制作镜像,Dockerfile
记录一些自己踩过的坑
一、简介
1.1 Alpine简介
Alpine Linux 是一个面向安全,轻量级的基于musl libc与busybox项目的Linux发行版
不同于主流的基于gunc(glibc)的发行版本
它简洁小巧,官方的docker镜像才5M,其余基于alpine的镜像也都是50M左右,而其它的docker镜像都是一百多M起步
它具有较完整的生态环境,主流的linux应用都有其移植版本
它有自己的包管理软件:apk
值得注意的是,在 Alpine Linux 存储库上,只有每个包的最新版本可用。旧的软件包版本被丢弃,一旦被丢弃,就不能再使用apk add来安装
想用旧版本软件就需要安装旧版本的 alpine ,或根据本文后面的方法更改 /etc/apk/repositories
1.2 Dockerfile
参考:https://www.cnblogs.com/yunmuq/p/15503281.html#三、dockerfile
二、alpine搭建php+apache2环境
# 安装软件
apk --no-cache --update
add apache2 php-apache2 openrc
# 简单配置apache2,为了消除提示
vi /etc/apache2/hpptd.conf
# 找到servername
/servername
# 添加配置,退出
ServerName localhost
# web目录
cd /var/www/localhost/htdocs
# 初始化openrc
openrc
# 启动apache2
rc-service apache2 start
这里踩的坑是,apache2 nginx这种,都需要openrc的支持,先要执行一下 openrc 初始化,不然运行 rc-service apache2 start
,可能提示
WARNING: nginx is already starting
那么就是启动失败
nginx安装参考:https://wiki.alpinelinux.org/wiki/Nginx_with_PHP
针对上述WARNING,nginx还要 mkdir /run/nginx/
touch /run/openrc/softlevel
然后设置目录权限,参考:https://stackoverflow.com/questions/65627946/how-to-start-nginx-server-within-alpinelatest-image-using-rc-service-command
鄙人额外踩的坑是,为了复现问题装低版本的php,找了个alpine 3.7 的镜像,结果 rc-service apache2 start
还提示启动网络失败,这种网络问题似乎只有低版本才会出现
networking failed to start
暂时妥协(往后看,后续已经解决低版本alpine中这个问题),用新版本镜像,无此网络问题
可以通过修改 /etc/apk/repositories ,来更改 apk 安装应用的版本
注意,排坑:
-
改了 /etc/apk/repositories ,用低版本,如果构建时不能访问,则可以尝试放弃 https 使用 http ,如 3.7 中默认的 repositories 是 http ,用 https 有可能无法访问
-
别用 3.7 版本,构建中可能出现
ERROR: libressl2.6-libcrypto-2.6.5-r0: trying to overwrite etc/ssl/cert.pem owned by ca-certificates-bundle-20191127-r5.
ERROR: libressl2.6-libcrypto-2.6.5-r0: trying to overwrite etc/ssl/openssl.cnf owned by libcrypto1.1-1.1.1l-r0.
三、alpine php+apache2 DockerFile
把在容器里的操作记录下来写进相应位置即可
下面给出我制作的 alpine-php5-apache2 的 DockerFile
因为我要复现问题,需要php5,最新能支持php5的版本是 alpine:3.8,但是在使用过程中也遇到一些问题,不过最后都解决了
DockerFile
FROM alpine:3.8
LABEL maintainer="https://www.cnblogs.com/yunmuq/p/15509873.html"
LABEL description="alpine php5 apache2 base web server"
EXPOSE 80
COPY src/ /var/www/localhost/htdocs.pre/
COPY start.sh /start.sh
RUN chmod 755 /start.sh
&& apk --no-cache --update add apache2 php5-apache2 openrc
&& rm -rf /var/www/localhost/htdocs
&& cp -rf /var/www/localhost/htdocs.pre /var/www/localhost/htdocs
&& rm -rf /var/www/localhost/htdocs.pre
&& chmod -R 755 /var/www/localhost/htdocs
&& sed -i 222iServerName localhost:80 /etc/apache2/httpd.conf
&& openrc && touch /etc/network/interfaces /run/openrc/softlevel
&& echo -e "auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp">/etc/network/interfaces
CMD ["/start.sh"]
先解释一下,start.sh 不更改权限,docker run
无法顺利运行;
apk --no-cache --update
无缓存,减少镜像的大小;
cp -rf
反斜杠是直接使用cp命令,否则可能会使用 ~/.bashrc
中的-i别名
/var/www/localhost/htdocs
权限要设置好,否则访问时 apache2 提示403:
apache2 You don't have permission to access
sed -i 222i
在文件222行插入 ServerName localhost:80
,sed中空格要转义
openrc 和 touch 都是初始化 openrc
最后一行是网络配置,这里解决了上面提到的网络问题,必须配置才能启动,网上说的用httpd启动作者没成功过
/etc/network/interfaces
文件并不是touch一下就好了,需要有配置,参考:官方维基
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
采用dhcp,缺点是从 docker run 到web启动时间有点长。其实可以用脚本,根据 /etc/hosts
netstat -r
来配置静态 ip
以下是start.sh
#!/bin/sh
openrc
rc-service apache2 start
tail -f -s 30 /dev/null