我正在尝试设置另一个dockerized node app。我已经有一个启动并运行应用程序并按预期工作。但是第二个应用程序启动时无法启动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}`);
});
}
答案 0 :(得分:0)
您可能缺少在docker-compose.yml上定义 web 服务的命令:
...
entrypoint: /bin/bash
tty: true
command: "npm start"
...
请记住,当 db 启动时,即使很难 web 启动,也不能保证在启动应用程序时数据库已准备就绪。
docker-cmpose docs建议使用
等待, dockerize 或sh兼容等待来控制启动顺序。
您还可以定义HEALTHCHECK(或Dockerfile healthcheck)以检查数据库是否可用。
答案 1 :(得分: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 Swarm或Kubernetes。
希望有所帮助。