首页 > 解决方案 > docker-compose up 无法启动容器服务之一

问题描述

我在 docker-compose.yaml 文件中定义了 3 个服务。触发此命令时,其中 2 个服务(my-app_my-app_1 和 my-app_mongodb_1)会自动启动docker-compose -f docker-compose.yaml up。但未能启动其中一项服务(my-app_mongo-express_1)。补充一下,我可以通过docker start my-app_mongo-express_1单独执行再次成功启动失败的容器。

文件内容 - 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

的输出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

mongo-express 容器的 Docker 日志:

→ 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.

如果我单独启动该容器,则可以正常工作:

→ 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…&quot;   mongo-express       running             0.0.0.0:8080->8081/tcp, :::8080->8081/tcp
my-app_mongodb_1         "docker-entrypoint.s…&quot;   mongodb             running             0.0.0.0:27017->27017/tcp, :::27017->27017/tcp
my-app_my-app_1          "docker-entrypoint.s…&quot;   my-app              running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp

我错过了什么?为什么我无法使用 一起启动所有容器docker-compose up

标签: dockerdocker-compose

解决方案


您可以使用该depends_on选项来控制定义的服务启动的顺序。

在这种特定情况下,服务对mongo-express服务有依赖关系mongodb,因此如果mongo-express服务之前启动mongodb,它将无法连接:

Could not connect to database using connectionString

这就是mongo-express手动启动服务成功的原因(因为mongodb已经在运行)。但是,请注意您可能仍需要解决的文档中的以下警告:

但是,对于启动 Compose 不会等到容器“准备好”(无论这对您的特定应用程序意味着什么) - 只等到它正在运行。. . 要处理这个问题,请将您的应用程序设计为在发生故障后尝试重新建立与数据库的连接。如果应用程序重试连接,它最终可以连接到数据库。


推荐阅读