174

You often see example hello world code for Node that creates an Http Server, starts listening on a port, then followed by something along the lines of:

console.log('Server is listening on port 8000');

But ideally you'd want this instead:

console.log('Server is listening on port ' + server.port);

How do I retrieve the port the server is currently listening on without storing the number in a variable prior to calling server.listen()?

I've seen this done before but I can't find it in the Node documentation. Maybe it's something specific to express?

KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
David Tang
  • 92,262
  • 30
  • 167
  • 149

19 Answers19

196

Express 4.x answer:

Express 4.x (per Tien Do's answer below), now treats app.listen() as an asynchronous operation, so listener.address() will only return data inside of app.listen()'s callback:

var app = require('express')();

var listener = app.listen(8888, function(){
    console.log('Listening on port ' + listener.address().port); //Listening on port 8888
});

Express 3 answer:

I think you are looking for this(express specific?):

console.log("Express server listening on port %d", app.address().port)

You might have seen this(bottom line), when you create directory structure from express command:

alfred@alfred-laptop:~/node$ express test4
   create : test4
   create : test4/app.js
   create : test4/public/images
   create : test4/public/javascripts
   create : test4/logs
   create : test4/pids
   create : test4/public/stylesheets
   create : test4/public/stylesheets/style.less
   create : test4/views/partials
   create : test4/views/layout.jade
   create : test4/views/index.jade
   create : test4/test
   create : test4/test/app.test.js
alfred@alfred-laptop:~/node$ cat test4/app.js 

/**
 * Module dependencies.
 */

var express = require('express');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.use(express.bodyDecoder());
  app.use(express.methodOverride());
  app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
  app.use(app.router);
  app.use(express.staticProvider(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

// Routes

app.get('/', function(req, res){
  res.render('index.jade', {
    locals: {
        title: 'Express'
    }
  });
});

// Only listen on $ node app.js

if (!module.parent) {
  app.listen(3000);
  console.log("Express server listening on port %d", app.address().port)
}
RavenHursT
  • 2,336
  • 1
  • 25
  • 46
Alfred
  • 60,935
  • 33
  • 147
  • 186
  • 1
    Thanks, I think that's exactly what I'm looking for. I'll accept it as soon as I get a chance to test it. Cheers. – David Tang Jan 30 '11 at 20:54
  • 9
    And if you don't want to have that variable `var listener` you can use `this.address().port` inside `app.listen()` callback – Andrei Stalbe Jan 23 '16 at 09:19
  • 1
    What does this look like in Express 5.x? – Diogenes Jul 09 '17 at 18:20
  • 3
    You can also get the port anywhere in a middleware : req.socket.address().port – jlguenego Apr 30 '18 at 11:33
  • 1
    Just to add on to what @AndreiStalbe said, you can use `this.address.port()` but you cannot use that inside an arrow function. you will need to do old school `app.listen(8000, function () { console.log('http://localhost:' + this.address().port); }` (yes, I know backticks are nicer, but I can't do them in stack overflow comments) – WORMSS Apr 26 '19 at 09:19
  • `listener.address` doesn't work when I try to run it from inside an `async` function, not sure why. Express 4.17.1, Node v14.17.0. – Ciro Santilli OurBigBook.com Dec 24 '21 at 09:06
68

In express v3.0,

/* No longer valid */
var app = express.createServer();
app.listen();
console.log('Server running on %s', app.address().port);

no longer works! For Express v3.0, you should create an app and a server this way:

var express = require('express');
var http = require('http');

var app = express();
var server = http.createServer(app);

app.get('/', function(req, res) {
    res.send("Hello World!");
});

server.listen(3000);
console.log('Express server started on port %s', server.address().port);

I ran in to this issue myself and wanted to document the new syntax. This and other changes in Express v3.0 are visible at https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x

dgh
  • 8,969
  • 9
  • 38
  • 49
  • Or you could just use the old method of creating the server, which still works. There just seems to no longer be a way to access the port afterword. However, since you are specifying the port yourself in the call to server.listen, there really isn't a need to use server.address().port, since you can just use the same value that you passed into server.listen. – Mary Hamlin Jul 31 '12 at 16:49
  • (Although I did just read the migration guide and see that the method for creating an app and server that you mentioned above is actually the new preferred method.) – Mary Hamlin Jul 31 '12 at 20:43
  • 3
    @MaryHamlin: This is useful if you are passing `0` to `server.listen()`, in which case a random port number is assigned. You might do this if you’re running several Express apps on one server and you don’t want to manually assign port numbers. – Nate Aug 31 '12 at 07:28
  • `app.listen()` also returns the http server instance. – Vicary Jan 05 '14 at 09:51
33

In case when you need a port at the time of request handling and app is not available, you can use this:

request.socket.localPort
user3348991
  • 331
  • 3
  • 2
27

In the current version (v0.5.0-pre) the port seems to be available as a property on the server object, see http://nodejs.org/docs/v0.4.7/api/net.html#server.address

var server = http.createServer(function(req, res) {
    ...
}

server.listen(8088);
console.log(server.address());
console.log(server.address().address);
console.log(server.address().port);

outputs

{ address: '0.0.0.0', port: 8088 }
0.0.0.0
8088
Jörn Horstmann
  • 33,639
  • 11
  • 75
  • 118
25

I use this way Express 4:

app.listen(1337, function(){
  console.log('Express listening on port', this.address().port);
});

By using this I don't need to use a separate variable for the listener/server.

Christian Landgren
  • 13,127
  • 6
  • 35
  • 31
17

If you're using express, you can get it from the request object:

req.app.settings.port // => 8080 or whatever your app is listening at.
chovy
  • 72,281
  • 52
  • 227
  • 295
11

Requiring the http module was never necessary.

An additional import of http is not necessary in Express 3 or 4. Assigning the result of listen() is enough.

var server = require('express')();

server.get('/', function(req, res) {
  res.send("Hello Foo!");
});

var listener = server.listen(3000);
console.log('Your friendly Express server, listening on port %s', listener.address().port);
// Your friendly Express server, listening on port 3000

Again, this is tested in Express 3.5.1 & 4.0.0. Importing http was never necessary. The listen method returns an http server object. https://github.com/visionmedia/express/blob/master/lib/application.js#L531

james_womack
  • 10,028
  • 6
  • 55
  • 74
8
req.headers.host.split(':')[1]
RockerFlower
  • 727
  • 2
  • 10
  • 28
8

If you did not define the port number and you want to know on which port it is running.

let http = require('http');
let _http = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello..!')
}).listen();
console.log(_http.address().port);

FYI, every time it will run in a different port.

Sheik
  • 91
  • 1
  • 2
7
var express = require('express');    
var app = express();

app.set('port', Config.port || 8881);

var server = app.listen(app.get('port'), function() {
    console.log('Express server listening on port ' + server.address().port); 
});

Express server listening on port 8881

KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
6

You can get the port number by using server.address().port like in below code:

var http = require('http');
var serverFunction = function (req, res) {

    if (req.url == '/') {
        console.log('get method');
        res.writeHead(200, { 'content-type': 'text/plain' });
        res.end('Hello World');
    }

}
var server = http.createServer(serverFunction);
server.listen(3002, function () {
    console.log('server is listening on port:', server.address().port);
});
Shubham Verma
  • 8,783
  • 6
  • 58
  • 79
6

With latest node.js (v0.3.8-pre): I checked the documentation, inspected the server instance returned by http.createServer(), and read the source code of server.listen()...

Sadly, the port is only stored temporarily as a local variable and ends up as an argument in a call to process.binding('net').bind() which is a native method. I did not look further.

It seems that there is no better way than keeping a reference to the port value that you provided to server.listen().

Eric Bréchemier
  • 1,908
  • 3
  • 18
  • 30
  • 1
    +1 and thanks for the research. I'm accepting Alfred's answer since he found the exact thing I was looking for, but I'm glad I know it's not in the Node core now. – David Tang Jan 31 '11 at 07:29
5

The simplest way to convert from the old style to the new (Express 3.x) style is like this:

var server = app.listen(8080);
console.log('Listening on port: ' + server.address().port);

Pre 3.x it works like this:

/* This no longer works */
app.listen(8080);
console.log('Listening on port: ' + app.address().port);
Waylon Flinn
  • 19,969
  • 15
  • 70
  • 72
3

I was asking myself this question too, then I came Express 4.x guide page to see this sample:

var server = app.listen(3000, function() {
   console.log('Listening on port %d', server.address().port);
});
Tien Do
  • 10,319
  • 6
  • 41
  • 42
  • 2
    But I don't know why server.address().address is always 0.0.0.0 on my local development machine (OSX). – Tien Do Oct 02 '14 at 06:20
  • This should be added to the accepted answer since Express 4.0 no longer treats app.listen() as a synchronous operation and you need to run listener.address() in the callback now. – RavenHursT Aug 12 '15 at 21:27
0

The findandbind npm addresses this for express/restify/connect: https://github.com/gyllstromk/node-find-and-bind

muckabout
  • 1,923
  • 1
  • 19
  • 31
-1
const express = require('express');                                                                                                                           
const morgan = require('morgan')
const PORT = 3000;

morgan.token('port', (req) => { 
    return req.app.locals.port; 
});

const app = express();
app.locals.port = PORT;
app.use(morgan(':method :url :port'))
app.get('/app', function(req, res) {
    res.send("Hello world from server");
});

app1.listen(PORT);
zurgl
  • 1,930
  • 1
  • 14
  • 20
-1

You might be looking for process.env.PORT. This allows you to dynamically set the listening port using what are called "environment variables". The Node.js code would look like this:

const port = process.env.PORT || 3000; 
app.listen(port, () => {console.log(`Listening on port ${port}...`)}); 

You can even manually set the dynamic variable in the terminal using export PORT=5000, or whatever port you want.

Kal Heyn
  • 9
  • 2
-1

express v4+

const app = require("express")();
app.listen( 5555, function() {
  console.log( this.address().port )
})
  • Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Nov 13 '22 at 20:38
-2

The easier way is just to call app.get('url'), which gives you the protocol, sub domain, domain, and port.

Downhillski
  • 2,555
  • 2
  • 27
  • 39