rflw
rflw

Reputation: 1785

ng serve not working in Docker container but express.js does

I've read similar question ng serve not working in Docker container but I don't understand why do I have to specify a host 0.0.0.0 to run ng serve. For comparison, I ran a simple script with express.js in the same container on the same port and in this case the website was served at localhost:8080 without defining 0.0.0.0 host.

As I understand both servers (ng serve and express.js) are working the same way. Both runs inside container but only express can be accessed in browser and I'm confused why ng serve isn't.

Steps to reproduce:

  1. Run LTS Node.js container with name angular-test from CLI and publish port 8080:4200
    docker container run --name angular-test -it -v ${PWD}:/app/ -p 8080:4200 node:lts /bin/bash
  2. connect to container's terminal docker container attach angular-test
  3. go to angular project and run ng serve
  4. go to browser localhost:8080 but returns "The connection was reset The connection to the server was reset while the page was loading. ...`
  5. stop ng serve
  6. run node test-express to start express.js server on the same port 4200
  7. go to browser localhost:8080 and website is loaded without any issue, text Express.js works! is visible
const express = require('express')
const app = express()
const port = 4200

app.get('/', (req, res) => {
  res.send('Express.js works!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

It probably doesn't matter but I'm using Docker for Windows with WSL2 (Windows 10 Pro).

Upvotes: 1

Views: 834

Answers (1)

rflw
rflw

Reputation: 1785

Express.js utilizes the NodeJs`s method
server.listen([port[, host[, backlog]]][, callback]) see documentation

If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.

If host isn't specified, Node.js sets unspecified IP address :: or 0.0.0.0 as default. If you want to know what host is being defaulted, call server.address() inside app.listen() where server is an object returned by http.Server which extends net.Server.

const port = 4200;
const server = app.listen(port, () => {
  console.log('App listening at', server.address())
})

server.address() should return an object, which in my case is

{ address: '::', family: 'IPv6', port: 4200 }

It is now clear that express.js is listening on ::, not localhost as I expected.

Upvotes: 2

Related Questions