使用Docker在Mac上设置后无法启动localhost:3000

4
我正在尝试设置另一个基于 Docker 的节点应用程序。我已经有一个正在运行的应用程序并且按预期工作。但是第二个应用程序在启动时失败并提示 http://localhost:3000 。请注意,在处理第二个应用程序时,第一个应用程序已经被正确关闭。
以下是我的 docker-composer.yml 文件内容:
    version: '3.0'

services:
  web:
    image: node:boron
    ports:
      - "3000:3000"
    volumes:
      - .:/myapp
    environment:
      NODE_ENV: 'dev'
      DATABASE_URL: postgres://postgres:xxxx@db:5432/myapp
    depends_on:
      - db 
    entrypoint: /bin/bash
    tty: true

  db:
    image: postgres:9.6.3
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "xxxxx"

$ docker-compose run --service-ports web 
$cd app
$npm run web

按预期运行应用程序

docker ps -a 显示映射为 0.0.0.0:3000->3000/tcp

但是当我启动 http://localhost:3000/api/message

它加载了一条消息,指出该网站无法启动...

$docker ps
b9b90610051a        node:boron          "/bin/bash"              6 seconds ago       Up 6 seconds        0.0.0.0:3000->3000/tcp   app_web_2
14739cf56f24        postgres:9.6.3      "docker-entrypoint.s…"   6 hours ago         Up 6 hours          5432/tcp                 app_db_1


package.json
{
  "name": “my app”,
  "engines": {
    "node": "6.11.1",
    "npm": "3.10.10"
  },
  "version": "0.1.0",
  "description": "",
  "main": "dist/bin/www/index.js",
  "scripts": {
    "start": "node dist/bin/www/index.js",
    "build": "tic -p .",
    "dev": "ts-watch --onSuccess \"node ./dist/bin/www/index.js\""
  },

index.ts文件- HTTP监听代码

const port = normalizePort(process.env.PORT || 3000);
const env = Environment.for(process.env.NODE_ENV || 'dev');
console.log('Starting server...'+port)
function startServer(env : Environment) {

  const app = new App(env).express;
  app.set('port', port);

  const server = http.createServer(app);
  server.on('error', onError);

  server.on('listening', function() {
    let addr = server.address();
    let bind = (typeof addr === 'string') ? `pipe ${addr}` : `port ${addr.port}`;
    console.log(`Listening on ${bind}`);
  });  
}

docker ps 命令(不带 -a 标志)会返回什么? - tgallacher
@whites11 它启动了服务器,但当我通过 Postman 获取 URL 时,它也无法到达服务器...通常在 console.log 中会显示 GET 请求... - user269867
你能分享一下你的 package.json 文件中关于 web script 的定义吗? - whites11
@whites11 请检查...我已经删除了依赖项...如果这些是必要的,请告诉我。 - user269867
@GonzaloMatheu 显示“附加到”的内容,就这样。 - user269867
显示剩余8条评论
2个回答

0

你可能忘记在docker-compose.yml中定义web服务的command

...
entrypoint: /bin/bash 
tty: true 
command: "npm start"
...

请注意,即使在启动db时会启动web,但不能保证在启动应用程序时数据库已准备就绪。 docker-cmpose docs建议使用
wait-for-itdockerize或sh兼容的wait-for来控制启动顺序。
您还可以定义一个HEALTHCHECK(或Dockerfile healthcheck)来检查数据库是否可用。

在 package.json 文件中,我有这样一行代码:"start": "node dist/bin/www/index.js"。 - user269867
我的意思是将其添加到docker-compose.yml文件中。 - Gonzalo Matheu
我已经有一个容器化的 Docker 应用程序,现在我想要启动另一个......是否可能运行多个 Docker 容器以分别运行 Node 应用程序。 - user269867
不在同一个端口上(在主机上) - tgallacher
@tgallacher 如果我使用不同的端口,那么我可以在同一台主机上运行不同的Node.js应用程序吗?如果您有任何参考资料,那就太好了。 - user269867

0
回顾您的compose文件,您需要确保入口节点脚本调用了启动函数startServer,因为您定义了它但没有调用它。您还应该确保Web服务正在调用您的Nodejs脚本。例如:

version: '3.0'
services:
  web:
    image: node:boron
    ports:
      - "3000:3000"
    volumes:
      - .:/myapp
    environment:
      NODE_ENV: 'dev'
      DATABASE_URL: postgres://postgres:xxxx@db:5432/myapp
    depends_on:
      - db 
    entrypoint: ["/bin/bash"]
    command: ["node", "dist/index.js"]
  db:
    image: postgres:9.6.3
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "xxxxx"

由于您正在使用Typescript,因此需要构建JS文件,我假设它们将位于dist文件夹中。此外,如果您的应用程序需要等待db运行起来,您可以使用此处讨论的示例wait-for-postgres.sh脚本:https://docs.docker.com/compose/startup-order/;然后相应地更新您的entrypoint

至于在同一主机上运行多个nodejs应用程序,只要它们各自绑定到主机上的不同端口,就可以这样做。因此,您可以复制您的web服务,并更新应用程序入口点(如上所述的dist/index.js)和Docker主机端口(即您的计算机--内部节点应用程序仍然可以监听3000)。例如,

version: '3.0'
services:
  web1:
    image: node:boron
    ports:
      - "3000:3000"
    volumes:
      - .:/myapp
    environment:
      NODE_ENV: 'dev'
      DATABASE_URL: postgres://postgres:xxxx@db:5432/myapp
    depends_on:
      - db 
    entrypoint: ["/bin/bash"]
    command: ["node", "dist/index1.js"]
  web2:
    image: node:boron
    ports:
      - "3001:3000"
    volumes:
      - .:/myapp
    environment:
      NODE_ENV: 'dev'
      DATABASE_URL: postgres://postgres:xxxx@db:5432/myapp
    depends_on:
      - db 
    entrypoint: ["/bin/bash"]
    command: ["node", "dist/Index2.js"]
  db:
    image: postgres:9.6.3
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "xxxxx"

如果您需要多个相同的 Web 服务实例以进行扩展或负载管理,则应考虑水平容器扩展解决方案,例如 Docker SwarmKubernetes

希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接