Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue running docker in production mode #1137

Closed
raserma opened this issue Mar 3, 2021 · 13 comments
Closed

Issue running docker in production mode #1137

raserma opened this issue Mar 3, 2021 · 13 comments
Labels
Docker troubleshooting Support with current features

Comments

@raserma
Copy link

raserma commented Mar 3, 2021

Hi,
We got Userfrosting running on our systems and I'd like to migrate it to Docker.
So I am trying to deploy Userfrosting in docker using the UF_MODE=production. However, after the installation, the frontend application fails with:

Something's not right here.

Please fix the following errors, then reload..
Incorrect permissions for file or directory.

/app/app/sprinkles is writeable, but it should not be writeable. Please modify the OS user or group permissions so that user www-data does not have write permissions for this directory.
Incorrect permissions for file or directory.

/app/app/vendor is writeable, but it should not be writeable. Please modify the OS user or group permissions so that user www-data does not have write permissions for this directory.

I have tried to give those folders read-only permissions, but then the frontend fails with the following:

Warning: require_once(/app/app/vendor/autoload.php): failed to open stream: Operation not permitted in /app/public/index.php on line 17

Fatal error: require_once(): Failed opening required '/app/public/../app/vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /app/public/index.php on line 17

Am I supposed to run production mode with Docker?

If I switch back to development mode before making those folder read-only, and restart the container, the portal loads successfully and I am able to login. However, with development mode enabled, the app container doesn't log anything from php-fpm service, which is not ideal.

@Silic0nS0ldier
Copy link
Member

Production mode has additional checks (they are cached, overall behaviour may one day change under #630).
As for Docker, not surprised to hear there are issues. UF wasn't built with containerisation in mind, and consequently it does some things which aren't the best fit (and in some cases, are simply incompatible with the underlying technologies). I intend to address this shortcoming some day under #1003

As for the issue you are seeing, it sounds like the permissions were changed in a "wrong" manner. Without seeing the command used to change the permissions (and the context they are run in) I can't help much. To hazard a guess, it looks like the permission change has blocked the user account within the container context. That is, there is an ownership issue. From memory there are some considerations for setting file permissions in a Dockerfile, may be worth referring to Docker documentation.

@raserma
Copy link
Author

raserma commented Mar 4, 2021

Thanks for the detailed answer.
EDIT: What are the differences between running development and production mode for the folder permissions? From what I understand from #630, "dev" mode sends errors to response and "prod" sends it to the stdout/frontend application. However when running under "dev" mode, I am not getting any permissions issues in the response.

Just out of curiosity, under the dev mode, is it possible to enable logs to stderr from php-fpm in the container app?

As per your second paragraph's answer, I may have broken something as I got stuck with this for few hours and tried few things.

I have deployed the solution from scratch again and ended up with the same issue when hitting localhost:8591:

Something's not right here.

Please fix the following errors, then reload..
Incorrect permissions for file or directory.

/app/app/sprinkles is writeable, but it should not be writeable. Please modify the OS user or group permissions so that user www-data does not have write permissions for this directory.
Incorrect permissions for file or directory.

/app/app/vendor is writeable, but it should not be writeable. Please modify the OS user or group permissions so that user www-data does not have write permissions for this directory.

Not sure if someone can point me to the right direction here. The folder permissions from the app container of folder are as follows:

root@372c39ea6c46:~# ls -lart /app/app/
total 24
-rw-r--r--  1 root     root      589 Mar  1 14:38 .htaccess
-rwxr-xr-x  1 root     root     1723 Mar  1 14:38 defines.php
-rw-r--r--  1 root     root      100 Mar  1 14:38 sprinkles.example.json
drwxr-xr-x  3 root     root       96 Mar  1 14:38 storage
drwxr-xr-x  8 www-data root      256 Mar  1 14:38 system
drwxr-xr-x  5 root     root      160 Mar  1 14:38 tests
-rw-r--r--  1 root     root      100 Mar  3 12:09 sprinkles.json
-rw-r--r--  1 root     root      509 Mar  3 19:17 .env.example
drwxr-xr-x 31 root     root      992 Mar  3 19:45 ..
drwxr-xr-x  5 root     root      160 Mar  4 07:53 sprinkles
drwxr-xr-x 42 root     root     1344 Mar  4 08:06 vendor
-rw-r--r--  1 root     root      472 Mar  4 08:16 .env
drwxrwxrwx  4 root     root      128 Mar  4 08:16 logs
drwxr-xr-x 17 root     root      544 Mar  4 08:16 .
drwxr-xr-x  6 root     root      192 Mar  4 08:17 assets
drwxrwxrwx  5 www-data www-data  160 Mar  4 08:20 cache
drwxrwxrwx  5 root     root      160 Mar  4 08:20 sessions

@Silic0nS0ldier
Copy link
Member

Dev mode is generally a lot more permissive (e.g. allowing certain folders to be writable). Production on the other hand has checks in place intended to guard against potential security issues. They aren't comprehensive, being more intended to push people into using best security practises rather than providing another layer of security.

My mastery of Unix permissions is non-existent so I'll defer to @lcharette on this front.

@lcharette
Copy link
Member

@raserma /app/app/sprinkles is indeed writable by the user root (drwxr-xr-x) witch appear to be your server user... I'm not a Docker guru, so not sure how you can get around this... The easier solution would be to disable the check altogether, which I believe is hardcoded right now...

@lcharette lcharette added Docker troubleshooting Support with current features labels Mar 5, 2021
@lcharette
Copy link
Member

Maybe @phillmac could help ?

@phillmac
Copy link
Contributor

phillmac commented Mar 5, 2021

E.g. My dockerfile looks something like this:

FROM peelvalley/php

ARG UF_VERSION=v4.4.3
ENV COMPOSER_MEMORY_LIMIT=-1

WORKDIR /var/www
RUN rm -rvf html && echo "Userfrosting ${UF_VERSION}"


#RUN git clone https://github.com/userfrosting/UserFrosting "$(pwd)" \
RUN  wget -qO-  https://github.com/userfrosting/UserFrosting/archive/${UF_VERSION}.tar.gz | tar xz --strip-components=1
RUN mv public html \
 && chmod u+x bakery \
 && chown -R www-data:www-data /var/www


USER www-data
RUN composer --no-ansi --no-progress --quiet install \
&& ./bakery -n --no-ansi --quiet build-assets


USER root

ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
CMD ["apache2-foreground"]

EXPOSE 80

The only caveat to this approach is needing to manage asset bundles separately e.g.

CMD ["bash", "-c", "bash app/production.sh && apache2-foreground"]

where the .sh script looks something like this:

#!/bin/bash

if [[ "${UF_MODE}" = "production" ]]; then
   if [[ ! -d html/assets ]]; then
      echo "Copying assets"
      mv public/assets html/assets
      chmod 555 app/sprinkles app/vendor
   else
      echo "Assets dir already exists"
   fi
else
   echo "Not in production mode"
fi

@phillmac
Copy link
Contributor

phillmac commented Mar 5, 2021

The end result is a bunch of switching users and messing about, but the critical thing is running chown -R www-data:www-data /var/www and chmod 555 app/sprinkles app/vendor either in the dockerfile as one of the last steps or before you fire up the web server instance as a sort of pre-start script

@phillmac
Copy link
Contributor

phillmac commented Mar 5, 2021

The final stage of my docker build looks something like this:

FROM peelvalley/userfrosting:v4.4.3

ARG GIT_USERNAME_ARG
ARG GIT_PASSWORD_ARG
ENV GIT_USERNAME=$GIT_USERNAME_ARG
ENV GIT_PASSWORD=$GIT_PASSWORD_ARG
ARG IMAGE_NAME_DIR

USER www-data

COPY ${IMAGE_NAME_DIR}sprinkles.json ${IMAGE_NAME_DIR}production.sh app/

RUN echo '#!/bin/bash' > /var/www/git-credentials.sh \
    && echo 'echo username="${GIT_USERNAME}"' >> /var/www/git-credentials.sh \
    && echo 'echo password="${GIT_PASSWORD}"' >> /var/www/git-credentials.sh

RUN git config --global credential.helper "/bin/bash /var/www/git-credentials.sh" \
    && composer update \
    && ls -la /var/www/app/sprinkles \
    && ./bakery build-assets --no-ansi \
    && ./bakery build-assets --compile --no-ansi

CMD ["bash", "-c", "bash app/production.sh && apache2-foreground"]

USER root

@phillmac
Copy link
Contributor

phillmac commented Mar 5, 2021

I really should move the asset builds to separate stage to cut down on the weight of nodejs I guess, But seeing as I use the same image for both dev and production, being able to quickly add assets in dev for the sake of testing is kinda handy too

@raserma
Copy link
Author

raserma commented Mar 5, 2021

Thank you guys!

@phillmac thanks for the Dockerfiles. I think I also executed those chmod/chown commands when debugging the container and nothing changed. However I will try these steps all over again later with a fresher brain in case I missed something.
Cheers!

@lcharette
Copy link
Member

he easier solution would be to disable the check altogether, which I believe is hardcoded right now...

FYI, there is an SKIP_PERMISSION_CHECK env for this apparently :

return getenv('SKIP_PERMISSION_CHECK') ? true : false;

@Silic0nS0ldier
Copy link
Member

@lcharette Thoughts on converting this into a discussion? (the GitHub feature that is)

@lcharette
Copy link
Member

I agree, we can try. Docker seems a complex topic not it's own that might or no have a definitive answer.

@userfrosting userfrosting locked and limited conversation to collaborators Apr 24, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Docker troubleshooting Support with current features
Projects
None yet
Development

No branches or pull requests

4 participants