本次环境基于php:7.4-fpm,因为我的服务需要cron和supervisor,而镜像中没有,镜像系统只有sysvinit,查询相关教程也无法使用,也不知道是什么原因,只能开始研究dockerfile
下面直接说步骤
准备步骤
先创建一个容器
docker run -itd --name php7.4 php:7.4-fpm
1.在本地创建脚本、/home/startService.sh
#!/bin/bash
# 启动cron服务
echo "启动cron服务"
service cron start
# 启动supervisor服务
echo "启动supervisor服务"
service supervisor start
echo "启动php服务"
php-fpm -F
# 脚本执行到这里说明服务已经尝试启动,现在让脚本保持运行
echo "服务已经开启..."
2.为了减少镜像层数我将脚本直接复制到容器中
docker cp /home/startService.sh php7.4:/bin/
docker exec php7.4 chmod 777 /bin/startService.sh
#下面这个是我服务需要创建的文件夹
docker exec php7.4 sh mkdir -p /var/log/supervisor
docker exec php7.4 sh chmod -R 755 /var/log/supervisor
3.将现有容器打包成镜像
docker commit -a "xiaohaohhh" -m "php-lnmp" php7.4 php:7.4
4.编写Dockerfile
vim /home/Dockerfile
FROM php:7.4
LABEL maintainer="xiaohaohhh"
RUN apt update && apt upgrade -y \
&& apt install -y libmariadb-dev-compat libmariadb-dev libzip-dev libmagickwand-dev imagemagick cron vim supervisor sudo \
&& docker-php-ext-install mysqli pdo_mysql zip exif gd intl bcmath opcache pcntl \
&& echo "" | pecl install imagick && echo "extension=imagick.so" > /usr/local/etc/php/conf.d/imagick.ini \
&& echo "" | pecl install redis && echo "extension=redis.so" > /usr/local/etc/php/conf.d/docker-php-ext-redis.ini \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT /bin/startService_sh.sh
5.重构镜像
docker build -t php:7.4-lnmp-v1.0 .
6.按照正常步骤重构
version: '3'
services:
php: # PHP容器配置
image: php:sh_apt
container_name: php7.4
privileged: true
restart: always
networks:
lnmp:
ipv4_address: 150.0.0.3
ports:
- "127.0.0.1:9000:9000"
volumes:
- /home/nginx/html:/var/www/html
- /home/php/php74/log:/var/log
networks:
lnmp: # 创建外部网络lnmp
external: true
避坑,这里坑了2天
原有php-fpm镜像中CMD是,如下图
如果想自定义启动脚本, 最终在启动php-fpm
以下是自定义脚本内容:特别注意php-fpm的启动和原有启动保持一致 这里-F是php-fpm取消守护进程的参数
官方解释
If you add a custom CMD in the Dockerfile, be sure to include -g daemon off;
in the CMD in order for nginx to stay in the foreground,
so that Docker can track the process properly (otherwise your container will stop immediately after starting)!
如果你在Dockerfile中添加了一个自定义CMD,一定要关闭-g守护进程;
为了让nginx留在前台,
这样Docker就可以正确地跟踪进程(否则你的容器会在启动后立即停止)!