【问题标题】:How can I spin up multiple node js services inside of a single docker compose?如何在单个 docker compose 中启动多个节点 js 服务?
【发布时间】:2020-02-16 21:21:41
【问题描述】:

所以我想做的是让 2 个 docker 容器运行(MongoDB 和 Postgres),这两个容器都在工作。现在我想做的是创建 2 个服务(node.js 实例),它们将从单独的容器连接,这些容器将查询和运行它们的数据库。每个服务应该只访问一个数据库。

显示我的 docker-compose.yml

services:

  #mongodb set up
  web:
    image: node
    build: ./mongodb_service
    ports:
    - 4000:4000
    depends_on:
    - mongodb

  mongodb:
    image: mongo
    expose:
    - '27017'

  web_postgres:
    image: node
    build: ./postgres_service
    ports:
      - "3000:3000"
    depends_on:
    - postgresdb

  #postgres db definition the env vars should be put in a properties file and passed to it somehow
  postgresdb:
    image: postgres
    #the health check confirms that the db is ready to accept connections and not just the container
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - PGUSER=user
      - PGPASSWORD=1234
      - PGPORT=5432
      - PGDATABASE=customerdirectory
#   Maps port 54320 (localhost) to port 5432 on the container. You can change the ports to fix your needs.
    ports:
      - "54320:5432"

目前正在破坏的是我的web_postgres 服务。当我运行docker-compose up 时,我注意到来自web 服务的console.log() 命令最终位于web_postgres 这就是我的意思web_postgres error。在图像的顶部,我的web_postgres_1 服务正在打印来自web 服务的内容。

我的docker-compose.yml 是否正确设置为让这些容器独立运行?

如果有什么缺失的部分,请 lmk 将上传。 非常感谢您的帮助。

这是来自我的web_postgres 服务的server.js 文件。

const express = require("express");
const { Pool, Client } = require('pg')
const app = express()
// pools will use environment variables
// for connection information
const pool = new Pool({
  user: 'user',
  host: 'localhost',
  database: 'customerdirectory',
  password: '1234',
  port: 5432,
})

pool.query('SELECT NOW()', (err, res) => {
  console.log(err, res)
  pool.end()
})

app.get("/", (req, res) => {
  res.send("Hello from Node.js app \n");
});

app.listen('3000', () =>{
  console.log("I hate this damn thingy sometimes")
})

这是打印出来的web 服务server.js 代码

const express = require("express");
var MongoClient = require('mongodb').MongoClient;
const app = express();

MongoClient.connect("mongodb://mongodb:27017", function(err, db) {
  if(err) throw err;
  db.close()
})

app.get("/", (req, res) => {
  res.send("Hello from Node.js app \n");
});

app.listen('4000', () =>{
  console.log("I hate this damn thingy sometimes")
})

【问题讨论】:

  • 我怀疑image: 标签引起了问题;你告诉 Docker Compose 两个服务都在运行同一个镜像(使用两个不同的 Dockerfile 来构建它)。不过,显示从错误容器中打印出字符串 web_postgres error 的代码会有所帮助。
  • @DavidMaze 上传,有趣的是当我以某种方式 ssh 进入容器时它们都共享同一个文件系统!!!这怎么可能?

标签: node.js mongodb postgresql docker docker-compose


【解决方案1】:

您需要从您的docker-compose.yml 文件中删除image:。当您指定两个容器具有相同的 image: 时,Docker Compose 会从表面上理解您并为两者使用相同的图像,即使有单独的 build: 指令也是如此。

image: 的文档说明:

如果图像不存在,Compose 会尝试拉取它,除非您还指定了 build,在这种情况下,它会使用指定的选项构建它并使用指定的标签对其进行标记。

所以这里发生的是 Compose 构建第一个服务的镜像,并将其标记为 node:latest(可能与同名的标准 Docker Hub 镜像冲突);当第二个容器启动时,它会看到该图像已经存在,因此它会重用它。

您可以通过简单的设置来演示这一点。使用子目录ab 创建一个新的空目录。创建a/Dockerfile

FROM busybox
WORKDIR /app
RUN echo Hello from a > hello.txt
EXPOSE 80
CMD ["httpd", "-f"]

类似地用不同的字符串创建b/Dockerfile

现在创建这个docker-compose.yml 文件:

version: '3'
services:
  a:
    # image: image
    build: a
    ports: ['8000:80']
  b:
    # image: image
    build: b
    ports: ['8001:80']

您可以按原样启动它,curl http://localhost:8000/hello.txt 和类似的端口 8001 可以看到两个不同的响应。但是,如果您取消注释这两个 image: 行,它们都将返回相同的字符串。在 Docker Compose 输出中也有一些线索,其中一个路径构建了两个镜像,而另一个只构建了一个,并且当您指定镜像名称时,会出现有关命名镜像不存在的警告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    相关资源
    最近更新 更多