Inconsistent localhost connection to Docker container running react app WSL2 Ubuntu

I’ve recently started to Dockerize a react app. I am able to easily build and run the app outside of a container without any issues.

I’ve built the following Dockerfile:

FROM node:latest

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

CMD [ "npm", "start" ]

I don’t have any problems building the image, and the container starts up without issue, but I can’t seem to access the container from my browser using localhost:8080.

In an effort to further troubleshoot the problem, I used this tutorial. I was able to create the express app, run it locally, the create the Dockerfile, create an image, run the container, and access at localhost:8080 without any issues, so the problem appears to be isolated to the project I’m trying to Dockerize.

What steps should I take to begin troubleshooting why I can’t access my project’s container from my browser?

Can you share the parts of the projects which makes you think it should work on that port? I see only an EXPOSE instruction which does nothing basically unless you have a services which relies on this metadata.


So in my react project’s package.json file is the following set of scripts:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config --env NODE_ENV=production --progress && copy package.json dist/package.json",
    "start": "webpack serve --hot --entry ./src/index.js --config ./"

In my Dockerfile I’m running the start command in the package.json file, which references the following file:

devServer: {
        headers: {
            'Content-Security-Policy': 'default-src \'self\' * style-src \'self\' connect-src \'self\' ws:// data: \'unsafe-inline\''
            // TODO: dynamically add the current tenant url to the CSP policy
            // TODO: remove the 'unsafe-inline' CSP policy
        hot: true,
        overlay: {
            warnings: true,
            errors: true
        transportMode: 'ws',
        //host: '',
        host: 'localhost',
        port: 8080,
        allowedHosts: [''],
        publicPath: 'auto',
        historyApiFallback: true,
        contentBase: path.resolve(__dirname, 'dist'),
        writeToDisk: true,

When I run the project without Docker using the npm run start command, the project starts up on localhost:8080 and I’m able to access it in the browser. When I build the image (docker image build -t client) and run a container using that image (docker container run --rm -p 8080:8080 client), when I try to go to localhost:8080, I get a browser message that “This page isn’t working right now” and the network tab says: “Failed to load response data: No resource with given identifier found”.

So I’m trying to understand why localhost:8080 works outside the context of a docker container, but doesn’t work when the project is being run inside a docker container.

That is the localhost of the container not the host. Replace it with:

host: ''


On second thought, I’m not sure what that parameter controls. If it is really the hostname like a virtual host, then will not help, but make sure the service is listening on all ip addresses of the container.

Okay, that appeared to resolve the issue. Apologies for my ignorance on this topic, but I was hoping you could elaborate a bit on your provided answer. Using causes the container to listen on all ip addresses. Is that a correct understanding? What are the ramifications of using such a setup in production?

Sorry, but we explained it so many times I sometimes just give the answer and let users to make the effort to find the answer to the “why” :slight_smile:

If you want to learn about Docker networks and ports, you can read my blog post:

Regarding you understood it correctly. The container has its own network, its own localhost. If the app listens on localhost in the container it won’t be available from outside.

Nothing. It is necessary. It is all ip addresses of the container, not the host. You can’t access it from other machines unless you forward a port from the host, which you did.

Thanks for the help, and the link. Cheers!