【问题标题】:ENV variables not passing into node JS code from DockerENV 变量未从 Docker 传递到节点 JS 代码
【发布时间】:2019-05-12 22:04:47
【问题描述】:

我正在运行一个示例代码,我正在将 mongoDB 的 env 变量从 docker run 解析到我的节点 js 中。

这是我当前的数据库配置文件

const mongoClient = require('mongodb').MongoClient;
const mongoDbUrl = process.env.MONGODB_URL;
console.log(process.env.MONGODB_URL)
let mongodb;

function connect(callback){
    mongoClient.connect(mongoDbUrl, (err, db) => {
        mongodb = db;
        callback();
    });
}
function get(){
    return mongodb;
}

function close(){
    mongodb.close();
}

module.exports = {
    connect,
    get,
    close
};

这是我的 Docker 文件

FROM node:latest
ENV MONGODB_URL=${MONGODB_URL}
WORKDIR /app
COPY package.json /app
COPY . /app
RUN npm install 
EXPOSE 4000
CMD ["node", "server.js"]

在我的 server.js 中,我正在测试哪里可以连接到在其中解析的 mongoDB URL



var bodyParser = require('body-parser')
, MongoClient = require('mongodb').MongoClient
, PORT = 4000
, instantMongoCrud = require('express-mongo-crud') // require the module
, express = require('express')
, app = express()
, path = require('path')
, options = { //specify options
    host: `localhost:${PORT}`
}
, db = require('./connection')


// connection to database
db.connect(() => {

    app.use(bodyParser.json()); // add body parser
    app.use(bodyParser.urlencoded({ extended: true }));

    // get function 
    app.get('/', function(req, res) {
        db.get().collection('users').find({}).toArray(function(err, data){
            if (err)
                console.log(err)
            else
                res.render('../views/pages/index.ejs',{data:data});
        });
    });

    // post functions
    app.post('/adduser', function(req, res) {
        var name=req.body.name
        var email=req.body.email
        var occupation=req.body.occupation
        var username=req.body.username

        console.log(name)
        console.log(email)

        db.get().collection('users').count({email : email}, function(err, result){
            console.log(result)
            if (result){
                console.log("user exists")
                res.send("user exists")
            }else{
                db.get().collection('users').save({name:name, email:email, occupation:occupation, username:username}, {w:1},function (err, result) {
                    if (err){
                        console.log("error")
                    } else{
                        console.log("success")
                        res.send("successful")
                    }        
                });
            }

        });


    });

    // delete user
    app.post('/deleteUser', function(req, res) {
        var email=req.body.email
        console.log(email)
        db.get().collection('users').deleteOne({email: email}, function(err,result){
            if (err){
                console.log("error")
            }else{
                console.log("successfully deleted user")
                res.send ("successfully deleted user")

            }

        });

    });

    app.listen(PORT, ()=>{
        console.log('started');
        console.log(db)
    })

    app.use(instantMongoCrud(options)); // use for the instant Mongo CRUD 
});




我跑了

docker run -e MONGODB_URL='mongodb://localhost:27017/user' <containerID>

并遇到连接未定义的问题。

TypeError: Cannot read property 'collection' of null
    at /app/app.js:24:17

有什么建议吗,因为我认为 process.env 可以获取 env 值

谢谢。

【问题讨论】:

  • 你能用docker run -e MONGODB_URL='mongodb://localhost:27017/user' &lt;containerID&gt; env | grep MONGODB_URL检查环境吗?
  • 嗨,是的 $ docker run -e MONGODB_URL='mongodb://localhost:27017/user' 3e7e3c1fe510 env | grep MONGODB_URL MONGODB_URL=mongodb://localhost:27017/user
  • 您本地的 MongoDB 也是 docker 容器还是只是普通安装?
  • 嗨@mihai,我正在为mongoDB使用docker容器。我也尝试过 docker run -d -e "MONGODB_URL=mongodb://mongodb/user" -p 4000:4000 e922a127d049 但没有用
  • 当然没用,因为它们在不同的网络上。您需要将它们放在同一个网络上。我会为它写一个解决方案,因为它更具可读性

标签: node.js dockerfile


【解决方案1】:

由于您的应用程序和您的 mongoDB 实例都在容器中运行,因此通过将它们连接到同一网络很容易让它们相互通信。

这些是步骤:

#create a new network
docker network create app-network

#use your normal docker run for mongodb but add the --network flag
docker run --network app-network --name=mongodb ....

#run your app container on the same network
docker run --network app-network -d -e "MONGODB_URL=mongodb://mongodb/user" -p 4000:4000 e922a127d049

如果您也熟悉 docker-compose,您可以在 docker-compose.yml 文件中声明这两个服务,然后它们会自动在同一网络上运行,而无需您创建一个。

【讨论】:

    【解决方案2】:

    在容器内部,localhost 并不是指你的本地机器。对于 iOS 或 Windows,您可以通过在 MONGODB_URL 中将 localhost 替换为 host.docker.internal 来解决此问题。这将解析为主机使用的内部 IP 地址。如果使用 Linux,您可以在 docker run 中使用标志 --network="host"

    【讨论】:

    • 啊,我明白了。我现在设法让它工作: docker run -d --network=mongo_db_default --link=mongodb:mongodb -e "MONGODB_URL=mongodb://mongodb/user" -p 4000:4000 跨度>
    • 请问如果我想访问 mongoDB 并且这个 mongoDB 是否作为容器运行在另一台机器上,即 aws 中的 ec2 上,该怎么办?
    • 我设法得到它: docker run -d --network=mongo_db_default --link=mongodb:mongodb -e MONGODB_URL='mongodb://:27017/user' - p 4000:4000 e922a127d049
    猜你喜欢
    • 2021-12-13
    • 2022-01-03
    • 1970-01-01
    • 2020-04-10
    • 2021-11-23
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多