Closed amitaibu closed 4 years ago
Absolutely everything in Dockerfile build time (for all Dockerfiles everywhere) happens as root. composer global require
should just be using root's home directory as a temporary storage place.
In your case, phpcs isn't really being installed globally, it's being installed in root's composer cache.
I see you're not the first person to encounter this, see https://unix.stackexchange.com/questions/280846/find-composer-global-install-path-as-root
I think the first thing to try is to symlink into /usr/local/bin
I'll take a look at this in the morning. But the basic issue is that composer's "install global" means "not site-install". It doesn't mean "make available for the machine", like it would everywhere else. But all that should be required is a symlink IIRC.
Thanks. Not sure how to create the symlink (as also the user doesn't have access to root's files), so I'd be happy for some help here :)
Once we figure this out, I'll create a PR to add that to the Dockerfile.example
Here's what we used to do when we used cgr to install drush (I DO NOT recommend this)
RUN composer global require consolidation/cgr
RUN /home/.composer/vendor/bin/cgr drush/drush:$DRUSH_VERSION && ln -s /home/.composer/vendor/bin/drush /usr/local/bin/drush
So that approach will probably work. But the bottom line is that composer isn't a very good tool for installing things globally.
What I recommend is just using the instructions at https://github.com/squizlabs/PHP_CodeSniffer#installation to install with phar file. So much easier. Install it in /usr/local/bin. This is how we install drush8 these days:
RUN curl -sSL "https://github.com/drush-ops/drush/releases/download/${DRUSH_VERSION}/drush.phar" -o /usr/local/bin/drush8 && chmod +x /usr/local/bin/drush8
BTW, I don't think the Dockerfile.example is a very good place for a complex item like this. Stack Overflow, ddev-contrib, or even adding it to that article are good places.
@rfay I see. But one more thing I didn't figure out yet - what about getting the specific coder sniffer for Drupal?
So we could do for example:
RUN composer global require consolidation/cgr
RUN ~/.composer/vendor/bin/cgr drupal/coder:^8.3.1
RUN ~/.composer/vendor/bin/cgr dealerdirect/phpcodesniffer-composer-installer
Then would we symlink them? If so what would be the correct place to do that?
BTW, I don't think the Dockerfile.example is a very good place for a complex item like this
:+1:
The install doc provides a lot of options, https://www.drupal.org/docs/8/modules/code-review-module/installing-coder-sniffer - It seems you can manually set the paths, phpcs --config-set installed_paths ~/.composer/vendor/drupal/coder/coder_sniffer
, so that means you can composer-install drupal/coder as you wish and then point to it.
Sorry, I've actually tried it - and it doesn't work:
ARG BASE_IMAGE=drud
FROM $BASE_IMAGE
# We try to avoid when possible relying on composer to download global, so in PHPCS case we can use the phar.
RUN curl -L https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar -o /usr/local/bin/phpcs.phar
RUN curl -L https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar -o /usr/local/bin/phpcbf.phar
# If however we need to download a package, we use `cgr` for that.
RUN composer global require consolidation/cgr
RUN ~/.composer/vendor/bin/cgr drupal/coder:^8.3.1
RUN ~/.composer/vendor/bin/cgr dealerdirect/phpcodesniffer-composer-installer
# Register Drupal's code sniffer rules.
RUN php /usr/local/bin/phpcs.phar --config-set installed_paths ~/.composer/global/drupal/coder/coder_sniffer --verbose
I believe the reason it doesn't work, is that when I use it as a non-root, it no longer sees those files. It just sees the default ones:
$ php /usr/local/bin/phpcs.phar -i
The installed coding standards are MySource, PEAR, PSR1, PSR12, PSR2, Squiz and Zend
Sorry, the way to work on this is not to do it in a Dockerfile. It's to do it in the running container. Or a running Debian container might be easiest. It's way to hard to work in a Dockerfile when you can't tell whether what is going to happen. But each of these steps can be taken one at a time inside the container, and it's much more satisfying. I'd be happy to do a zoom or whatever with you and we can work through this together.
Where I'd start is docker run -it drud/ddev-webserver:v1.13.1 bash
and proceed from there. It's a much more experimental setup and lets you figure out what's going on and solve the problems one at a time.
If you want to zoom right now we could. Or whenever it works for you. Ping me in slack either to give it a try or to set an appointment.
You were almost there. The path given for the phpcs --config-set installed_paths
in the drupal.org article was incorrect, but there was still the problem of permissions in ~root. There are many ways to solve this, but here's what I did, using COMPOSER_HOME as /usr/local/composer during the build stage.
What I did was to work interactively in docker run -it --rm drud/ddev-webserver:v1.13.1 bash
(or docker run -it --rm drud/ddev-webserver:v1.13.1-<projectname>-built bash
which has everything already working in your add-on Dockerfile working in it.
ARG BASE_IMAGE
FROM $BASE_IMAGE
ENV COMPOSER_HOME=/usr/local/composer
# We try to avoid when possible relying on composer to download global, so in PHPCS case we can use the phar.
RUN curl -L https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar -o /usr/local/bin/phpcs && chmod +x /usr/local/bin/phpcs
RUN curl -L https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar -o /usr/local/bin/phpcbf && chmod +x /usr/local/bin/phpcbf
# If however we need to download a package, we use `cgr` for that.
RUN composer global require consolidation/cgr
RUN $COMPOSER_HOME/vendor/bin/cgr drupal/coder:^8.3.1
RUN $COMPOSER_HOME/vendor/bin/cgr dealerdirect/phpcodesniffer-composer-installer
# Register Drupal's code sniffer rules.
RUN phpcs --config-set installed_paths $COMPOSER_HOME/global/drupal/coder/vendor/drupal/coder/coder_sniffer --verbose
# Make Codesniffer config file writable for ordinary users in container.
RUN chmod 666 /usr/local/bin/CodeSniffer.conf
# Make COMPOSER_HOME writable if regular users need to use it.
RUN chmod -R ugo+rw $COMPOSER_HOME
# Now turn it off, because ordinary users will want to be using the default
ENV COMPOSER_HOME=""
$ ddev ssh
rfay@d8composer-web:/var/www/html/web$ phpcs -i
The installed coding standards are MySource, PEAR, PSR1, PSR12, PSR2, Squiz, Zend, Drupal and DrupalPractice
@rfay this works great, thank you. Would you like me to add it in Stackoverflow or ddev-contrib?
Yay! Yes, please. ddev-contrib has an empty section for this kind of thing, https://github.com/drud/ddev-contrib#ddevweb-builddockerfile-examples-to-customize-web-container
Stack Overflow is fine and a little easier for a quick thing. Either is fine. Thanks!
Glad it's working! Closing this for now.
btw, here's a PR on drupal-starter
that now uses this -- https://github.com/Gizra/drupal-starter/pull/7
Finally got to add it to StackOverflow -- https://stackoverflow.com/questions/61870801/add-global-phpcs-and-drupal-coder-to-ddev-in-custom-dockerfile/61870802#61870802
Thanks!
I recently had to set this up and a few things have changed, mainly:
Here's the latest config that worked for me:
## Install PHPCS Globally
ENV COMPOSER_HOME="/usr/local/composer"
# We try to avoid relying on Composer to download global, so in `phpcs` case we can use the PHAR.
RUN curl -L https://phars.phpcodesniffer.com/phpcs.phar -o /usr/local/bin/phpcs && chmod +x /usr/local/bin/phpcs
RUN curl -L https://phars.phpcodesniffer.com/phpcbf.phar -o /usr/local/bin/phpcbf && chmod +x /usr/local/bin/phpcbf
# Allow installation of known package plugins
RUN composer global config --no-plugins allow-plugins.drupal/coder true
RUN composer global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
# Require composer packages globally
RUN composer global require drupal/coder
RUN composer global require dealerdirect/phpcodesniffer-composer-installer
## Register Drupal's code sniffer rules for phpcs.
RUN phpcs --config-set installed_paths $COMPOSER_HOME/vendor/drupal/coder/coder_sniffer,$COMPOSER_HOME/vendor/slevomat/coding-standard/SlevomatCodingStandard/,$COMPOSER_HOME/vendor/sirbrillig/phpcs-variable-analysis/VariableAnalysis/ --verbose
## Make Codesniffer config file writable for ordinary users in container.
RUN chmod 666 /usr/local/bin/CodeSniffer.conf
## Make COMPOSER_HOME writable if regular users need to use it.
RUN chmod -R ugo+rw $COMPOSER_HOME
## Now turn it off, because ordinary users will want to be using the default
ENV COMPOSER_HOME=""
This was tested on ddev v1.23.0-2-g5cc331835 with PHPStorm and VSCode.
@cballenar thanks for this!
Could you please edit your post to say what version of DDEV you changed for? (v1.23.0?)
Could you also add a comment with a link on https://stackoverflow.com/questions/61870801/add-global-phpcs-and-drupal-coder-to-ddev-in-custom-dockerfile/61870802#61870802 ? (Or edit it if you have permissions)
@cballenar your snipped not working
PHP Fatal error: Uncaught Error: Class "Symfony\Component\Yaml\Yaml" not found in /usr/local/composer/vendor/drupal/coder/coder_sniffer/Drupal/Sniffs/InfoFiles/AutoAddedKeysSniff.php:59
@rfay Are where general way to install composer package globally ? For example how can I utilize composer autocomplete for magento ?
Hi @sergiirepin - Please open a new issue when you have a new issue. But the approach would be the same as here, a custom Dockerfile that does
RUN composer global require bamarni/symfony-console-autocomplete
@rfay thanks! I will add an issue, but I am not sure if it is a ddev issue :) Need some guide probablly, it is not clear how to configure the autocomplete: shell itself in WSL but PHP in docker.
You'll be using it inside ddev ssh
, inside the web container, not on the WSL2 shell.
@rfay Thanks! The question in SO now. :)
Describe the bug
Following the examples in https://www.ddev.com/ddev-local/customizing-ddev-local-images-with-a-custom-dockerfile/ and the example Docker file:
I tried to
composer global require drupal/coder
.This didn't work as expected, as it installs for root
However the user that will later try to invoke it, isn't
root
.To Reproduce
Add
Dockerfile
under.ddev/web-build
withIt will error out on
phpcs
If Instead I install it manually after the container is up with
ddev composer global require...
it works as-expected. So I suspect it has to do with the USER used to run the commands.