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:
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/webin the container which is odd since that folder is owned byrootand well .... isrootI 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
/webto 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.
- 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 updateso you download the libraries needed by the project. - Add
symfonyapp.localto 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.
2 Answers
Answers 1
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.
Answers 2
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
/web... is 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 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.
0 comments:
Post a Comment