如何编写 docker-compose.yml 以便我可以从 php 访问 deamon 的容器?

How to compose docker-compose.yml so i can access deamon's container from php?

我需要 Docker 方面的帮助。

假设我有 docker-compose.yml 版本 3 和 Nginx+PHP。如何添加图像 vitr/casperjs 以便我可以从 PHP 调用它,例如

exec('casperjs --version', $output);

感谢任何帮助。

已更新:

看起来正确答案是:不可能

您需要将 PHP 和 CasperJS(以及 PhantoJS)放在同一个容器中才能让它们协同工作。如果有人可以证明我错了并更好地展示在哪里做,那就太好了。这是像工作示例一样的东西:

FROM nanoninja/php-fpm

ENV PHANTOMJS_VERSION=phantomjs-2.1.1-linux-x86_64 
ENV PHANTOMJS_DIR=/app/phantomjs

RUN apt-get update -y
RUN apt-get install -y apt-utils libfreetype6-dev libfontconfig1-dev wget bzip2

RUN wget --no-check-certificate https://bitbucket.org/ariya/phantomjs/downloads/${PHANTOMJS_VERSION}.tar.bz2
RUN tar xvf ${PHANTOMJS_VERSION}.tar.bz2
RUN mv ${PHANTOMJS_VERSION}/bin/phantomjs /usr/local/bin/
RUN rm -rf phantom*

RUN mkdir -p ${PHANTOMJS_DIR}
RUN echo '"use strict"; \n\
  console.log("Hello, world!"); + \n\
  console.log("using PhantomJS version " + \n\
  phantom.version.major + "." + \n\
  phantom.version.minor + "." + \n\
  phantom.version.patch); \n\
  phantom.exit();' \
  > ${PHANTOMJS_DIR}/script.js

RUN  apt-get update -y && apt-get install -y \
      git \
      python \
     && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/n1k0/casperjs.git
RUN mv casperjs /opt/
RUN ln -sf /opt/casperjs/bin/casperjs /usr/local/bin/casperjs

Q: How to compose docker-compose.yml so i can access deamon's container from php?

答:您可以共享 docker 的 unix domain socket 来访问守护进程的容器。

类似如下:

docker-compose.yml:

version: '3'
services:
  app:
    image: ubuntu:16.04
    privileged: true
    volumes:
      - /usr/bin/docker:/usr/bin/docker
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7
    command: docker run --rm vitr/casperjs casperjs --version

测试:

# docker-compose up
WARNING: Found orphan containers (abc_plop_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Recreating abc_app_1 ... done
Attaching to abc_app_1
app_1  | 1.1.4
abc_app_1 exited with code 0

你可以看到 1.1.4 是在 app container 中通过执行命令 docker run --rm vitr/casperjs casperjs --version 打印出来的。

这只是一个例子,你可以在自己的php container中调用docker run --rm vitr/casperjs casperjs --version而不是使用ubuntu:16.04,仍然在php代码中使用exec并且得到输出。

更新:(2018/11/05)

首先我觉得有些概念需要和你保持一致:

  • -d:这意味着start a container in detached mode,而不是daemon。在docker中,当我们谈到daemon时,意思是docker daemon,它曾经接受docker cli的连接,见here

  • --rm:这个只是为了删除temp container用完了,你也可以不用。

使用 -dno -d 的区别:

  • With -d:它将 运行 容器处于分离模式,这意味着即使容器 运行ning,cli 命令 docker run,也会立即退出并显示容器 ID,您不会看到任何日志,如下所示:

    # docker run -d vitr/casperjs casperjs --version d8dc585bc9e3cc577cab15ff665b98d798d95bc369c876d6da31210f625b81e0

  • Without -d:cli命令直到container命令完成才会退出,所以你可以看到命令的输出,如下:

    # docker run vitr/casperjs casperjs --version 1.1.4

所以,你的要求是想要得到 casperjs 的输出,我想你肯定必须使用 no -d 模式。

如果你接受了以上的概念,那么你可以继续看一个可行的例子:

文件夹结构:

abc
├── docker-compose.yml
└── index.php

docker-compose.yml:

version: '3'
services:
  phpfpm:
    container_name: phpfpm
    image: nanoninja/php-fpm
    entrypoint: php index.php
    privileged: true
    volumes:
      - .:/var/www/html
      - /usr/bin/docker:/usr/bin/docker
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7

index.php:

<?php
exec('docker run vitr/casperjs casperjs --version', $output);
print_r($output);

测试:

~/abc# docker-compose up
Starting phpfpm ... done
Attaching to phpfpm
phpfpm    | Array
phpfpm    | (
phpfpm    |     [0] => 1.1.4
phpfpm    | )
phpfpm exited with code 0

可以看到1.1.4是通过php打印出来的,注意privileged&volumes是必须设置的东西。