nextcloud/docker

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

frenkdefrog opened this issue · 6 comments

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.

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?

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.

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)

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...

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.

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