Search code examples
dockerdocker-composedocker-desktop

Docker Desktop Dev Environment permission denied on script?


Enviroment

I'm new to docker and am trying to setup my project in the new Docker Desktop - Dev Environment feature as a compose project.

Problem

In my compose file I'm setting up a dev mongo server that needs to be initialized as a replicaSet. This requires executing a few commands in mongosh and I have as a separate script. The way I have it works when checked out as a local directory but does not work when Docker Desktop pulls from git directly.

When it's creating the mongo-setup it fails due to permissions:

Container mongo-setup  Starting
Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/scripts/mongosetup.sh": permission denied: unknown
exit status 1

I removed the entry script so the container booted and CLI'd into it. The file does exist, so how do I correct the permissions so that it works? I don't want to have to manually enter the container to change its permissions.

enter image description here

Alternative

Other solutions for this are using the healthcheck to run the command. This however, while works with docker-compose up doesn't work in Docker Desktop Dev Enviroments:

healthcheck:
      test: test $$(echo "rs.initiate().ok || rs.status().ok" | mongo  --quiet) -eq 1
      interval: 10s

This errors out with saying $ needs to be escaped. Doesn't matter how many $ I put. From what I can tell, docker desktop generates its own devenv-docker-compose.yaml from the original docker-compose.yaml and there's a parsing issue with the escaped characters.

Test Repo that fails

https://github.com/jrj2211/mongo-docker-test

Setup Images

enter image description here

enter image description here

Files

# File: .docker/docker-compose.yaml
version: "3.8"
services:
  mongo-setup:
    container_name: mongo-setup
    image: mongo
    restart: on-failure
    networks:
      default:
    volumes:
      - ./.docker/scripts/mongosetup.sh:/scripts/mongosetup.sh
    entrypoint: [ "/scripts/mongosetup.sh" ]
    depends_on:
      - mongodb
  mongodb:
    hostname: mongodb
    container_name: mongodb
    image: mongo:5.0.9
    environment:
      MONGO_INITDB_DATABASE: test
      MONGO_REPLICA_SET_NAME: rs0
    volumes:
      - mongo-data:/data/db
    expose:
      - 27017
    ports:
      - "27017:27017"
    restart: always
    entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs0" ]

volumes:
  mongo-data:
# File: .docker/scripts/mongosetup.sh
#!/bin/bash

MONGODB1=mongodb

echo "Waiting for startup.."
until curl http://${MONGODB1}:27017/serverStatus\?text\=1 2>&1 | grep uptime | head -1; do
  printf '.'
  sleep 1
done

echo Executing setup at `date +"%T" `
mongosh --quiet --host ${MONGODB1}:27017 <<EOF
rs.initiate();
db.getMongo().setReadPref('primaryPreferred');
rs.status();
EOF

Solution

  • Looking at my "ls -la" of the file its not executable. Changing my entry point to include "sh" did the trick. I also set the user as root but not sure if that was necessary:

    entrypoint: ["sh", "/scripts/mongosetup.sh" ]
    user: root
    

    It does sound like this has some drawbacks if you have a more complicated script where some features are not available.

    I'd still be curious if there are any other ways to set this as executable from the docker-compose file.