wodby / php

Generic PHP docker container images
MIT License
155 stars 103 forks source link

Do not use www-data as default user #22

Closed csandanov closed 6 years ago

csandanov commented 6 years ago
  1. In version 2.x of this image we had root as the default user
  2. Quickly we realized that it's not good (drush and composer don't like to be run from root) and changed it to www-data. User www-data (uid/gid 82) is a de-facto standard in Alpine Linux for php-fpm, nginx, apache packages, something similar to www-data in Debian/Ubuntu
  3. PR https://github.com/wodby/php/pull/18 was posted making a good point that fpm and HTTP server shouldn't have write access to user's files (codebase), as the result we changed fpm user to php-fpm (1000) in 3.5.0
  4. Now, we realized that the way we use www-data is completely wrong, it's a standard system user that comes with a "package" similar to www-data in Debian/Ubuntu that should be used only to run a package daemon, so it's not a usual Linux user and should not be used to log in and manage files
  5. Based on 4 we decided to release 4.x version of stack where we add a new default user wodby with uid/gid 1000 to match user in most Linux distributions. PHP-FPM will run via sudo with FPM user/group set to www-data (82). User wodby will be a part of www-data group.

Feb 16th UPDATED: wodby added to www-data group

csandanov commented 6 years ago

Also, we now have nginx and apache as default users in HTTP servers with UID/GID different from 82 and with only read access.

proteo commented 6 years ago

Hi there. Many thanks for your hard work, this is a definitively a great step forward. Don't know if I'm asking too much, but do you think that could be possible to set the wodby uid/gid using variables on container basis, in a future version? In our shop we've adopted your images as base for pretty much everything we do with Drupal and Wordpress, but we use a mixture of host machines (mostly Macs and some flavors of Linux) for local development so having the ability to set custom ids would be insanely great.

csandanov commented 6 years ago

@Proteo do you want to have docker build arguments for that? are you going to rebuild the image?

What kind of issues do you experience with non-matching uid/gid?

proteo commented 6 years ago

Hi @csandanov, we're actually using slightly modified versions of your repos to build customized images to match a specfic uid:gid using build arguments. For example, in Mac we use 501:20 since usually that's the uid:gid of the user running Docker and of the user working in the code. I know that you can add your user to the group 82 (clamav in macOS) as suggested in the docker4drupal documentation, but having a matching uid makes things way easier for everybody. But the perfect, ideal scenario, would be having the ability to set uid:gid per container_, maybe using something like this which basically takes input from ENV variables set in your docker compose file or run arguments. We actually tried to do something like that, hooking some bash commands in your /bin/init_volumes script but we soon realized that there are several config directories that need to be taken care of, so simply changing the uid of the user creates access problems in these directories.

csandanov commented 6 years ago

I guess we could add a macos image variant with 501:20 for uid/gid. But what kind of issues do you have with non-matching uid/gid in your local environment?

proteo commented 6 years ago

Well, one of the most common and recurring issues is with with D7 projects (yes, we still pretty much live in the D7 realm) where you don't really have a standard process to add new code or even update the existing one. So peeps keep throwing files and never remember to update/change file permissions. But, from your response I assume that setting uid/gid per container is not a feasible thing?

csandanov commented 6 years ago

The solution with updating uid/gid is not feasible because you have to be root to perform any manipulation with wodby user, this means the default user will be root. You can't change your current user id via sudo and stay sane.

Could you please clarify why do you need to change file permissions for new code? You probably add it from the host machine via git or copying, why would you need to change it? It's still have read permissions for php-fpm so it shouldn't be a problem.

csandanov commented 6 years ago

-dev-macos variants have been added with default wodby uid/gid 501:20 since -4.2.0 stability tag. Also, you can now use build arguments WODBY_USER_ID/WODBY_GROUP_ID to customize ids.

proteo commented 6 years ago

@csandanov absolutely fantastic, thank you very much. You're right, adding code with a different uid is no a major issue because it still can be read. It's more like the purpose of having the 1000 uid matching the user in Linux. Your support is greatly appreciated, now we have a few less repos to mantain :)

johandenhollander commented 6 years ago

@csandanov How should I use the build arguments in a docker-compose file?

Would be nice if rebuilding this image would always take the users uid as a variable. Some of my coworkers had their systems set up by the sys admin. So the Admin account is then 501 and the user account has 502

csandanov commented 6 years ago

@johandenhollander see https://github.com/wodby/php#build-arguments

johandenhollander commented 6 years ago

My php section looks like this. How would I rewrite it to include the build arguments? Sorry if this is a n00b question... I have no experience with build arguments. I did try something by adding a dockerfile but that was not successful for me.

services:

  php:
    image: wodby/drupal-php:${PHP_WODBY_TAG}
    environment:
      PHP_DOCROOT: ${DOCROOT} # Relative path inside the /var/www/html/ directory.
      PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog.test:1025
      PHP_XDEBUG: 1
      PHP_XDEBUG_DEFAULT_ENABLE: 1
      PHP_XDEBUG_ENABLED: 1
      PHP_XDEBUG_REMOTE_ENABLE: 1
      PHP_XDEBUG_REMOTE_AUTOSTART: 0
      PHP_XDEBUG_REMOTE_CONNECT_BACK: 0         # This is needed to respect remote.host setting bellow
      PHP_XDEBUG_REMOTE_HOST: "10.254.254.254"  # You will also need to 'sudo ifconfig lo0 alias 10.254.254.254'
      PHP_MAX_INPUT_VARS: 15000
      PHP_MEMORY_LIMIT: 2048M
      PHP_MAX_EXECUTION_TIME: 360
    volumes:
      - docker-sync:/var/www/html:nocopy
    links:
      - solr
    external_links:
      - mysql
      - dockerdns
    networks:
      - default
      - commonapps_default
    dns:
     - ${DOCKERDNS}
csandanov commented 6 years ago

You can't do that via docker-compose file, you'll have to build your own images with build args.

mfrieling commented 6 years ago

Hello. I have a similar issue with users and permissions. First, I'm working with Docker for Windows on Windows 10. I have more or less the D4D stack with some config changes, but the main change is that I use the wodby/php image instead of the wodby/php-drupal image, because I want to use it for Magento 2 development and not for Drupal. Furthermore with the wodby/php-nginx I've overwritten the Nginx config files with versions suiting Magento 2.

The problem with Magento (1 and 2) is, that it of course like Drupal write permissions for the content files directory needs, but not only. Additionally it has a var/ folder for session files, caches, logs, reports (aka error log files, one per error) etc. and a generated/ folder where Magento 2 puts it's generated code files. Magento has something called Magento Compiler but as it is PHP it is not what we understand of a compiler. It is a tool that collects tons of files and rewrites them to increase performance. I do not know how exactly it works in Magento 2, but in one it basically collects all code files from app/code/core, app/code/community and app/code/local, searches them for overrides (a file/class in core can be overriden/replaced by one in community and local, one in community in local), then takes its namespace, replaces / with _ and creates an new PHP file inside the generated code folder using that as name. It copies the code of all files of that namespace into the new file and updates the class autoloader to search the classes in the combined generated file instead of in the originals. Because Magento consists of some 10,000 files more than Drupal and for PHP searching files in one directory than in a deep subdirectory structure seems to be faster, they do stuff like this.

Now my problem with the container is, that neither Magento executed via the browser nor the Magento CLI tool can delete, modify or create files due to permission problems. At least the CLI tools reports this, and the web frontend is plain HTML, so obviously generated CSS files could not be created.

nortmas commented 6 years ago

I have a pretty critical issue with this approach using gitlab ci on my staging server. The problem is that all file structure was created by user 1000 (wodby) and when the Drupal app tries to create any folder for instance 'files' 'tmp' etc... it says that it has no permissions, because the app uses www-data. The parent folders have permissions 'drwxrwxr-x', my assumption is that the www-data should be added to the group wodby. I can't do it myself because usermod not found. Please advise.

csandanov commented 6 years ago

That's why the image has $FILES_DIR=/mnt/files that used a destination symlink for sites/*/files. Tmp dir should be fine if you use /tmp.

nortmas commented 6 years ago

I'm sorry but I'm not sure what do yo mean. When I do project installation using drush inside docker container (in gitlab ci pipline), it creates the file system as a wodby but when I get to the website, Drupal app can't create the files in the folder files because it was created by wodby and the www-data has no access to the files directory.

Another option if I get into the container as www-data and run drush, it creates folders but then I'm not able to remove it as a gitlab-runner user on my server because I don't have user 82.

csandanov commented 6 years ago

Well, what would you do if these weren't containers? You install a project via drush and it creates directories from your user, that's expectable and you should set correct ownership/permissions afterward for fpm user. Alternatively, you can always change the container's default user and fpm user if you want to, use the same user for everything or use root everywhere, it's up to you.

nortmas commented 6 years ago

Thank you! I'm not an advanced docker user. Just trying to find the best way and of course, it's preferable to use a native solution (which is supposed to be used in such cases). Thank you for making time to answer!

davidwhthomas commented 5 years ago

Just noting for those with file permissions after the wodby vs www-data user update. The wodby user is in the www-data group. You can change your www-data folder/file permissions to be group writable to fix.

find /path/to/files -type d -exec chmod 775 {} \;
find /path/to/files -type f -exec chmod 664 {} \;