Home > other >  Can't run a bash script from docker-compose command in mongodb container
Can't run a bash script from docker-compose command in mongodb container

Time:05-03

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?

CodePudding user response:

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.

CodePudding user response:

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.

  • Related