skip to Main Content

Im trying to run a bash script in a mongo db container on start up, so i have a script file and i put the location of the script file in the command argument of my docker-compose, like so:

mongo1:
container_name: mongo1
image: mongo:4.4
volumes:
  - ~/mongors/data1:/data/db
  - ./rs-init.sh:/scripts/rs-init.sh
networks:
  - mongors-network
ports:
  - 27021:27017
links:
  - mongo2
  - mongo3
restart: always
entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "dbrs" ]
command: /scripts/rs-init.sh

But when i do docker-compose up, it says this command is invalid, then gives me all the options for mongodb commands:

Invalid command: /scripts/rs-init.sh
 Options:
   --networkMessageCompressors arg (=snappy,zstd,zlib)
                                         Comma-separated list of compressors to
                                         use for network messages

 General options:
   -h [ --help ]                         Show this usage information
   --version                             Show version information
   -f [ --config ] arg                   Configuration file specifying

How do i run this bash script in the container on startup?

2

Answers


  1. To understand the error, you need to understand the relationship between command and entrypoint: the value of command is provided as an argument to whatever is defined in entrypoint, so given this:

    entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "dbrs" ]
    command: /scripts/rs-init.sh
    

    You are trying to run the command line:

    /usr/bin/mongod --bind_ip_all --replSet dbrs /scripts/rs-init.sh
    

    …which doesn’t make any sense; /scripts/rs-init.sh isn’t a valid argument to the mongod command.


    As @Turing85 points out in a comment, the correct solution in this case is to take advantage of the behavior built into the mongo container: it looks for initialization files in /docker-entrypoint-initdb.d. For this to work, you need to not specify your own entrypoint in your docker-compose.yaml (because doing so overrides the ENTRYPOINT baked into the container image):

    mongo1:
      container_name: mongo1
      image: mongo:4.4
      volumes:
        - ~/mongors/data1:/data/db
        - ./rs-init.sh:/docker-entrypoint-initdb.d/rs-init.sh
      networks:
        - mongors-network
      ports:
        - 27021:27017
      restart: always
    

    Unrelated to your question: You should also remove the links section from your docker-compose.yaml file; the use of links has been deprecated for years (because it is fragile in the event that one of the linked containers restarts); you can just refer to other containers in your compose file by name.

    Login or Signup to reply.
  2. When you have an ENTRYPOINT and a CMD in the same container run, the CMD is passed to the ENTRYPOINT as a parameter and you end up only having a single, combined command being executed. In your case, the command ends up being

    /usr/bin/mongod --bind_ip_all --replSet dbrs /scripts/rs-init.sh
    

    and Mongo complains that it doesn’t understand the last parameter.

    Instead, you can change your entrypoint to a shell and run the 2 commands you want by concatenating them with &&, like this

    entrypoint: ["/bin/bash"]
    command: -c '/scripts/rs-init.sh && docker-entrypoint.sh mongod'
    

    I’ve chosen to start Mongo with the ‘normal’ startup script. If you prefer your existing way of doing it (/usr/bin/mongod --bind_ip_all --replSet dbrs), you should be able to use that instead.

    As a note, you should only do this if you want the script to run every time you start the container. If you want the script to only run when you’re initializing a new database (i.e. the /data/db volume mount is empty), then you should use the /docker-entrypoint-initdb.d directory as @Turing85 and @larsks suggest. But as I read your post, you want to run it every time.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search