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.