1

So I am trying to build a LAMP-app with Docker because I always have issues with installing PHP and such on my local machine.

Currently I am following a tutorial from Brad Traversy: PHP Crash Course on youtube and I am getting stuck at the part where he explains 'filehandling'. Part 14.

This is the error I am getting:

Warning: fopen(users.txt): Failed to open stream: Permission denied in /var/www/html/filehandling.php on line 13
Fatal error: Uncaught TypeError: fwrite(): Argument #1 ($stream) must be of type resource, bool given in /var/www/html/filehandling.php:15 Stack trace: #0 /var/www/html/filehandling.php(15): fwrite(false, 'Brad') #1 {main} thrown in /var/www/html/filehandling.php on line 15

I also added screenshots of the error and file itself, my Dockerfile, and the docker-compose.yaml file.

errormessage in browser

filehandling.php

Dockerfile

docker-compose.yml

When I look up the user with 'whoami', I get user'root' in the Docker container. When I try 'whoami' outside of the container, I get my regular username.

I have tried changing permissions with chmod 755 and chmod 777 inside the Dockerfile, but that didn't work either.

Is there anybody who can help?

Thanks so much in advance!

Following @hakre advice: This is what I get when I do ls -altrh inside of the containers shell:

This is what I get when I do ls -altrh inside the container:

# ls -altrh
total 68K
drwxr-xr-x 1 root root 4.0K Sep 13 09:45 ..
-rwxr-xr-x 1 1000 1000   14 Oct 14 14:57 phpinfo.php
drwxr-xr-x 2 1000 1000 4.0K Oct 14 18:51 db
-rwxr-xr-x 1 1000 1000    0 Oct 15 17:18 .env
-rwxr-xr-x 1 1000 1000   90 Oct 15 17:23 .env.example
-rwxr-xr-x 1 1000 1000    5 Oct 15 17:25 .gitignore
-rwxr-xr-x 1 1000 1000 3.7K Nov  9 17:15 variables.php
-rwxr-xr-x 1 1000 1000  468 Nov  9 17:32 getpost.php
-rwxr-xr-x 1 1000 1000  599 Nov 14 15:15 sanitizinginput.php
-rwxr-xr-x 1 1000 1000  167 Nov 14 15:38 cookies.php
-rwxr-xr-x 1 1000 1000  904 Nov 14 16:03 sessions.php
-rwxr-xr-x 1 1000 1000  225 Nov 19 17:10 package.json
drwxr-xr-x 4 1000 1000 4.0K Nov 20 15:26 .
-rwxr-xr-x 1 1000 1000  734 Nov 20 15:26 docker-compose.yml
-rwxr-xr-x 1 1000 1000  335 Nov 20 15:26 index.php
drwxr-xr-x 2 1000 1000 4.0K Nov 20 16:29 extras
-rwxr-xr-x 1 1000 1000  283 Nov 20 18:07 filehandling.php
-rwxr-xr-x 1 1000 1000   73 Nov 20 18:12 Dockerfile
# 

Edit: Also this is what I get when looking for the user of apache in the container's shell:

# ps aux | egrep '(apache|httpd)'
root           1  0.3  0.1 219560 28892 ?        Ss   09:28   0:00 apache2 -DFOREGROUND
www-data      23  0.0  0.0 219592  7804 ?        S    09:28   0:00 apache2 -DFOREGROUND
www-data      24  0.0  0.0 219592  7804 ?        S    09:28   0:00 apache2 -DFOREGROUND
www-data      25  0.0  0.0 219592  7804 ?        S    09:28   0:00 apache2 -DFOREGROUND
www-data      26  0.0  0.0 219592  7804 ?        S    09:28   0:00 apache2 -DFOREGROUND
www-data      27  0.0  0.0 219592  7804 ?        S    09:28   0:00 apache2 -DFOREGROUND
root          35  0.0  0.0   3180   652 pts/0    S+   09:29   0:00 grep -E (apache|httpd)

And tried changing these in the Dockerfile, not at the same time of course:

RUN chown -R www-data /var/www/html/ 
and this: RUN chown -R www-data:www-data /var/www/html/ 
and this: RUN chown 777 /var/www/html 
and this: RUN chown 777 www-data /var/www/html 

But no success –

DDt
  • 11
  • 3
  • A short hint for the type-error: it will go away when you handle the first warning. If you look closely at the type error message you may already have a clue why that is. The chmod's in the Dockerfile don't persist for that image (and won't further for other images and it's fine to not do that in the first place so to have it removed again). What does `ls -altrh` give when executed within the `www`s' container shell? – hakre Nov 20 '22 at 18:49
  • thanks for replying! My response was too long according to Stackoverflow so I've edited my original post with my response to you. – DDt Nov 20 '22 at 19:42
  • user id (uid) 1234 in the mapping is not the owner of the directory (which is root, 1000 inside the contiainer which is the default user in your rootless docker setup 1000 -> 1 mapping) therefore perhaps not using uid 1234 works directly (and IIRC should be done for your rootless docker, just drop the user namespacing/1234 with it) – hakre Nov 20 '22 at 19:44
  • Im sorry, but could you walk me through these steps? I really don't understand. – DDt Nov 20 '22 at 19:54
  • Sorry, my last comment was pretty rough and I think I've conflated the user-mapping with a different question. First find out under which user the PHP script is executed in your setup, https://serverfault.com/q/125865/69499 may give the pointers. Then provide access to the mount for that user or change the user to your user. The username is likely www-data (user id 33), but you should verify this first. The user-ids are shared between your host and the container. E.g. if you change the group owner of the directory to the container user id, then it should be able to create files in that dir. – hakre Nov 21 '22 at 00:47
  • IIRC when you RUN chown in the Dockerfile it will render void the moment the mount is in effect from the docker compose file as it is at /var/www/html/ . The directory listing from within the running container should confirm this. That is the entry with the single dot `.`. You either need to change the ownership therefore after mount (only change the group to www-data and add your own user on the host to that group on the host [with the same group-id] and raise the permissions for the group) -or- you configure the apache within the container to run under the user-id of your user (1000). – hakre Nov 21 '22 at 17:43
  • sorry, but this is still pretty rough for me. Can you give an example of what it should look like? – DDt Nov 23 '22 at 16:01
  • https://wiki.archlinux.org/title/users_and_groups https://httpd.apache.org/docs/2.4/ https://httpd.apache.org/docs/2.4/getting-started.html https://httpd.apache.org/docs/2.4/mod/mod_unixd.html#user (via https://httpd.apache.org/docs/2.4/mpm.html) – hakre Nov 23 '22 at 21:28

2 Answers2

0

The fopen() function opens a file or URL.

Syntax

fopen(filename, mode, include_path, context)

Example

<?php
$file = fopen("test.txt", "r");

//Output lines until EOF is reached
while(! feof($file)) {
  $line = fgets($file);
  echo $line. "<br>";
}

fclose($file);
?>

Your Issue: Most likely the code is looking in another directory so the directory must be explicitly specified to avoid such errors. It must also ensure that the necessary permissions are obtained.

fopen('/path/to/file/test.txt','r');

You can make this easier by using some functions that make it easier to get your directory

fopen($_SERVER['DOCUMENT_ROOT'].'test.txt','r');

References:

W3Schools fopen Function

PHP: fopen() Permission denied

  • Hi, thank you for your answer. I tried playing around with the paths, but that did not work either unfortunately. – DDt Nov 21 '22 at 09:42
  • Would you please return the current directory, you may use one of the proposed solutions in this link https://stackoverflow.com/questions/9997391/php-get-name-of-current-directory – Abdulkhaliq Ghwainm Nov 22 '22 at 12:58
  • I get this with echo getcwd()in filehandling.php: var/www/html and when I manually create the users.txt file inside of the extras directory, I get this: /var/www/html/extras I think I might have to do something with UID and GID perhaps inside of dockercompose, but no clue on how and where to start – DDt Nov 23 '22 at 16:19
  • please try to use this pice of code `fopen('/var/www/html/extras/test.txt','r');` – Abdulkhaliq Ghwainm Nov 23 '22 at 16:28
  • I tried replacing the variable $file for that piece of code, but that didn't work. – DDt Nov 23 '22 at 16:40
0

I have changed the Dockerfile to this:

FROM php:8.1.10-apache

WORKDIR /var/www/html

RUN docker-php-ext-install mysqli pdo pdo_mysql

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

# Create a new user
RUN adduser --disabled-password --gecos '' developer

# Add user to the group
RUN chown -R developer:www-data /var/www

RUN chmod 755 /var/www

# Switch to this user
USER developer

And also changed the variable's path $file to 'extras/users.txt' again. This worked!

DDt
  • 11
  • 3