【问题标题】:How can I start php-fpm in a Docker container by default?默认情况下,如何在 Docker 容器中启动 php-fpm?
【发布时间】:2021-05-06 01:20:01
【问题描述】:

我有这个 Docker 镜像 -

FROM centos:7
MAINTAINER Me <me.me>
RUN yum update -y
RUN yum install -y git https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

RUN yum install -y ansible
RUN git clone https://github.com/.../dockerAnsible.git
RUN ansible-playbook dockerFileBootstrap.yml
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;

VOLUME [ "/sys/fs/cgroup" ]
EXPOSE 80 443 3306

CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

基本上,我希望它在 docker 容器启动时启动 php-fpm。如果我手动进入容器并使用/usr/sbin/php-fpm 打开它,我就可以使用 php-fpm。

我用这个命令在我的 ansible 文件中尝试了它(它没有工作)。我也尝试使用服务模块,但没有运气。-

 - name: Start php fpm
   command: /usr/sbin/php-fpm

如何让 php-fpm 与 apache 一起运行?

【问题讨论】:

  • 添加RUN /usr/sbin/php-fpm?
  • 没有骰子。使用 this 启动容器后,它仍然无法启动。

标签: php docker ansible


【解决方案1】:

您应该使用supervisor 来启动多个服务

在你的 dockerfile 中,安装 supervisor,然后你启动

COPY ./docker/supervisord.conf /etc/supervisord.conf
....
CMD ["/usr/bin/supervisord", "-n"]

您的docker/supervisord.conf 包含您想要启动的所有服务,因此您可以拥有类似的东西

[program:php-fpm]
  command=/opt/remi/php70/root/usr/sbin/php-fpm -c /etc/php-fpm.conf
  ;command=/usr/sbin/php70-fpm -c /etc/php-fpm.d
  stdout_logfile=/dev/stdout
  stdout_logfile_maxbytes=0
  stderr_logfile=/dev/stderr
  stderr_logfile_maxbytes=0

[program:nginx]
  command=/usr/sbin/nginx
  stdout_logfile=/dev/stdout
  stdout_logfile_maxbytes=0
  stderr_logfile=/dev/stderr
  stderr_logfile_maxbytes=0

当然,您应该适应您的路径和 php-fpm 版本以及您的服务(在我的示例中为 nginx,为您提供 apache 等),但基本上,supervisor 是从一个管理多个服务启动的最佳方式起点。

这里可以找到docker关于supervisor的官方文档

https://docs.docker.com/engine/admin/using_supervisord/

【讨论】:

  • 虽然这种方法看起来可行,但对于我需要启动的一项额外服务来说似乎有点过头了。是否可以将我的 CMD 链接在一起,或者在初始化 Docker 容器时启动它?
  • 另一种选择是在另一个容器中运行 php-fpm 并将两个容器放在同一个网络上。然后将 php-fpm httpd 配置指向另一个容器。
  • 我真的不觉得这种方法矫枉过正,supervisor 是处理多处理器管理的常用方法,也是 docker 推荐的方法,它只有你的 docker 文件会改变一点,还有一个配置文件.如果您想稍后添加一些服务,您的容器将更加灵活。但如果你找到更简单的“合法”方法,请告诉我们,我很感兴趣
  • 建议增加另一层复杂性并不是一个好的答案。投反对票。
  • 我们应该考虑到现在容器确实是为单一服务而设计的。从这个角度来看,这个答案是合法的。
【解决方案2】:

我来这里是为了寻找如何在前台运行php-fpm,以便它可以是 docker 容器中的 PID 1。解决办法是

php-fpm -F -R

说明

我们可以通过php-fpm --help查看可用选项

-F, --nodaemonize 
      force to stay in foreground, and ignore daemonize option from config file

如果您在 docker 容器中运行 php-fpm,那么您很有可能以 root 身份运行该进程。如果没有额外的标志,php-fpm 不会以 root 身份启动:

  -R, --allow-to-run-as-root
        Allow pool to run as root (disabled by default)

【讨论】:

  • 嗨,以 root 身份运行 php-fpm 是否安全?我很担心
  • 此答案仅适用于在容器化环境中运行 php-fpm。如果您不使用 docker 或其他容器,以 root 身份运行 php-fpm 会大大增加您对黑客的风险。
  • 此命令在 Dockerfile 中不起作用,这是此答案的用例。
【解决方案3】:

我最近需要类似的东西。对于 alpine linux 镜像,运行 php-fpm 和 web 服务器作为容器命令就足够了。定义在Dockerfile 有点像这样:

CMD /usr/bin/php-fpm -D; nginx

即。守护php-fpm,然后在前台运行nginx

ubuntu/debian 图像上,还需要允许通过运行 Dockerfile RUN 命令来启动最近安装的软件包,如下所示:

RUN echo "exit 0" > /usr/sbin/policy-rc.d

然后在CMD 命令中重新启动php-fpm

CMD /etc/init.d/php7.0-fpm restart && nginx -g "daemon off;"

更多关于policy-rc.d的信息请见in this askubuntu question

【讨论】:

  • 我的普通朋友,第三个工作完美。谢谢。 :-)
【解决方案4】:

如果您想在同一个容器中运行 php-fpmApache(通常使用 MPM 事件),您可能会发现此配置很有用:

[supervisord]

[program:php-fpm]
command=php-fpm -F -R
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:apachectl]
command=apachectl -D "FOREGROUND" -k start
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

【讨论】:

    【解决方案5】:

    我使用 rc.local 在容器内启动服务,然后在该容器内运行命令来执行 rc.local。下面是一个示例运行命令:

    sudo docker run --restart=always -itd --name mycontainer -p 80:80 -p 443:443 myimage/name /bin/bash -c "/etc/rc.local && while true; do echo hello world; sleep 100; done"
    

    这是来自 /etc 的 rc.local 文件之一

    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    # Make sure that the script will "exit 0" on success or any other
    # value on error.
    #
    # In order to enable or disable this script just change the execution
    # bits.
    #
    # By default this script does nothing.
    sleep 5
    service mysql start
    sleep 5
    service php5-fpm start
    sleep 5
    service nginx start
    exit 0
    

    这样做是使用图像“myimage/name”启动一个名为“mycontainer”的容器,并暴露端口 80 和 443。一旦启动,它会调用 mysql、php5-fpm 和 nginx 来启动,每个之间暂停 5 秒。通过这种方式,您可以调用任何您希望在该容器内运行的服务来启动。不过请记住为这些服务添加开放端口。

    此运行命令还会每 100 秒将“Hello World”作为“脉冲”附加到您的日志文件中,让您知道它何时运行以及何时停止。

    【讨论】:

      【解决方案6】:

      我相信上面@ckeeney 的答案可以被接受为正确答案,但我无法让它适用于我的特定案例。

      使用哑初始化

      我已经能够通过哑初始化代理 PID1,并使用以下命令守护 PHP-FPM:dumb-init /usr/sbin/php-fpm7.2 -F -R https://engineeringblog.yelp.com/2016/01/dumb-init-an-init-for-docker.html

      【讨论】:

        猜你喜欢
        • 2016-10-14
        • 2018-08-19
        • 1970-01-01
        • 2021-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-05
        相关资源
        最近更新 更多