Skip to content
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

docker-entrypoint.sh: executable shell script test is unreliable #1108

Closed
mhw opened this issue Jul 13, 2023 · 3 comments
Closed

docker-entrypoint.sh: executable shell script test is unreliable #1108

mhw opened this issue Jul 13, 2023 · 3 comments

Comments

@mhw
Copy link

mhw commented Jul 13, 2023

docker-entrypoint.sh uses a .sh file's executable mode to decide whether to source or exec the shell script. Due to a long-standing issue on Docker Desktop for macOS when VirtioFS or gRPC FUSE are used all files mounted into the container from the host are executable according to test -x even if the executable bit is not set, so this test is unreliable. As a result non-executable scripts in /docker-entrypoint-initdb.d are executed, giving a Permission denied error and the script does not run.

Although this really needs fixing in Docker Desktop, it's potentially going to lead to hard-to-diagnose issues in Postgres initialisation so I thought it at least worth reporting here for visibility. A possible workaround for the Docker issue could be to use stat and grep: something like if stat -c '%A' "$f" | grep -q '^-..x'; then ....

@yosifkit
Copy link
Member

We had a similar issue in docker-library/mysql#862; no great conclusion there 😞. I'd rather not introduce hacky/fragile code when test -x is the correct detection. The filesystem presenting differing values is where the fix should happen.

To work around it, you can build an image FROM postgres:[version] that copies in your sh scripts.

@mhw
Copy link
Author

mhw commented Jul 17, 2023

Yeah, I'd not be keen on adding the workaround to replace test -x either.

I went with your suggestion in our code. For those who run into this issue the changes came down to the following:

  • Change the docker-compose.yml file to use a built image instead of the upstream Postgres one, and remove the bind mount to /docker-entrypoint-initdb.d:

    --- a/docker-compose.yml
    +++ b/docker-compose.yml
    @@ -9,7 +9,8 @@ services:
           - db
    
       db:
    -    image: postgres:14
    +    build: docker/db-container
    +    # image: postgres:14
         restart: always
         ports:
           - '5434:5432'
    [...]
         volumes:
           - db_data:/var/lib/postgresql/data
    -      - type: bind
    -        source: ./docker/initdb
    -        target: /docker-entrypoint-initdb.d
    +      # - type: bind
    +      #   source: ./docker/initdb
    +      #   target: /docker-entrypoint-initdb.d
           - type: bind
    
  • Create a Dockerfile for the new image:

    # docker/db-container/Dockerfile
    FROM postgres:14
    
    COPY ./initdb /docker-entrypoint-initdb.d
    
  • Move shell and SQL scripts into docker/db-container/initdb so their executable bits are preserved by copying in to the image.

@tianon
Copy link
Member

tianon commented Dec 14, 2023

I'd love to figure out where/why test -x is failing to return the correct answer, but I think that rabbit hole is out of scope here. 🙇 😅 ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants