当在Docker上运行时,节点JS预期会话未定义,但在MAC上运行良好

我有一个简单的Node JS Web应用程序服务器,允许用户login和发布/编辑一个简单的博客。 我使用Redis作为会话存储,使用CouchDB作为我的数据库。 我在我的MAC上运行一切(Node应用程序,Redis,Couch DB)并使用运行在MAC上的浏览器连接到它( https:// localhost:3000或localhost:3001)。 我可以login,张贴/编辑博客一切工作正常。

上周我尝试dockerizing我的节点JS应用程序。 基本上,我的节点应用程序在Docker容器上运行,但是我的redis和couchdb继续在主机上运行(即我的MAC)。 我已经使用docker机器dockerize节点的应用程序。

Docker机器(Docker VM)的IP为: 192.168.99.101
我的MAC地址: 192.168.0.100

我连接我的浏览器( https://192.168.99.101:3000192.168.99.101:3001 ),我看到login页面。 然后我inputlogging凭证。 我的浏览器将页面发布到docker上的节点应用程序。 节点应用程序读取用户,从CouchDB(运行在MAC主机上)passwd并成功validation密码是否正确。 但是,节点服务器无法从POST请求对象获取有效的会话,因此无法保存会话。 我经历了很多关于这个主题的stackoverflow和其他文章,没有任何帮助。

我已经确定networking不是问题。 即,我可以使用curl命令从docker shell访问redis和couchdb。

是否将我的浏览器连接到不同的物理IP导致此问题? 我应该切换到域名? 我想更好地理解这里发生了什么。 感谢你的帮助。

初始化:

const express = require('express'); const bodyParser = require('body-parser'); var app = express(); const http = require('http'); const https = require('https'); const mustache = require('mustache'); var cookieParser = require('cookie-parser'); var session = require('express-session'); //var cookieSession = require('cookie-session'); const redis = require("redis"); const redisStore = require('connect-redis')(session); const redisClient = redis.createClient(); : : app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); app.use(cookieParser()); app.use( session( { secret: REDIS_SECRET_KEY, // create new redis store. store: new redisStore({ host: REDIS_SERVER_HOST, port: REDIS_SERVER_PORT, client: redisClient,ttl : 260}), // REDIS_SERVER_HOST = 192.168.0.100, REDIS_SERVER_PORT=6379 saveUninitialized: false, resave: false, cookie: { expires: false, maxAge: 30 * 24 * 60 * 60 * 1000 } })); : : // Logic to setup various routes app.get('/', function(req, res) { var userName = getUserName(req); if (userName != "") res.redirect('/home'); else res.redirect('/login'); }); /** Login page. After login user is redirected to home page */ app.get('/somepage', function(req, res) { : }); : : 

在Docker上运行时,loginfunction没有看到cookie或会话。 它在我的MAC上运行时看到了一切。

 function login(user, passwd, dbPasswd) { if (dbPasswd == passwd) { // Store userID in REDIS session! if (postReq.cookies) console.log("Cookie: -> ", postReq.cookies); // Cookie is empty when on docker, but is fine when run on my MAC postReq.session.key = userName; // BOMBS on docker, works fine when run on my MAC postResp.redirect("/home"); } // Logic to handle login failure } 

在Docker上运行时,我看到下面的错误:

 /usr/src/app/mysource.js:760 postReq.session.key = userName; ^ TypeError: Cannot set property 'key' of undefined at IncomingMessage.<anonymous> (/usr/src/app/mysource.js:760:26) at emitNone (events.js:72:20) at IncomingMessage.emit (events.js:166:7) at endReadableNT (_stream_readable.js:913:12) at nextTickCallbackWith2Args (node.js:442:9) at process._tickCallback (node.js:356:17) 

尽我所能,我已经validation了以下内容:
1)节点应用程序在我的MAC上运行良好
2)docker和MAC之间没有networking问题。 我能够从dockershell访问redis,couchDB
3)在MAC和docker环境之间,package.json和节点模块是相同的
4)阅读关于这个问题的几篇文章,但不知道发生了什么问题

请帮忙!!

Atlast,我用我的代码发现了这个问题。 非常感谢rudeamanuel为redisClient添加事件监听器的非常有用的技巧。

当我添加事件监听器时,我的节点应用程序的docker部署一直在使用redis连接错误,如下所示:

 UNABLE to establish connection with Redis { [Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379] code: 'ECONNREFUSED', errno: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 6379 } 

回想一下,我已经初始化了我的快速会议如下,所以我一直在摸摸自己为什么会继续连接到本地,尽pipe我指定了正确的Redis主机。

 const redisClient = redis.createClient(); : : app.use( session( { secret: REDIS_SECRET_KEY, // create new redis store. store: new redisStore({ host: REDIS_SERVER_HOST, port: REDIS_SERVER_PORT, client: redisClient,ttl : 260}), // REDIS_SERVER_HOST = 192.168.0.100, REDIS_SERVER_PORT=6379 saveUninitialized: false, resave: false, cookie: { expires: false, maxAge: 30 * 24 * 60 * 60 * 1000 } })); 

看来下面的语句是问题:

 new redisStore({ host: REDIS_SERVER_HOST, port: REDIS_SERVER_PORT, client: redisClient,ttl : 260}) 

当我初始化redisClient,它似乎客户端默认为本地和6379,随后当我用客户端和主机,端口信息,redisStore对象初始化redisStore忽略主机/端口,并采取客户端对象的参数。 所以要解决这个问题,

 redisClient = redis.createClient(REDIS_SERVER_PORT, REDIS_SERVER_HOST); : : app.use(session( { secret: REDIS_SECRET_KEY, // create new redis store. store: new redisStore({client: redisClient, ttl: 260}), saveUninitialized: false, resave: false, cookie: { expires: false, maxAge: 30 * 24 * 60 * 60 * 1000 } })); 

这解决了它。 很多,非常感谢这个论坛,我能够迅速解决我的问题。 你们真棒!