使用Docker容纳Apache,MySQL和PHP

I've been searching the web and reading manuals and I just can't seem to get my head around what is wrong with my Docker setup.

The Goal

To container-ize Apache, PHP and MySQL allowing them to be customized on a per-project basis. The only dependency to deploy the stack should be docker. All other dependencies / actions should be able to be able to be built / run via Dockerfile.

The Proof of Concept

From my Apache + MySQL + PHP stack via docker-compose.yml file - I'd like to target an index.php page to successfully render Hello Docker! along with a list of all available databases.

The Problem

When I visit docker.dev/index.php in my browser, rather than the PHP code running, I can only view the PHP source code. This is what I see:

<?php

/**
 * This file:
 *     Has not been tested
 *     Does not use prepared statements
 *     Is for Proof of Concept only!
 */

$host = '127.0.0.1';
$user = 'root';
$pass = 'docker';

$conn = new mysqli($host, $user, $pass);

$sql = 'show databases';
$results = $conn->query($sql);

?>

<h1>Hello Docker!</h1>

<ul>
    <?php while ($row = $results->fetch_assoc()) : ?>
        <li><?= $row['Database'] ?></li>
    <?php endwhile ?>
</ul>

My understanding (which may be mistaken) is that Apache is correctly handling the virtual host, but doesn't know to load the PHP file through an Apache PHP Module.

I have setup Apache to depends_on PHP and I have linked them through a network (along with MySQL) but obviously I'm missing something or else everything would be working just as I want it to).

I have created an repo on github that should allow you to test my setup with a few simple commands:

git clone https://github.com/dambrogia/docker-testing.git
cd docker-testing
docker-compose up -d

You will also have to edit add docker.dev to 127.0.0.1 in your hosts file on your host machine!

How can I render the PHP rather than read the source of it when I visit docker.dev/index.php?

I do not want to use a PHP and Apache combined image if at all possible. I would like to have three separate containers - PHP, Apache, MySQL.

duanmei1894
duanmei1894 我之所以要问的是,如果您安装标准PHP容器的许多版本之一-他们已经安装了Apache。您需要做的就是启动您需要的PHP容器。但是因为这有Apache,你说你想要一个不同的容器-因此这个问题。
大约 3 年之前 回复
drqn5418
drqn5418 是什么让你相信它不可能?您能提供文件,链接或仅详细说明您的任何一份陈述吗?谢谢你的回复!非常感谢!
大约 3 年之前 回复
duanbai1370
duanbai1370 -因为我不同的项目使用不同版本的PHP,有时取决于需要做什么。我不想被归入一个静态设置。我希望我的设置在这个方面是动态的,IMO是docker的全部要点。谢谢你的回复!非常感谢!
大约 3 年之前 回复
duanli6834
duanli6834 我不确定它是否可能。但可以肯定的是,Nginx,PHP可能有单独的容器
大约 3 年之前 回复
dongpan3001
dongpan3001 是否有任何特殊原因不希望Apache和PHP捆绑在一起?
大约 3 年之前 回复

3个回答



我解决了这个问题,并为任何有兴趣深入解释或概念证明的人创建了一个回购。</ p> \ n

请参阅我的回购: https://github.com/dambrogia/docker-testing </ p>

TL; DR </ h2>

我用来解决此问题的方法是通过 fcgi:// php将所有 .php </ code>文件的apache请求代理到PHP-FPM: 9000 </代码>。 端口9000是默认值</ p>

您可以在运行中看到此Apache设置这里。</ p>

/ var / www / html / $ 1 </ code> 设置的一部分是文件在PHP容器中的映射位置。</ p>
</ div>

展开原文

原文

I solved this question and created a repo for anyone who is interested a more in depth explanation or proof of concept.

Please see my repo: https://github.com/dambrogia/docker-testing

TL; DR

The approach I used to solve this was proxying all apache requests to any .php files to PHP-FPM via fcgi://php:9000. Port 9000 is the default

You can see this Apache setting in action here.

The /var/www/html/$1 portion of the setting is where the files are mapped within the PHP container.

If you're working with PHP, and you wish to have a single process per container, then I do recommend using Nginx and using PHP-FPM, as it's significantly easier to configure than Apache for this type of setup (at least that's what I've found).

You need to ensure you have a common shared volume to both the Nginx and PHP containers. In that volume you would have your index.php. Here is a crude example docker-compose.yml:

services:
  php7:
    image: "php:7.1.10-fpm"
    container_name: "prefix-php"
    volumes:
      - "./your/local/dir:/var/www/html"
  nginx:
    image: "nginx:1.13.6"
    container_name: "prefix-nginx"
    ports:
      - "80:80"
      - "443:443"
    links:
      - "php7"
    volumes:
      - "./your/local/dir:/var/www/html"

You would then run this following command in the directory where the docker-compose.yml file is:

$ docker-compose -p prefix

The reason for "prefix" is that you create a project grouping for your containers so as not to clash with other container names.

Naturally you then need an nginx site configuration that points to /var/www/html. You will have little to no configuration requirements for the php-fpm container.

A side note regarding the nginx configuration. The above docker-compose.yml is incomplete without the referencing of the php container within the nginx configuration. This would look like so (roughly speaking):

server {
    listen 80 default_server;

    # ...more config, like root, index, server_name, etc

    location ~* \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass prefix-php:9000; # Note the container name here.
        fastcgi_index index.php;
        fastcgi_hide_header X-Powered-By;
        fastcgi_read_timeout 300s;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # ...more rules
}

You'll notice I named the container "php7", you could actually add another "php5" container to this docker-compose.yml and then that allows you to define nginx sites that use different versions of PHP all running on the same docker-compose setup.

I appreciate that this doesn't directly answer your question as it doesn't solve it using apache, but it's an alternative to consider.

Hopefully this at least gives you ideas to help solve your setup.

duandui2803
duandui2803 你的答案的最新更新,看起来你比你原来的更进一步
接近 3 年之前 回复
doufu9521
doufu9521 nps,很高兴能帮到你。 我知道这不是你要找的答案,并且同意你的答案是正确的。
接近 3 年之前 回复
douyinyi7766
douyinyi7766 我只是编辑了我的答案,包括一个小的nginx网站配置示例,它演示了如何使用php容器的名称。 由于链接:config,nginx容器“知道”有关php容器的信息。 / dock / hosts记录由docker添加和管理,以便链接的容器可以进行通信。 作为那些阅读的笔记。 答案包含“版本2”docker-compose,“版本3”但是建议使用网络:而不是链接:
接近 3 年之前 回复
donglu9134
donglu9134 我赞成戴夫应该给他+10。 虽然他确实让我使用nginx正确的方向 - 1.我最初的问题是针对apache和2.关键是PHP FPM并将PHP文件的apache请求代理到PHP FPM容器。 他的答案是非常有建设性的,并帮助我的调试过程(如果没有它,我可能不会找到解决方案,因此upvote)但我自信地认为我的答案是正确的答案。 我的意图不是帮助/伤害任何人的代表,而是为了让信息更广泛地提供给正在寻找的任何人。
接近 3 年之前 回复
dongzhi6927
dongzhi6927 出于兴趣,Dave,nginx容器如何从您的配置中知道哪个容器转发PHP请求? 我看到有一个链接条目,但AFAIK只让Docker Compose了解启动服务的顺序。
接近 3 年之前 回复
douwen9534
douwen9534 顺便说一句,值得注意的是,如果你接受别人的答案,他们会获得+15声望,如果你接受自己的声望,你就会获得+0。 所以,虽然您可以自由接受自己的答案,但您会考虑优先接受Dave吗? 这似乎与您实际使用的解决方案一致。
接近 3 年之前 回复
doukang2003
doukang2003 感谢您的详细解答,@ AlexKapustin也提前推荐了nginx,所以我稍微进入了nginx世界。 我使用你在这里推荐的相同类型的设置,所以你提供的肯定是一个可行和有前途的解决方案。 我把我从nginx学到的东西(以及代理:9000用于fpm)和我正在将它应用于Apache设置并获得更多运气。 我很快就会有更新的解决方案。 感谢您的回复,它肯定可以帮助其他人在路上!
大约 3 年之前 回复



你遇到了“容器应该做一件事”的模因,这很好,但这并不意味着你应该 把它拆分到目前为止。 一个LAMP容器在Docker-land中是完全正常的,我不知道在分解Apache和PHP方面做了哪些努力 - 我怀疑这是浪费工程努力。</ p>

As 你说,你希望能够运行不同的PHP版本。 这绝对没问题,您应该在 Dockerfile </ code>中自定义它。 如果您打算构建一组服务可以继承的容器,那么您可以简单地拥有一个基本的Apache容器,在继承 Dockerfile </ code>的基础上添加PHP。</ p>

我运行一组微服务,它们使用5.6和7.0的混合。 它们都来自非常简单的 alpine </ code>(不同版本:3.5,3.6和最新版本,将成为3.7)。 复制并粘贴我的 Dockerfile </ code>要求大约需要15分钟,加上我可能会做的一些容器调整。 所以,如果你的目标是一套准备好的容器,我不确定你在实践中节省了多少时间。</ p>

如果你真的</ em>想要追求这个,你可以看看 Piwik 使用的机制 。 我不熟悉它,但PHP容器提供FastCGI,需要由另一个容器中的Web服务器代理。</ p>
</ div>

展开原文

原文

You've encountered the meme of "containers should do one thing", which is fine, but it does not mean that you ought to split it down this far. A LAMP container is perfectly normal in Docker-land, and I don't know what efforts have been made to split up Apache and PHP - I suspect it is waste of engineering effort.

As you say, you wish to be able to run different PHP versions. That's absolutely fine, and you should customise that in your Dockerfile. If your intention is to build a set of containers that your services can inherit from, then you could simply have a base Apache container, upon which you add PHP in inheriting Dockerfiles.

I run a set of microservices, which use a mix of 5.6 and 7.0. They all inherit from a very plain alpine (of varying versions: 3.5, 3.6 and latest, which will become 3.7). It takes about 15 minutes to copy-and-paste my Dockerfile requirements on top, plus a bit of container tweaking that I'd probably do anyway. So, if a ready-to-run set of containers is your aim, I am not sure how much time you'd be saving in practice.

That all said, if you really want to pursue this, you could look into the mechanism that Piwik uses. I am not familiar with it, but the PHP container serves FastCGI, and that needs to be proxied by a web server, in another container.

dou8mwz5079
dou8mwz5079 哦亲爱的,这篇文章似乎不太受欢迎。 有人想提供一些反馈意见吗?
接近 3 年之前 回复
立即提问
相关内容推荐