Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

PHP file_put_contents() in docker container can not write to underlying ubuntu operating system

I am learning to use Docker to host a php application. I tried making a simple index.php that will write a hello world to a test.txt file to my underlying ubuntu operating system. But I am running into a lot of issues no matter what I try. I started off with these 3 files:

// ~/docker/docker-compose.yml
version: "3.8"
services:
  website:
    container_name: website
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "80:80"
    volumes:
      - ../public_html:/var/www/html
    logging:
      options:
        max-file: "10"
        max-size: 10m

// ~/docker/Dockerfile
FROM php:5.4-apache

RUN chown -R www-data:www-data /var/www/html

CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]

// ~/public_html/index.php

<?php file_put_contents('test.txt', 'hello world');

I start up the project with these "start up" commands:

john@localhost: sudo su
root@localhost: systemctl start docker
root@localhost: exit
john@localhost: sudo chown -R john:john ~/docker
john@localhost: sudo chown -R john:john ~/public_html
john@localhost: sudo chmod -R 755 ~/public_html
john@localhost: cd ~/docker
john@localhost: sudo docker-compose up --build -d;

The user john has sudo privileges.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

When I visit my web page at http://192.168.0.10/index.php, I see the error message

Warning: file_put_contents(test.txt): failed to open stream: Permission denied in /var/www/html/index.php on line 1

I can work around the problem by running this command from my ubuntu host machine:

touch ~/public_html/test.txt && chmod 777 ~/public_html/test.txt

But I really want to keep permissions to 755.

I read that I have to keep the all the user ids aligned between my host ubuntu machine and guest containers. So I tried a few things, but everyone of my attempts causes the docker container to fail and not even start up. This was my most recent attempt along with the error seen:

// ~/docker/.env
// when I did `id -u`, i saw the value 1000.  So I will assign it to an env variable
CURRENT_UID=1000

// ~/docker/docker-compose.yml
version: "3.8"
services:
  website:
    container_name: website
    user: ${CURRENT_UID}
    environment:
      CURRENT_UID: ${CURRENT_UID}
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "80:80"
    volumes:
      - ../public_html:/var/www/html
    logging:
      options:
        max-file: "10"
        max-size: 10m

// ~/docker/Dockerfile
FROM php:5.4-apache

USER ${CURRENT_UID}:${CURRENT_UID}
RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /var/www/html
RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /etc/apache2
RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /var/log/apache2
RUN chown -R ${CURRENT_UID}:${CURRENT_UID} /var/run/apache2

CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]

The container fails to start when I run the "start up" commands. I do a sudo docker logs website and it shows:

[Wed Jun 28 23:01:18.623744 2023] [core:error] [pid 7] (13)Permission denied: AH00099: could not create /var/run/apache2/apache2.pid
[Wed Jun 28 23:01:18.623918 2023] [core:error] [pid 7] AH00100: apache2: could not log pid to file /var/run/apache2/apache2.pid
Action '-D FOREGROUND' failed.
The Apache error log may have more information

Can anyone tell me what am I doing wrong? Is there a way to look at the Apache error logs after the container fails?

>Solution :

Docker does not respect the host system’s passwd config, and does not run as your UID, it runs as whatever user happens to be configured in the image, which maps to whatever UID is in the image’s passwd file. In this case the image runs as root to start apache, which then does a setuid/setgid to www-data [UID/GID 33] according to it’s configuration.

After using the chmod 777 kludge you should be able to see the UID/GID that the files were created under with ls -an.

You’ll either need to:

  • Change the ownership of the mounted volumes to UID/GID 33, eg chown -R 33:33 ~/public_html
  • Customize the image to add a user/group with UID/GID matching the host UID/GID you want to use, and then configure apache to run as that user.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading