ENV变量未从Docker传递到节点JS代码中

时间:2019-05-12 10:56:11

标签: node.js dockerfile

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

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

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值

谢谢。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

由于您的应用程序和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文件中声明这两个服务,然后它们将自动在同一网络上运行,而无需您创建一个。