nextcloud / docker

⛴ Docker image of Nextcloud
https://hub.docker.com/_/nextcloud/
GNU Affero General Public License v3.0
5.98k stars 1.82k forks source link

Automatically set directory ownership when using NEXTCLOUD_DATA_DIR #1396

Open aanno opened 3 years ago

aanno commented 3 years ago

I'm using the nextcloud docker image (nc version 20.0.6.1). It seems to have support for setting NEXTCLOUD_DATA_DIR, but there are issues.

Snippet of my docker-compose file:

  app:
    image: nextcloud:fpm-alpine
    restart: unless-stopped
    volumes:
      - nextcloud:/var/www/html
      - nc_data:/opt/nextcloud/data
    environment:
      - MYSQL_HOST=db
      - REDIS_HOST=redis
      - OVERWRITEWEBROOT=/nextcloud
      - NEXTCLOUD_DATA_DIR=/opt/nextcloud/data
    env_file:
      - db.env
    depends_on:
      - db
      - redis

Issue 1: Permissions on NEXTCLOUD_DATA_DIR are not set

If you try this, nextcloud installation (with browser button 'Install') does not work, because 'www-data:root' has no permission to write to /opt/nextcloud/data.

Workaround

Before starting the installation process in the browser, log into the container and fix the permissions, i.e.

$ podman exec -it <nextcloud-container-id> sh
/var/www/html # chown -R www-data:root /opt/nextcloud/data/

It would be great if the /entrypoint.sh script would set the permissions appropriate.

Issue 2: appdata directory at NEXTCLOUD_DATA_DIR location must be served

If I use the workaround above to complete the installation process, I could log in, but there are missing resources. This is because after the install, my NEXTCLOUD_DATA_DIR (/opt/nextcloud/data) looks like this:

# ls -l /opt/nextcloud/data/
total 12
drwxr-xr-x    4 www-data www-data        32 Feb  7 08:18 admin
drwxr-xr-x    8 www-data www-data        89 Feb  7 08:18 appdata_ocvkg7lyrl56
-rw-r--r--    1 www-data www-data         0 Feb  7 08:17 index.html
-rw-r-----    1 www-data www-data      9736 Feb  7 08:18 nextcloud.log

# ls -l /opt/nextcloud/data/appdata_ocvkg7lyrl56/
total 0
drwxr-xr-x    2 www-data www-data        23 Feb  7 08:17 appstore
drwxr-xr-x    3 www-data www-data        19 Feb  7 08:18 avatar
drwxr-xr-x   11 www-data www-data       147 Feb  7 08:43 css
drwxr-xr-x    3 www-data www-data        19 Feb  7 08:18 dashboard
drwxr-xr-x    4 www-data www-data        34 Feb  7 08:18 js
drwxr-xr-x    8 www-data www-data        60 Feb  7 08:18 preview

# ls -l /opt/nextcloud/data/appdata_ocvkg7lyrl56/css/
total 0
drwxr-xr-x    2 www-data www-data        97 Feb  7 08:18 activity
drwxr-xr-x    2 www-data www-data       215 Feb  7 08:18 core
drwxr-xr-x    2 www-data www-data       109 Feb  7 08:18 dashboard
drwxr-xr-x    2 www-data www-data        55 Feb  7 08:18 icons
drwxr-xr-x    2 www-data www-data       100 Feb  7 08:18 notifications
drwxr-xr-x    2 www-data www-data       106 Feb  7 08:43 settings
drwxr-xr-x    2 www-data www-data        97 Feb  7 08:18 text
drwxr-xr-x    2 www-data www-data       103 Feb  7 08:18 theming
drwxr-xr-x    2 www-data www-data       130 Feb  7 08:18 user_status

# ls -l /opt/nextcloud/data/appdata_ocvkg7lyrl56/js
total 0
drwxr-xr-x    2 www-data www-data        97 Feb  7 08:18 activity
drwxr-xr-x    2 www-data www-data       118 Feb  7 08:18 core

There are a bunch of files inside /opt/nextcloud/data/appdata_ocvkg7lyrl56 that needs to be served by the web server (i.e. nginx in my case). However, the whole idea of using NEXTCLOUD_DATA_DIR is to harden the installation (with better protecting user data).

Perhaps it is possible to move stuff under /opt/nextcloud/data/appdata_<random_id> to the nextcloud directory (/var/www/html for nextcloud-docker) in the /entrypoint.sh script?

aanno commented 3 years ago

I can partly solve/circumvent issue 2 with:

$ podman exec -it <nextcloud-container-id> sh
/var/www/html # cp -r /opt/nextcloud/data/appdata_ocvkg7lyrl56/js .
/var/www/html # cp -r /opt/nextcloud/data/appdata_ocvkg7lyrl56/css .
/var/www/html # chown -R www-data:root css js

But even than the installation is somehow broken. For example if I log in (as admin) in the browser, and choose 'Administration -> Overview' I see the following:

There are some errors regarding your setup.

* It was not possible to execute the cron job via CLI. The following technical errors have appeared:
   + Your data directory is invalid Ensure there is a file called ".ocdata" in the root of the data directory.
   + Cannot create "data" directory This can usually be fixed by giving the webserver write access to the root directory. See https://docs.nextcloud.com/server/20/go.php?to=admin-dir_permissions

And on 'Adminstration -> Logging' I see the following 2 errors:

Error | index | RuntimeException: Could not get appdata folder for preview
    /var/www/html/lib/private/Files/AppData/AppData.php - line 157:
    OC\Files\AppData\AppData->getAppDataFolder()
    /var/www/html/lib/private/Preview/Storage/Root.php - line 75:
    OC\Files\AppData\AppData->newFolder("6/f/4/9/2/2/f/18")
    /var/www/html/lib/private/Preview/Generator.php - line 471:
    OC\Preview\Storage\Root->newFolder("18")
    /var/www/html/lib/private/Preview/Generator.php - line 132:
    OC\Preview\Generator->getPreviewFolder(OC\Files\Node\File {})
    /var/www/html/lib/private/Preview/Generator.php - line 109:
    OC\Preview\Generator->generatePreviews(OC\Files\Node\File {}, [ { width: 3 ... }], "text/markdown")

Error | index | OCP\Files\NotPermittedException: Could not create folder
    /var/www/html/lib/private/Files/AppData/AppData.php - line 157:
    OC\Files\Node\Folder->newFolder("icons")
    /var/www/html/lib/private/Template/IconsCacher.php - line 90:
    OC\Files\AppData\AppData->newFolder("icons")
aanno commented 3 years ago

I now also rechecked that the problems mentioned above are caused by - NEXTCLOUD_DATA_DIR=/opt/nextcloud/data, i.e. if I omit the line from my docker-compose file, everything works as expected.

Conclusion: NEXTCLOUD_DATA_DIR is still in the nextcloud-docker image, but it can't be used at present.

0x47 commented 3 years ago

May I ask what you chose to do about it since February? Facing issue after issue since trying to migrate to a containerized Nextcloud setup, I am beginning to think this is more of a hobby/fun project instead of being meant for production use. Did you somehow go through with it? Or would you recommend not using Nextcloud Docker at this time.

EDIT: Just for reference, this is from the official documentation:

It is highly recommended to place your data directory outside of the Web root (i.e. outside of /var/www). It is easiest to do this on a new installation.

0x47 commented 3 years ago

I worked around this issue with a custom Dockerfile built on top of the fpm-alpine one:

ARG NEXTCLOUD_DATA_DIR=/opt/nextcloud_data
ARG IMAGE_TAG=fpm-alpine

FROM nextcloud:${IMAGE_TAG}

ARG NEXTCLOUD_DATA_DIR

RUN mkdir -p ${NEXTCLOUD_DATA_DIR}; \
    chown -R www-data:root ${NEXTCLOUD_DATA_DIR}; \
    chmod -R g=u ${NEXTCLOUD_DATA_DIR}

VOLUME ${NEXTCLOUD_DATA_DIR}

ENTRYPOINT ["/entrypoint.sh"]
CMD ["php-fpm"]

In fact, the default Dockerfile seems to create a data directory for some reason, but is stays unused afterwards: https://github.com/nextcloud/docker/blob/ede3bdc0cce452196a2a92b45f47a6059ba5e538/21.0/fpm-alpine/Dockerfile#L98

At least for a fresh installation the above workaround seems to work nicely.

0x47 commented 3 years ago

Sorry, I have to take that back partially. While the UI generally seems to work fine, the settings still show warnings:

  • It was not possible to execute the cron job via CLI. The following technical errors have appeared:

Additionally, the cron job container does not work any more, logging

cron_1            | crond: wakeup dt=60
cron_1            | crond: file www-data:
cron_1            | crond:  line php -f /var/www/html/cron.php
cron_1            | crond:  job: 0 php -f /var/www/html/cron.php
cron_1            | crond: child running /bin/ash
cron_1            | crond: USER www-data pid   9 cmd php -f /var/www/html/cron.php
cron_1            | Your data directory is invalid
cron_1            | Ensure there is a file called ".ocdata" in the root of the data directory.
cron_1            | 
cron_1            | Cannot create "data" directory
cron_1            | This can usually be fixed by giving the webserver write access to the root directory. See https://docs.nextcloud.com/server/21/go.php?to=admin-dir_permissions
cron_1            | 
cron_1            | crond: wakeup dt=10
aanno commented 3 years ago

Dear @0x47,

sorry for replying late. I posted the question/problem some time ago. And I now think it's a bad idea to try to change NEXTCLOUD_DATA_DIR from a working nextcloud instance (this is also discouraged in the documentation). Hence, my bottom line was 'don't do' (but I forgot to close the ticket).

Recently, I have come back to NEXTCLOUD_DATA_DIR for a new nextcloud instance and haven't encounter this problem. (I have setup my nextcloud anew with podman instead of docker for the container, you could see it at https://github.com/aanno/nextcloud-docker/blob/feature/aanno-example-podman-test/.examples/docker-compose/with-nginx-proxy-self-signed-ssl/mariadb/fpm/docker-compose.yml ).

HOWEVER, my other problem described here (the problem with the appdata_ocvkg7lyrl56/js and appdata_ocvkg7lyrl56/css) stuff is present with my new configuration as well. I'm just circumventing the problem with https://github.com/aanno/nextcloud-docker/blob/feature/aanno-example-podman-test/.examples/docker-compose/with-nginx-proxy-self-signed-ssl/mariadb/fpm/nc/myentrypoint.sh . But my feeling is that the problem is not related to NEXTCLOUD_DATA_DIR but to my try to get nextcloud at http(s)://example.com/nextcloud with OVERWRITEWEBROOT=/nextcloud.

Kind regards,

aanno

0x47 commented 3 years ago

Thank you for your reply! I think I was able to finally figure out the issue for my case. First, I created the data directory though my custom Dockerfile (and from what I can see, you did the same with your custom myentrypoint.sh script). For the second part with the errors regarding cron, I realized that I simply forgot to add the data directory volume to the cron container in my docker-compose.yml.

It's unfortunate that you are still seeing this issue but I guess since it works for me (with a default setup) you could be on the right track with your feeling about the custom webroot.

In conclusion, I feel like it's still misleading to have the NEXTCLOUD_DATA_DIR switch available when it won't even work without creating the directory manually.

Thanks again!

rapgru commented 3 years ago

Hey @aanno! I'd like to set up my NextCloud with s3fs and exclude the appdata directory from the s3 storage to speed up the UI. I have that idea from this interesting blog post of a company providing that service to customers.

Your image/fork seems to be perfect for this, as I can in theory place the DATA_DIR somewhere outside the webroot, mount that directory with s3fs and use local ssd storage for the webroot. But I have some questions that you could probably answer.

As far as I can see, your entrypoint copies the appdata files to the webroot on startup. How does that affect nextcloud when a plugin or whatever decides to write to the appdata folder? Does it change the files in the webroot or in the data dir? Are changes only effective after a restart? I'm a bit lost.

Looking forward to any input, rapgru

aanno commented 3 years ago

The myentrypoint.sh thing is a kind of HACK that circumvents the 'Issue 2' of my bug report (i.e. the top post). The script just fixes that, copying the mentioned files into the installation. AFAIK, this is normally only needed after updating (the version of) nextcloud. Because it copies 'too early' (before the first run of the new version), I normally need to restart/recreate the containers after a first 'admin' login (and browsing around the setting and plugin nextcloud pages).

Hence, I'm not aware that it changes any (other) files in appdata. The change is permanent (and needed - but see above).

jcastro commented 1 year ago

I’m also having this issue. I’m in proComcast, anyone figured a way to do it where everything works correctly? Thanks!

nsrosenqvist commented 1 year ago

I'm too getting these error messages:

It was not possible to execute the cron job via CLI. The following technical errors have appeared:

I have set NEXTCLOUD_DATA_DIR to /data, at which I have mounted a RAID array. For me, the second message doesn't make any sense, since I already have the directory created and can successfully upload files to it. When I check to the permissions of the directory, www-data does have write permissions there, and the file .ocdata exists, so I'm not sure what is causing this issue. What should be the owner and group of the files here? In the conversation above it appears that it should be www-data:root and not www-data:www-data, like I have it, does that make a difference?

drwxrwx--- 10 www-data www-data  4096 Sep 25 18:31 .
drwxr-xr-x  1 root     root      4096 Sep 25 21:09 ..
-rw-r--r--  1 www-data www-data   542 Sep 23 23:29 .htaccess
-rw-r--r--  1 www-data www-data     0 Sep 23 23:29 .ocdata
drwxr-xr-x 10 www-data www-data  4096 Sep 25 21:09 appdata_ocoiosn2qokv
drwxr-xr-x  2 www-data www-data  4096 Sep 25 18:06 files_external
-rw-r--r--  1 www-data www-data     0 Sep 23 23:29 index.html
drwxr-xr-x  4 www-data www-data  4096 Sep 25 18:45 redacted_user1
drwxr-xr-x  4 www-data www-data  4096 Sep 25 18:46 redacted_user2
drwxr-xr-x  4 www-data www-data  4096 Sep 23 23:31 redacted_user3
-rw-r-----  1 www-data www-data 21475 Sep 25 18:37 nextcloud.log
drwxr-xr-x  4 www-data www-data  4096 Sep 25 18:21 redacted_user4
drwxr-xr-x  4 www-data www-data  4096 Sep 25 18:47 redacted_user5
drwxr-xr-x  4 www-data www-data  4096 Sep 25 18:46 redacted_user6

I can also see permissions related errors in the administration log, which appears to be related to the generation of previews for the Photos app:

[index] Error: OCP\Files\NotPermittedException: Could not create folder "/appdata_ocoiosn2qokv/preview/9/b/f/3/1/c/7/15" at <<closure>>

 0. /var/www/html/lib/private/Files/AppData/AppData.php line 147
    OC\Files\Node\Folder->newFolder("9/b/f/3/1/c/7/15")
 1. /var/www/html/lib/private/Preview/Storage/Root.php line 74
    OC\Files\AppData\AppData->newFolder("9/b/f/3/1/c/7/15")
 2. /var/www/html/lib/private/Preview/Generator.php line 643
    OC\Preview\Storage\Root->newFolder("15")
 3. /var/www/html/lib/private/Preview/Generator.php line 139
    OC\Preview\Generator->getPreviewFolder(["OC\\Files\\Node\\File"])
 4. /var/www/html/lib/private/Preview/Generator.php line 116
    OC\Preview\Generator->generatePreviews(["OC\\Files\\Node\\File"], [[64,64,false,"fill"]], "image/jpeg")
 5. /var/www/html/lib/private/PreviewManager.php line 192
    OC\Preview\Generator->getPreview(["OC\\Files\\Node\\File"], 64, 64, false, "fill", null)
 6. /var/www/html/apps/photos/lib/Controller/PreviewController.php line 162
    OC\PreviewManager->getPreview(["OC\\Files\\Node\\File"], 64, 64)
 7. /var/www/html/apps/photos/lib/Controller/PreviewController.php line 128
    OCA\Photos\Controller\PreviewController->fetchPreview(["OC\\Files\\Node\\File"], 64, 64)
 8. /var/www/html/lib/private/AppFramework/Http/Dispatcher.php line 230
    OCA\Photos\Controller\PreviewController->index(15, 64, 64)
 9. /var/www/html/lib/private/AppFramework/Http/Dispatcher.php line 137
    OC\AppFramework\Http\Dispatcher->executeController(["OCA\\Photos\\C ... "], "index")
10. /var/www/html/lib/private/AppFramework/App.php line 183
    OC\AppFramework\Http\Dispatcher->dispatch(["OCA\\Photos\\C ... "], "index")
11. /var/www/html/lib/private/Route/Router.php line 315
    OC\AppFramework\App::main("OCA\\Photos\\Co ... r", "index", ["OC\\AppFramewo ... "], ["15","photos.preview.index"])
12. /var/www/html/lib/base.php line 1068
    OC\Route\Router->match("/apps/photos/api/v1/preview/15")
13. /var/www/html/index.php line 36
    OC::handleRequest()

GET /apps/photos/api/v1/preview/15?etag=b95ab58eb0ea58da4a1b3cee694c34ed&x=64&y=64
from 192.168.X.X by redacted_user at 2023-09-25T18:37:00+00:00
joshtrichards commented 4 months ago

There are a bunch of files inside /opt/nextcloud/data/appdata_ocvkg7lyrl56 that needs to be served by the web server (i.e. nginx in my case). However, the whole idea of using NEXTCLOUD_DATA_DIR is to harden the installation (with better protecting user data).

Nothing in appdata_INSTANCEID/ (or data/ for that matter) is ever served directly by the web server. appdata is an internal filesystem managed by Nextcloud on behalf of apps. Everything there is accessed through Nextcloud APIs and, in turn, via mod_php or fpm.

That's why there are no special steps required, to have one's datadirectory outside the webroot, even in non-Docker installs. If there was, it would have to be fixed upstream (in Server), not in the Docker image.

I tested and I don't have any issue using NEXTCLOUD_DATA_DIR via the fpm-alpine image described in original report (outside of the permissions issue also noted; more on that one below).

Based on the comments from @0x47 the only issue seems to be default permissions for the mounted custom data volume. With a preliminary test this does appear to be problem.

At a minimum, the need for manual chown needs to be documented. It may make sense to simply chown outright the specified NEXTCLOUD_DATA_DIR in the entrypoint.sh.

I suspect the reason this wasn't caught originally is because it's a very old option in the image and many people probably used it bind mounts at the time (which ironically tend to create permission issues). In this case it may been expected behavior to change that.

joshtrichards commented 3 months ago

Related: #1889