3

I have a React app which is based on Facebook's create-react-app. During development I run it on a specific local port (60001). To achieve this I changed the default start script in the scripts part of my package.json to the following:

    "start": "set PORT=60001 && react-scripts start",

I now have a requirement to run this in a Docker container using the same port. In my Dockerfile I have these two stages:

FROM node:alpine as build
COPY ./package.json /app/package.json
WORKDIR /app
RUN npm install
RUN rm -f .npmrc

FROM build as build-dev
COPY ./public/ /app/public
COPY ./src/ /app/src
EXPOSE 60001
CMD ["npm", "start"]

Notice I'm exposing the port on the container that I expect the npm dev server to bind to.

I build the image as you'd expect, targeting the build-dev Docker stage above.

docker build --target build-dev -t my-app:local

I then run the container like this:

docker run -it -p 60001:60001 my-app:local

The intention is to bind my local port 60001 to the same port on the container when I expect my dev app build to be running.

When I do this I see confirmation that npm is running the correct script and that the app has compiled. However, browsing to http://localhost:60001/ gives me nothing. Just an ERR_CONNECTION_REFUSED, as if there's nothing there.

I can't see what I'm doing wrong here. Any ideas? I'd hoped I might be able to get some insight from the container logs, but when I run docker logs for this container I just see the react scripts output confirming my app compiled.

Tom Troughton
  • 3,941
  • 2
  • 37
  • 77

2 Answers2

4

If you are using docker-compose adding this one line solved the problem for me...

The line is stdin_open: true.

Here is a basic example of my docker-compose.yml:

version: "3.7"

services:
  test-app:
    stdin_open: true
    container_name: test-app
    build: .
    ports:
      - "3000:3000"
    volumes:
      - /app/node_modules
      - .:/app

Example Dockerfile for reference:

FROM node:alpine

WORKDIR /app

COPY package.json yarn.lock ./

RUN yarn install

COPY . .

EXPOSE 3000

CMD ["yarn", "start"]

For more information on this I would checkout the github issue for create-react-app

GitHub Issue


Good luck! This drove me nuts for hours

PS Not sure how this will hold up in a production build

Eli Johnson
  • 1,492
  • 1
  • 10
  • 10
0

Seems like the app bind with container localhost.

Try to debug

docker exec -it <container_id> ash
#then
curl localhost:60001

It should work on localhost.

To make it accessible from outside of container do the following.

# i think its window syantax
"start": "set PORT=60001 HOST=0.0.0.0 react-scripts start",

or

"start": "PORT=60001 HOST=0.0.0.0 react-scripts start",

HOST:

By default, the development web server binds to all hostnames on the device (localhost, LAN network address, etc.). You may use this variable to specify a different host.

advanced-configuration HOST option react-app

Adiii
  • 54,482
  • 7
  • 145
  • 148
  • Thanks for the answer. Unfortunately I get `ash: curl: not found`. I did still try your suggestion `"start": "set PORT=60001 HOST=0.0.0.0 react-scripts start",` which crashed the container, but also `"start": "set PORT=60001 HOST=0.0.0.0 && react-scripts start",` which claimed to be running the dev server but still no site on localhost. I also tried adding `ENV HOST=0.0.0.0` to my Dockerfile before the `EXPOSE` line and using the original `start` script, but still same problem. – Tom Troughton Oct 17 '19 at 07:48
  • Apk add - - no-cache curl amd try – Adiii Oct 17 '19 at 08:05
  • Also it would be great if provid link to github repo so I can try – Adiii Oct 17 '19 at 08:20
  • Cheers, will try when I get a chance. Unfortunately currently on a private repo. If I get a chance I'll try to get a demo up somewhere... – Tom Troughton Oct 17 '19 at 08:23