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 222i\ServerName\ localhost:80 /etc/apache2/httpd.conf \
&& openrc && touch /etc/network/interfaces /run/openrc/softlevel \
&& echo -e "auto lo\niface lo inet loopback\nauto eth0\niface 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