简体   繁体   English

如何构建 docker 容器端口? 使用--net 还是--link?

[英]How to structure docker container ports? Use --net or --link?

I have 2 docker containers.我有 2 个 docker 容器。 One contains a simple node.js web app which contains server information and MongoDB connection details.一个包含一个简单的 node.js web 应用程序,其中包含服务器信息和 MongoDB 连接详细信息。 The second contains a running instance of MongoDB.第二个包含 MongoDB 的运行实例。

I am attempting to run the web app container to connect to the MongoDB container like so:我正在尝试运行 web 应用程序容器以连接到 MongoDB 容器,如下所示:

docker run --link mongodb2:mongodb2 -p 49160:8080 -it --name web node-web-app

Doing this I can successfully access and view the hosted page at http://hostname:49160/ but I cannot connect to MongoDB.这样做我可以成功访问和查看位于 http://hostname:49160/ 的托管页面,但我无法连接到 MongoDB。

Another method I have tried is:我尝试过的另一种方法是:

docker run --net container:mongodb2 -ti --name web node-web-app

Here I can successfully connect to MongoDB, but I cannot access my hosted page at http://hostname:27017/.在这里,我可以成功连接到 MongoDB,但无法访问位于 http://hostname:27017/ 的托管页面。 Instead I receive the message:相反,我收到消息:

It looks like you are trying to access MongoDB over HTTP on the native driver port.

I have also attempted to pass port details like so using the --net method:我还尝试使用 --net 方法传递端口详细信息:

docker run --net container:mongodb2 -p 49160:8080 -ti --name web node-web-app

but I receive a docker error:但我收到 docker 错误:

docker: Error response from daemon: conflicting options: port publishing and the container type network mode.
See 'docker run --help'.

I believe there is an issue with the way I am configuring my ports, but I am new to both docker and setting up web servers.我相信我配置端口的方式存在问题,但我对 docker 和设置 web 服务器都是新手。

Here is my web app code:这是我的 web 应用程序代码:

'use strict';
const express = require('express');
// App
const app = express();

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

const MongoClient = require('mongodb').MongoClient;

// Connect URL
const url = 'mongodb://127.0.0.1:27017';

var db;
var ticket;

MongoClient.connect(url, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}, (err, client) => {
    if (err) {
        return console.log(err);
    }

    // Specify database you want to access

    db = client.db('DB');

    console.log(`MongoDB Connected: ${url}`);

    ticket = db.collection('ticket');

    ticket.find().toArray((err, results) => {
        console.log(results);
    });

});

//Routes
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html')
});


app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`)

You should use a named Docker network to connect between containers.您应该使用名为 Docker 的网络来连接容器。 Once you do, the other containers' names will be usable as host names.完成后,其他容器的名称将可用作主机名。

docker network create some-network
docker run -d --net some-network --name mongodb2 mongo
docker run -d --net some-network --name app -p 49160:8080 node-web-app

In your source code, you can't hard-code the location of the database, since it's somewhat likely it won't be on the same machine or in the same container when you deploy it.在您的源代码中,您不能对数据库的位置进行硬编码,因为当您部署它时,它很可能不在同一台机器上或同一容器中。 localhost could be a reasonable developer default but the option needs to be configurable. localhost可能是合理的开发人员默认设置,但该选项需要可配置。

const mongoHost = process.env.MONGO_HOST || 'localhost';
const url = `mongodb://${mongoHost}:27017`;
docker run ... -e MONGO_HOST=mongodb2 ...

If you're using Docker Compose to launch things, it provides a default network for you (different from the "default bridge network" in the core Docker documentation) and you need to do very little setup;如果您使用 Docker Compose 来启动事物,它会为您提供一个default网络(不同于核心 Docker 文档中的“默认桥接网络”)并且您需要做的设置很少; just use the other container's Compose service name as a host name.只需使用其他容器的 Compose 服务名称作为主机名。

version: '3.8'
services:
  mongodb2:
    image: mongo
  app:
    build: .
    ports: ['49160:8080']
    environment:
      - MONGO_HOST=mongodb2

Of the other options you propose, --link is considered obsolete now that named networks have essentially replaced it.在您提出的其他选项中, --link被认为已过时,因为命名网络已基本上取代了它。 Setting one container to run in another's network namespace is also a very unusual setup, and it comes with limitations like what you show.将一个容器设置为在另一个的网络命名空间中运行也是一种非常不寻常的设置,并且它具有您所展示的限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM