“AH01071: Got error 'Unable to open primary script”: Container permissions or Symfony3 issue?

I am trying to run a Symfony 3 “base” application (meaning non complexity at all and just a few bundles installed but not even enabled) in a “LAMP” stack using Docker and Docker Compose (I’ve removed MySQL from the post because it’s not relevant). This is my docker-compose.yml file:

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

And this is the Dockerfile for the php-fpm container:

  • Dockerized PostgreSQL: psql: FATAL: the database system is starting up
  • Difference between containers (Docker) and IIS
  • Cannot push images to Dockerhub
  • docker-registry v2.2.0 S3 config not overwritten
  • How do I scale up my cluster on Google Container Engine / Kubernetes?
  • create a pure data image in docker
  • 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
    

    The thing is I am getting this error all the time if I try to access the dev environment using http://symfonyapp.local/app_dev.php:

    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
    

    Having the error above I can think in:

    • Ownership|permissions issue at /data/www/web in the container which is odd since that folder is owned by root and well …. is root I don’t need to explain
    • Something is failing with Symfony3 and I’m not aware of it also I couldn’t find it so far
    • Apache|PHP-FPM can’t write on such folder which leads to the first item on this list
    • Apache config is blocking the directory /web to be written. (mod_scurity is not running so I can’t blame it)

    This is what I’ve tried so far without success because I am still getting the same error all the time.

    1. Change ownership/permissions in the container (this lead into an error in Linux since permissions in volumes are changed in host as well, the same doesn’t happen in Windows). Below is an explanation in how do I achieve such thing.

    Brief explanation in how do I change ownership/permissions:

    The php-fpm Dockerfile is inherit from docker-centos7-supervisord which has this script as ENTRYPOINT. So I have created a file /container-files/config/init/20-permissions.sh with the following content:

    #!/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 "$@"
    

    The file above gets executed after container starts and volumes are mounted. I did know the file is executed because I am seeing Set up permissions finished in the php-fpm container logs. It’s weird though because checking ownership/permissions after show me the following:

    > 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
    

    So in this case I am not sure if this is going well or if it’s possible even. I have created a repository with two branches with all the necessary to gives this a try: master having httpd and php-fpm both in one container and httpd having them in separated containers. Although the result in both is the same.

    To get everything up and running you should:

    • Run docker-compose up -d --build --force-recreate (the –force-recreate and –build are not necessary but is just in case)
    • Run docker exec -it php-fpm composer update so you download the libraries needed by the project.
    • Add symfonyapp.local to your hosts files

    Currently I am using Docker in Windows, this is the info about it:

    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
    

    But I have tested this in Linux as well and I have the same behavior meaning the error still there.

    What is happening here? Can you give me some ideas or solution? At this point I am out of them and don’t know what else to do.

  • Docker's behavior when mounting volumes
  • How can I improve the performance of my Boot2Docker vm
  • How to delete all Docker local Docker images
  • Docker MAC Address Generation
  • What are the different ways of implementing Docker FROM?
  • Docker configuration using the systemd configuration style
  • 2 Solutions collect form web for ““AH01071: Got error 'Unable to open primary script”: Container permissions or Symfony3 issue?”

    TL;DR: The permission problem is being introduced during composer update. Possibly during one of the scripts (a list of which can be found in composer.json).

    I started from scratch on a VM with your repository and followed your startup instructions.

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

    At this point, the chown from 20-permissions.sh should have been run. To verify that, I looked inside the container. The error I have seen related to /data/www/var/cache/dev, so I looked at the permissions on every directory in that path.

    [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
    

    So far, so good. The chown has set everything to apache:root and using the modes specified in the script.

    Next, I exited the container and ran the composer update.

    docker-compose exec php-fpm composer update
    

    When prompted, I used the database parameters I found in the git repo, and everything installed fine. Next, I went back into the container to see if the permissions had changed.

    [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
    

    As you can see, some things are now owned by root:root. As far as I can tell, this is simply because the container itself runs things as root. So when you exec a job inside, that job is run as root. Therefore, anything it creates is, by default, owned by root.

    Meanwhile, Apache runs as the user “apache”, because that is what supervisord is configured to do.

    There are probably more elegant fixes for this problem, but this one was the simplest one I came up with:

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

    After that, the app returns

    Welcome to
    Symfony 3.2.2

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

    I haven’t tried to fix things any better than this. But my suggestion would be to try to have the startup run composer update for you and do the chown job after that. You probably don’t need to chown all of /data/www, as Apache probably doesn’t need write privs to everything in there. My guess was that the cache directory is one place it needs to write, so I chown’d that path.

    After spent days and hours trying to get this working I finally got it thanks to Symfony #support channel in Slack and to the following channels on the IRC #symfony, #httpd, #php, #docker and last but not least to @DanLowe who takes the time to find a solution and help me out with the issue.

    The facts|thoughts:

    • Is a Symfony 3.2.2 issue … is not
    • Is a Docker running on Windows … is not
    • Is a permission issue on the directory /webis not
    • Is a PHP-FPM problem … is not
    • Is a Apache (httpd) problem … is not

    The problem: A miss configuration in PHP (.ini file) due to a copy & paste from Nginx setup to be used with Apache (previously I was using Nginx and then I moved to Apache leaving the PHP setup as it was).

    // this work in Nginx but does not work in Apache  
    // cgi.fix_pathinfo is required to get PHP to adhere to the CGI spec
    
    ; Fix the cgi.fix_pathinfo directive
    cgi.fix_pathinfo = 0
    

    By default that line is commented in the php.ini file. But waits this could be an issue when PHP is using FastCGI and ProxyPass and so on …. well yes (I read it somewhere before) and no (if you research and set up your server as it should be). The solution to the problem above is comment out the line as it’s by default:

    ; Fix the cgi.fix_pathinfo directive
    ; cgi.fix_pathinfo = 0
    

    The solution to the “security” breach introduced above is and I’ve quoted from here:

    If you have a recent version of PHP-FPM (~5.3.9+?), then you need to
    do nothing, as the safe behaviour below is already the default.

    Otherwise, find php-fpm’s http://www.conf file (maybe
    /etc/php-fpm.d/www.conf, depends on your system). Make sure you have
    this:

    security.limit_extensions = .php

    Again, that’s default in many places these days.

    In my case I am using PHP 7.1 but even though I’ve secured my server by adding such line at my /etc/php-fpm.d/www.conf.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.