docker - "AH01071: Got error ' 无法打开主脚本“: Container permissions or Symfony3 issue?

标签 docker symfony docker-compose

我正在尝试使用 Docker 和 Docker Compose 在“LAMP”堆栈中运行 Symfony 3“基本”应用程序(意味着完全不复杂,只安装了一些包,但甚至没有启用)(我已从其中删除了 MySQL)该帖子,因为它不相关)。这是我的 docker-compose.yml 文件:

version: '2'
services:
  php-fpm:
    build: docker/php-fpm
    ports:
        - "80:80"
    volumes:
      - ./sources:/data/www
      - ./data/logs/symfony:/data/www/var/logs
  db:
    image: mysql
    environment:
        MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
        MYSQL_DATABASE: ${MYSQL_DATABASE}
        MYSQL_USER: ${MYSQL_USER}
        MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
        - sql-data:/var/lib/mysql

这是 php-fpm 容器的 Dockerfile:

FROM reynierpm/docker-centos7-supervisord:latest
ENV TERM=xterm \
    PATH="/root/.composer/vendor/bin:${PATH}" \
    COMPOSER_ALLOW_SUPERUSER=1
RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
                   https://rpms.remirepo.net/enterprise/remi-release-7.rpm
RUN yum install -y  \
        yum-utils \
        git \
        zip \
        unzip \
        nano \
        httpd \
        php71-php-fpm \
        php71-php-cli \
        php71-php-common \
        php71-php-gd \
        php71-php-intl \
        php71-php-json \
        php71-php-mbstring \
        php71-php-mcrypt \
        php71-php-mysqlnd \
        php71-php-pdo \
        php71-php-pear \
        php71-php-xml \
        php71-pecl-apcu \
        php71-php-pecl-apfd \
        php71-php-pecl-memcache \
        php71-php-pecl-memcached \
        php71-php-pecl-mongodb \
        php71-php-pecl-redis \
        php71-php-pecl-request \
        php71-php-pecl-uploadprogress \
        php71-php-pecl-xattr \
        php71-php-pecl-zip && \
        yum clean all && rm -rf /tmp/yum*

RUN rm -f /etc/httpd/conf/httpd.conf /etc/httpd/conf.d/* /etc/httpd/conf.modules.d/* && \
    ln -sfF /opt/remi/php71/enable /etc/profile.d/php71-paths.sh && \
    ln -sfF /opt/remi/php71/root/usr/bin/{pear,pecl,phar,php,php-cgi,phpize} /usr/local/bin/. && \
    mv -f /etc/opt/remi/php71/php.ini /etc/php.ini && \
    ln -s /etc/php.ini /etc/opt/remi/php71/php.ini && \
    rm -rf /etc/php.d && \
    mv /etc/opt/remi/php71/php.d /etc/. && \
    ln -s /etc/php.d /etc/opt/remi/php71/php.d

RUN curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony && \
    chmod a+x /usr/local/bin/symfony

COPY container-files /

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
    composer global install --no-dev

RUN yum install -y php71-php-pecl-xdebug && \
    yum clean all && rm -rf /tmp/yum* && \
    php --version

RUN chmod +x /config/bootstrap.sh
RUN echo 'alias sf="php bin/console"' >> ~/.bashrc

WORKDIR /data/www
EXPOSE 80 9001

问题是,如果我尝试使用 http://symfonyapp.local/app_dev.php 访问 dev 环境,我总是会收到此错误:

php-fpm  | [Sat Jan 14 15:09:27.655609 2017] [proxy_fcgi:error] [pid 13:tid 140600250660608] [client 172.18.0.1:43960] AH01071: Got error 'Unable to open primary script: /data/www/web/_wdt/210673 (No such file or directory)\n', referer: http://symfonyapp.local/app_dev.php

出现上述错误我可以思考:

  • 容器中 /data/www/web 的所有权|权限问题很奇怪,因为该文件夹归 root 所有,而且 .... 是 root我不需要解释
  • Symfony3 出了点问题,我不知道,而且到目前为止我也找不到它
  • Apache|PHP-FPM 无法在此类文件夹上写入,从而导致此列表中的第一项
  • Apache config阻止写入目录 /web。 ( mod_scurity 没有运行,所以我不能责怪它)

这是我迄今为止尝试过的方法,但没有成功,因为我仍然总是遇到相同的错误。

  1. 更改容器中的所有权/权限(这会在 Linux 中导致错误,因为卷中的权限也会在主机中更改,但在 Windows 中不会发生同样的情况)。下面是我如何实现这样的事情的解释。
<小时/>

如何更改所有权/权限的简要说明:

php-fpm Dockerfile 继承自docker-centos7-supervisord,其中包含 script作为ENTRYPOINT。所以我创建了一个文件 /container-files/config/init/20-permissions.sh包含以下内容:

#!/usr/bin/env bash

chown -R apache:root /data/www && \
find /data/www -type d -print0 | xargs -0 chmod 775 && \
find /data/www -type f -print0 | xargs -0 chmod 664
echo "Set up permissions finished"

exec "$@"
<小时/>

上面的文件在容器启动并安装卷后执行。我确实知道该文件已执行,因为我在 php-fpm 容器日志中看到设置权限已完成。但这很奇怪,因为在向我显示以下内容后检查所有权/权限:

> docker exec -it php-fpm ls -la /data/www/web
total 57
drwxr-xr-x 2 root root  4096 Jan 14 03:45 .
drwxr-xr-x 2 root root  4096 Jan 14 00:40 ..
-rwxr-xr-x 1 root root  3319 Jan 13 23:54 .htaccess
-rwxr-xr-x 1 root root   635 Jan 14 03:45 app.php
-rwxr-xr-x 1 root root  1184 Jan 14 03:45 app_dev.php
-rwxr-xr-x 1 root root  2092 Jan 13 23:54 apple-touch-icon.png
drwxr-xr-x 2 root root     0 Dec 13 13:36 bundles
-rwxr-xr-x 1 root root 21244 Jan 14 00:04 config.php
-rwxr-xr-x 1 root root  6518 Jan 13 23:54 favicon.ico
-rwxr-xr-x 1 root root   116 Jan 13 23:54 robots.txt

所以在这种情况下,我不确定这是否进展顺利,或者是否有可能。我创建了一个包含两个分支的存储库,其中包含尝试此操作所需的所有必要条件:master将 httpd 和 php-fpm 放在一个容器中并且 httpd将它们放在单独的容器中。虽然两者的结果是相同的。

要让一切正常运行,您应该:

  • 运行docker-compose up -d --build --force-recreate(--force-recreate和--build不是必需的,但以防万一)
  • 运行docker exec -it php-fpm Composer update以便下载项目所需的库。
  • symfonyapp.local 添加到您的主机文件

目前我在 Windows 中使用 Docker,这是有关它的信息:

Version: 1.13.0-rc6-beta36 (9696)
Channel: Beta
Sha1: 64a715b54327a0ec8f28076d1a343f4c811856fb
Started on: 2017/01/13 18:34:34.519
Resources: C:\Program Files\Docker\Docker\Resources
OS: Windows 10 Pro
Edition: Professional
Id: 1607
Build: 14393
BuildLabName: 14393.693.amd64fre.rs1_release.161220-1747

但我也在 Linux 中对此进行了测试,并且我有相同的行为,这意味着错误仍然存​​在。

这里发生了什么?你能给我一些想法或解决方案吗?此时我已经脱离了他们,不知道还能做什么。

最佳答案

TL;DR:composer 更新期间引入了权限问题。可能在其中一个脚本期间(可以在 composer.json 中找到其列表)。

我使用您的存储库在虚拟机上从头开始,并按照您的启动说明进行操作。

git clone https://github.com/reypm/symfony3app
cd symfony3app
docker-compose up -d --build --force-recreate

此时,20-permissions.sh 中的 chown 应该已运行。为了验证这一点,我查看了容器内部。我看到的错误与 /data/www/var/cache/dev 相关,因此我查看了该路径中每个目录的权限。

[my-vm]# docker-compose exec php-fpm bash
[container]# ls -la /data/www{,/var{,/cache{,/dev}}}

ls: cannot access /data/www/var/cache/dev: No such file or directory
/data/www:
total 168
drwxrwsr-x 8 apache root   4096 Jan 15 19:26 .
drwxr-xr-x 8 root   root   4096 Jan 15 19:27 ..
-rw-rw-r-- 1 apache root    248 Jan 15 19:26 .gitignore
-rw-rw-r-- 1 apache root     74 Jan 15 19:26 README.md
drwxrwsr-x 5 apache root   4096 Jan 15 19:27 app
drwxrwsr-x 2 apache root   4096 Jan 15 19:26 bin
-rw-rw-r-- 1 apache root   2387 Jan 15 19:26 composer.json
-rw-rw-r-- 1 apache root 119533 Jan 15 19:26 composer.lock
-rw-rw-r-- 1 apache root    978 Jan 15 19:26 phpunit.xml.dist
drwxrwsr-x 3 apache root   4096 Jan 15 19:26 src
drwxrwsr-x 3 apache root   4096 Jan 15 19:26 tests
drwxrwsr-x 4 apache root   4096 Jan 15 19:26 var
drwxrwsr-x 2 apache root   4096 Jan 15 19:26 web

/data/www/var:
total 52
drwxrwsr-x 4 apache root  4096 Jan 15 19:26 .
drwxrwsr-x 8 apache root  4096 Jan 15 19:26 ..
-rw-rw-r-- 1 apache root 34272 Jan 15 19:26 SymfonyRequirements.php
drwxrwsr-x 2 apache root  4096 Jan 15 19:26 cache
drwxrwsr-x 2 apache root  4096 Jan 15 19:26 sessions

/data/www/var/cache:
total 8
drwxrwsr-x 2 apache root 4096 Jan 15 19:26 .
drwxrwsr-x 4 apache root 4096 Jan 15 19:26 ..
-rw-rw-r-- 1 apache root    0 Jan 15 19:26 .gitkeep

到目前为止,一切都很好。 chown 已将所有内容设置为 apache:root 并使用脚本中指定的模式。

接下来,我退出容器并运行 Composer 更新。

docker-compose exec php-fpm composer update

出现提示时,我使用了在 git 存储库中找到的数据库参数,一切都安装得很好。接下来,我回到容器中查看权限是否已更改。

[my-vm]# docker-compose exec php-fpm bash
[container]# ls -la /data/www{,/var{,/cache{,/dev}}}

/data/www:
total 164
drwxrwsr-x  9 apache root   4096 Jan 15 19:20 .
drwxr-xr-x  8 root   root   4096 Jan 15 19:18 ..
-rw-rw-r--  1 apache root    248 Jan 15 19:17 .gitignore
-rw-rw-r--  1 apache root     74 Jan 15 19:17 README.md
drwxrwsr-x  5 apache root   4096 Jan 15 19:18 app
drwxrwsr-x  2 apache root   4096 Jan 15 19:21 bin
-rw-rw-r--  1 apache root   2387 Jan 15 19:17 composer.json
-rw-rw-r--  1 apache root 114331 Jan 15 19:20 composer.lock
-rw-rw-r--  1 apache root    978 Jan 15 19:17 phpunit.xml.dist
drwxrwsr-x  3 apache root   4096 Jan 15 19:17 src
drwxrwsr-x  3 apache root   4096 Jan 15 19:17 tests
drwxrwsr-x  5 apache root   4096 Jan 15 19:21 var
drwxr-sr-x 25 root   root   4096 Jan 15 19:21 vendor
drwxrwsr-x  3 apache root   4096 Jan 15 19:21 web

/data/www/var:
total 96
drwxrwsr-x 5 apache root  4096 Jan 15 19:21 .
drwxrwsr-x 9 apache root  4096 Jan 15 19:20 ..
-rw-rw-r-- 1 apache root 34272 Jan 15 19:21 SymfonyRequirements.php
-rw-r--r-- 1 root   root 39637 Jan 15 19:21 bootstrap.php.cache
drwxrwsr-x 3 apache root  4096 Jan 15 19:21 cache
drwxr-sr-x 2 root   root  4096 Jan 15 19:21 logs
drwxrwsr-x 2 apache root  4096 Jan 15 19:17 sessions

/data/www/var/cache:
total 12
drwxrwsr-x 3 apache root 4096 Jan 15 19:21 .
drwxrwsr-x 5 apache root 4096 Jan 15 19:21 ..
-rw-rw-r-- 1 apache root    0 Jan 15 19:17 .gitkeep
drwxr-sr-x 4 root   root 4096 Jan 15 19:21 dev

/data/www/var/cache/dev:
total 636
drwxr-sr-x 4 root   root   4096 Jan 15 19:21 .
drwxrwsr-x 3 apache root   4096 Jan 15 19:21 ..
-rw-r--r-- 1 root   root     90 Jan 15 19:21 annotations.map
-rw-r--r-- 1 root   root 277718 Jan 15 19:21 appDevDebugProjectContainer.php
-rw-r--r-- 1 root   root  38062 Jan 15 19:21 appDevDebugProjectContainer.php.meta
-rw-r--r-- 1 root   root 213247 Jan 15 19:21 appDevDebugProjectContainer.xml
-rw-r--r-- 1 root   root  84170 Jan 15 19:21 appDevDebugProjectContainerCompiler.log
-rw-r--r-- 1 root   root   4790 Jan 15 19:21 classes.map
drwxr-sr-x 3 root   root   4096 Jan 15 19:21 doctrine
drwxr-sr-x 4 root   root   4096 Jan 15 19:21 pools

如您所见,有些内容现在归 root:root 所有。据我所知,这只是因为容器本身以 root 身份运行。因此,当您在内部执行作业时,该作业将以 root 身份运行。因此,默认情况下,它创建的任何内容都归 root 所有。

同时,Apache 以用户“apache”运行,因为这就是supervisord 的配置目的。

对于这个问题可能有更优雅的解决方案,但这是我想到的最简单的一个:

docker-compose exec php-fpm chown -R apache:root /data/www/var/cache
docker-compose restart php-fpm

之后,应用程序返回

Welcome to Symfony 3.2.2

Your application is now ready. You can start working on it at: /data/www/

我还没有尝试过比这更好的解决办法。但我的建议是尝试让启动程序为您运行 Composer 更新,然后执行 chown 工作。您可能不需要 chown 全部 /data/www,因为 Apache 可能不需要对其中的所有内容进行写入权限。我的猜测是缓存目录是它需要写入的地方,所以我更改了该路径。

关于docker - "AH01071: Got error ' 无法打开主脚本“: Container permissions or Symfony3 issue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41646272/

相关文章:

docker - 将nginx容器ip动态添加到phpfpm/etc/hosts文件中

amazon-web-services - 从 docker 容器内部连接到主机的辅助 IP

symfony - Docker 与 Symfony 4 - 无法看到文件更改

symfony - 原始内容的 Twig UTF-8 编码

php - 嵌入名为 “Button” : the prototype contains a wrong form 的实体的表单集合

node.js - 使用 docker-compose 对 Node Express 应用程序进行 Docker 化

docker - 错误状态终止的Kubernetes Pod终止

python-2.7 - 使用 docker-py 从容器运行和共享主机文件夹

docker - 如何从Docker容器内部访问boot2docker-ip

sql-server - Docker-在 Composer 之前或之后运行Dockerfile的方式如何?