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

Nextcloud 28 alpine image - permission denied when post-installation hook is invoked #2217

Closed frenkdefrog closed 4 months ago

frenkdefrog commented 4 months ago

Hi everyone, I wonder if any of us has faced with the issue "Permission denied" when a bash script should run from the post-installation hook directory using nextcloud:28.0.5-fpm-alpine image. I keep getting this error even if only an "echo" is in the bash script. If I try to execute the script from the docker container it is the same, so I assume something is around how alpine handles these bash scripts. But if I invoke the shell script with "/bin/sh changesettings.sh" (using the right path, of course) the script can run. Any idea would be highly appreciated since now I am using some hacky-workaround.

joshtrichards commented 4 months ago

If I try to execute the script from the docker container it is the same, so I assume something is around how alpine handles these bash scripts.

Works for me.

Is the execute bit set on the script?

frenkdefrog commented 4 months ago

As for my knowledge, it is. It has 755 permissions.

The error:

>Nextcloud was successfully installed
app    | Setting trusted domains…
app    | System config value trusted_domains => 1 set to string cloud.company.tld
app    | => Searching for scripts (*.sh) to run, located in the folder: /docker-entrypoint-hooks.d/post-installation
app    | ==> Running the script (cwd: /var/www/html): "/docker-entrypoint-hooks.d/post-installation/setup.sh"
app    | sh: /docker-entrypoint-hooks.d/post-installation/setup.sh: Permission denied
app    | ==> Failed at executing "/docker-entrypoint-hooks.d/post-installation/setup.sh". Exit code: 126

The relevant service definition in docker-compose.yaml:

app:
    image: nextcloud:28.0.5-fpm-alpine
    container_name: app
    restart: always
    volumes:
      - /srv/dockerdata/nextclouddata:/var/www/html:z
      - ./app-hooks/post-installation:/docker-entrypoint-hooks.d/post-installation
    environment:
      - POSTGRES_HOST=db
      - REDIS_HOST=redis
      - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS}
      - OVERWRITEHOST=${OVERWRITE_HOST}
      - OVERWRITEPROTOCOL=${OVERWRITE_PROTOCOL}
      - TRUSTED_PROXIES=${TRUSTED_PROXIES}
      - FORWARDED_FOR_HEADERS=[HTTP_X_FORWARDED_FOR]
    env_file:
      - .env
    depends_on:
      - db
      - redis
    networks:
      - backend

What I could observe is that the owner of the setup.sh file is neither root nor www-data, but 1001. I don't know where 1001 comes from, because on the host it has the same owner then all the other shared/used file have. But doing an exec from the container I can see the followings:

>docker-entrypoint-hooks.d/post-installation # ls -lh
total 4K     
-rwxr-xr-x    1 1001     1001         973 May  9 04:23 setup.sh
/docker-entrypoint-hooks.d/post-installation # ./setup.sh 
/bin/sh: ./setup.sh: Permission denied

Invoking the script directly by passing the full path:

/docker-entrypoint-hooks.d/post-installation # /bin/sh setup.sh 
Initializing nextcloud setup...
System config value default_phone_region set to string HU
System config value default_language set to string hu
System config value force_language set to string hu
System config value default_locale set to string hu_HU
System config value force_locale set to string hu_HU
System config value skeletondirectory set to empty string
System config value maintenance_window_start set to integer 1
Adding additional fs_storage_path_prefix index to the oc_filecache table, this can take some time...
oc_filecache table updated successfully.
/docker-entrypoint-hooks.d/post-installation # 

The setup.sh script holds:

/docker-entrypoint-hooks.d/post-installation # cat setup.sh 
#!/bin/sh
set -eu

run_as() {
    su -p www-data -s /bin/sh -c "$1"
}

if [ ! -f /var/www/html/.setup_done ]; then

    echo "Initializing nextcloud setup..."

    run_as "php /var/www/html/occ config:system:set default_phone_region --value='HU'"
    run_as "php /var/www/html/occ config:system:set default_language --value='hu'"
    run_as "php /var/www/html/occ config:system:set force_language --value='hu'"
    run_as "php /var/www/html/occ config:system:set default_locale --value='hu_HU'"
    run_as "php /var/www/html/occ config:system:set force_locale --value='hu_HU'"
    run_as "php /var/www/html/occ config:system:set skeletondirectory --value=''"
    run_as "php /var/www/html/occ config:system:set maintenance_window_start --value='1' --type=integer"
    run_as "php /var/www/html/occ db:add-missing-indices"

    touch /var/www/html/.setup_done
fi

I don't know what I am missing.

martadinata666 commented 4 months ago

1001 is likely your host userid. The file created had 1001 but www-data of nextcloud (inside container) not 1001, hence permission denied. Fast fix set 777 or set ownership to www-data id of container(#id www-data)

frenkdefrog commented 4 months ago

1001 is likely your host userid. The file created had 1001 but www-data of nextcloud (inside container) not 1001, hence permission denied. Fast fix set 777 or set ownership to www-data id of container(#id www-data)

Already tried it, didn't help. I would like to avoid to setting 777, but if there is no other solution can help, this might be the one...

joshtrichards commented 4 months ago

or set ownership to www-data id of container(#id www-data)

I'm away from my desk at the moment, but I believe the id is 82 in the Alpine FPM images:

https://github.com/docker-library/php/blob/396ead877c1751e756f484e01ac72c93925dfaa8/8.3/alpine3.19/fpm/Dockerfile#L32

So try chown 82:82 xxx.

joshtrichards commented 4 months ago

I just noticed you're trying to su within your script. The script runs with the uid of your Nextcloud installation. That'll be www-data.

If I try to execute the script from the docker container it is the same, so I assume something is around how alpine handles these bash scripts. But if I invoke the shell script with "/bin/sh changesettings.sh" (using the right path, of course) the script can run.

/docker-entrypoint-hooks.d/post-installation # /bin/sh setup.sh Initializing nextcloud setup...

You seem to be executing (for testing) your in-container commands as root based on your prompt.

Your script contains this:

 run_as() {
    su -p www-data -s /bin/sh -c "$1"
}

That won't work. It's also unnecessary (if I understand your goal - since it'll already run as www-data).

https://github.com/nextcloud/docker?tab=readme-ov-file#using-the-nextcloud-command-line-interface

app    | sh: /docker-entrypoint-hooks.d/post-installation/setup.sh: Permission denied
app    | ==> Failed at executing "/docker-entrypoint-hooks.d/post-installation/setup.sh". Exit code: 126

So this isn't a bug in the image's hook support.

If you get stuck still, I suggest popping over to the community help forum: https://help.nextcloud.com