I have defined 3 services in the docker-compose.yaml file. Out of which 2 services (my-app_my-app_1 & my-app_mongodb_1) are getting started automatically when firing this command docker-compose -f docker-compose.yaml up
. But failing to start one of the service (my-app_mongo-express_1). Just to add, I can start the failed container successfully again by executing docker start my-app_mongo-express_1
separately.
Contents of file - docker-compose.yaml:
→ cat docker-compose.yaml
version: '3'
services:
my-app:
image: maryo/my-app:1.2
ports:
- 3000:3000
mongodb:
image: mongo
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
volumes:
- mongo-data:/data/db
mongo-express:
image: mongo-express
ports:
- 8080:8081
environment:
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG_MONGODB_ADMINPASSWORD=password
- ME_CONFIG_MONGODB_SERVER=mongodb
volumes:
mongo-data:
driver: local
Output of docker-compose ps
→ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
my-app_mongo-express_1 "tini -- /docker-ent…" mongo-express exited (0)
my-app_mongodb_1 "docker-entrypoint.s…" mongodb running 0.0.0.0:27017->27017/tcp, :::27017->27017/tcp
my-app_my-app_1 "docker-entrypoint.s…" my-app running 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
Docker logs for mongo-express container:
→ docker logs my-app_mongo-express_1
Welcome to mongo-express
------------------------
(node:8) [MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
Could not connect to database using connectionString: mongodb://admin:password@mongodb:27017/"
(node:8) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [mongodb:27017] on first connect [Error: connect ECONNREFUSED 172.25.0.4:27017
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16) {
name: 'MongoNetworkError'
}]
at Pool.<anonymous> (/node_modules/mongodb/lib/core/topologies/server.js:441:11)
at Pool.emit (events.js:314:20)
at /node_modules/mongodb/lib/core/connection/pool.js:564:14
at /node_modules/mongodb/lib/core/connection/pool.js:1000:11
at /node_modules/mongodb/lib/core/connection/connect.js:32:7
at callback (/node_modules/mongodb/lib/core/connection/connect.js:289:5)
at Socket.<anonymous> (/node_modules/mongodb/lib/core/connection/connect.js:319:7)
at Object.onceWrapper (events.js:421:26)
at Socket.emit (events.js:314:20)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
(node:8) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:8) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Works fine if I start that container separately:
→ docker start my-app_mongo-express_1
my-app_mongo-express_1
→ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
my-app_mongo-express_1 "tini -- /docker-ent…" mongo-express running 0.0.0.0:8080->8081/tcp, :::8080->8081/tcp
my-app_mongodb_1 "docker-entrypoint.s…" mongodb running 0.0.0.0:27017->27017/tcp, :::27017->27017/tcp
my-app_my-app_1 "docker-entrypoint.s…" my-app running 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
What am I missing? Why I am not able to start all the containers together using docker-compose up
?
CodePudding user response:
You can use the depends_on
option to control the order in which your defined services startup.
In this specific case, the mongo-express
service has a dependency on the mongodb
service, and so if the mongo-express
service is started before mongodb
, it will fail to connect:
Could not connect to database using connectionString
This is why starting the mongo-express
service manually succeeds (because mongodb
is already running). However, note the following caveat from the documentation which you may still need to address:
However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it’s running . . . To handle this, design your application to attempt to re-establish a connection to the database after a failure. If the application retries the connection, it can eventually connect to the database.