Create-react-app: [React-Scripts] v3.4.1 fails to start in Docker

Created on 21 Mar 2020  Â·  45Comments  Â·  Source: facebook/create-react-app

Describe the bug

I updated from [email protected] to [email protected] and when I attempted to restart my Docker container using the new version it exited with code 0.

Recreating core-ui_web_1 ... done
Attaching to core-ui_web_1
web_1        |
web_1        | > [email protected] start /app
web_1        | > react-app-rewired start
web_1        |
web_1        | ℹ 「wds」: Project is running at http://172.24.0.6/
web_1        | ℹ 「wds」: webpack output is served from
web_1        | ℹ 「wds」: Content not from webpack is served from /app/public
web_1        | ℹ 「wds」: 404s will fallback to /
web_1        | Starting the development server...
web_1        |
core-ui_web_1 exited with code 0

This is all the logs had, but running docker-compose ps showed an exit code of 0. I tried running with/without react-app-rewired to rule that out as an issue, but the only thing that solved the issue was downgrading to ~3.3.0 again.

One weirdness I see that is different from 3.3.0 and 3.4.1 is the webpack output is served from line is blank in 3.4.1 but says / in 3.3.0.

Did you try recovering your dependencies?

I ran a fresh Docker rebuild with no cache using node:erbium as the base image to ensure there was no corruption. No luck.

Which terms did you search for in User Guide?

Docker, exit code 0.

Environment

Ran in my docker container to ensure the output is accurate.

➜  dc run web npx create-react-app --info
npx: installed 99 in 7.075s

Environment Info:

  current version of create-react-app: 3.4.1
  running from /root/.npm/_npx/6/lib/node_modules/create-react-app

  System:
    OS: Linux 4.9 Debian GNU/Linux 9 (stretch) 9 (stretch)
    CPU: (4) x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
  Binaries:
    Node: 12.13.1 - /usr/local/bin/node
    Yarn: 1.19.1 - /usr/local/bin/yarn
    npm: 6.12.1 - /usr/local/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: Not Found
  npmPackages:
    react: ^16.12.0 => 16.12.0
    react-dom: ^16.12.0 => 16.12.0
    react-scripts: ^3.4.1 => 3.4.1
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

  1. Install CRA with [email protected]
  2. Run in docker container
  3. Exits with code 0

Expected behavior

I expected the server to start.

Actual behavior

The server exited with status code 0 and no output after Starting the development server...

Reproducible demo

All CRA settings are left as their default. No CLI flags or env vars other than NODE_ENV=development.

Here's my Dockerfile:

# create base image with all packages, proper entrypoint, and directories created
FROM node:erbium AS base

# install any packages we need from apt here
RUN apt-get update \
    && apt-get install dumb-init

# set entrypoint to `dumb-init` as it handles being pid 1 and forwarding signals
# so that you dont need to bake that logic into your node app
ENTRYPOINT ["dumb-init", "--"]

# all of our code will live in `/app`
WORKDIR /app

# using the base image, create an image containing all of our files
# and dependencies installed, devDeps and test directory included
FROM base AS dependencies

COPY package*.json ./
RUN npm set progress=false \
    && npm config set depth 0 \
    && npm i
COPY ./config-overrides.js ./
COPY ./public ./public
COPY ./src ./src

# if you have any build scripts to run, like for the `templated-site` flavor
# uncomment and possibly modify the following RUN command:
# RUN npm run build
# keeping all of the bash commands you can within a single RUN is generally important,
# but for this case it's likely that we want to use the cache from the prune which will
# change infrequently.

# test running image using all of the files and devDeps
FROM dependencies AS test
USER node
ENV NODE_ENV=test
# use `sh -c` so we can chain test commands using `&&`
CMD ["npm", "test"]

FROM dependencies AS development

# expose port 3000 from in the container to the outside world
# this is the default port defined in server/manifest.js, and
# will need to be updated if you change the default port
EXPOSE 3000
CMD ["npm", "start"]

# release ready image, devDeps are pruned and tests removed for size control
FROM development AS release

RUN npm prune --production \
    rm -rf lib/**/*.spec.js

bug report needs investigation needs triage

Most helpful comment

Adding stdin_open: true to the docker-compose file solved the issue for me

All 45 comments

Update: using customize-cra i forced the publicPath to be set to / which fixed nothing being shown in the output, but i still get exit code 0.

Ah, https://github.com/facebook/create-react-app/commit/7e6d6cd05f3054723c8b015c813e13761659759e is the cause. When I set CI=true in my docker setup the container starts without issue. I believe that this should not cause the process to exit because it likely breaks running CRA in docker for many people in v3.4.0+.

For anyone else that stumbles on this, instead of using docker-compose up to start your CRA service with ^3.4.0, use docker-compose run which will attach your TTY to the container and prevent the breakage.

It is impossible to run in the background now without the CI flag enabled.

Same here with docker run.
Downgrading react-scripts to 3.3.0 was not a valid solution because of this other issue https://github.com/facebook/create-react-app/issues/8499
Downgrading react-scripts to 3.4.0 works.

Adding stdin_open: true to the docker-compose file solved the issue for me

Adding stdin_open: true or tty: true to the docker-compose file works.

stdin_open stands for interactive and tty means terminal. If you do a quick google search you find this:
Screen Shot 2020-03-24 at 11 22 29

7e6d6cd clearly indicates a check for interactivity.

docker run by default allocates tty. So that's why that works.
https://docs.docker.com/compose/reference/run/

Docker's documentation says: "For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process."

https://docs.docker.com/engine/reference/run/#foreground

The dev environment can be started, but the production environment is blank on browser

I am a user of CircleCI, I use a cypress orb to run my e2e tests
CI=true yarn start is not enough, the server is closed

CircleCI received exit code 0

Rollbacking to 3.4.0 make it works (I was using the 3.3.1 version before and it worked)

In my case I do not have much control over the docker being runned

This is (I think) the cause: https://github.com/facebook/create-react-app/pull/7203

Judging by this and that docker containers by default are not interactive, that is why this is currently broken and setting tty: true fixes that.

I see lot of workarounds here. It's very unfortunate that step up from 3.4.0 to 3.4.1 (very minor improvement... yeap) causes that many of developers looses hours for additional reasearch to find out what stopped working - exit code 0...
Sure, adding the stdin_open: true helped but is it somewhere in documentation or some notification in logs?

Adding stdin_open: true to the docker-compose file solved the issue for me

It's working for me thanks!!

upgrading to 3.4.1 with the change made from #7203 is also causing my circle ci puppeteer pipelines to break by closing the process. will start looking for workarounds.

Issue also affects kubernetes deployments based off of using the npm start command inside a docker image. an exit 0 is returned causing the pod to enter crashloopback.
adding the CI=true to the .env file fixes the issue. downgrading to 3.4.0 also resolves this behavior.

Adding stdin_open: true worked for me.

@rozacek this actually is in the release notes here: https://github.com/facebook/create-react-app/releases

7203 Closes webpack dev server and exits process on "end" stdin (@kelseyleftwich)

I agree that 3.4.1 has caused quite a bit of chaos for a minor version bump. It also updates to babel 7.9 which is significant as it adds new syntax to typescript for re-exports.

Adding stdin_open: true worked for me too.

I can't use stdin_open: true as i'm not using docker-compose,

I'm trying to run cypress tests in Circle CI and CI=true makes no difference either.

I think I might be echoing some of the other users. If this is just for a single Docker container, that's run with Dockerfile, is there a way to set this option? Is the preferred way to migrate to docker-compose?

Adding stdin_open: true worked for me.

@rozacek this actually is in the release notes here: https://github.com/facebook/create-react-app/releases

7203 Closes webpack dev server and exits process on "end" stdin (@kelseyleftwich)

I agree that 3.4.1 has caused quite a bit of chaos for a minor version bump. It also updates to babel 7.9 which is significant as it adds new syntax to typescript for re-exports.

I added it and then the hot reload stopped working, did you have that issue too?

As others have mentioned I can't get Cypress to start the dev server in CircleCI (which runs in a docker container without tty) with 3.4.1. The output of the test is a little different than the OP, In fact, it returns exit code 1; but I think it's the same issue. While we add CI=true in our script below, CircleCI already sets it by default:

> CI=true BROWSER=none PORT=60009 react-scripts start

ℹ 「wds」: Project is running at http://192.168.80.3/
ℹ 「wds」: webpack output is served from 
ℹ 「wds」: Content not from webpack is served from /root/repo/public
ℹ 「wds」: 404s will fallback to /
Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.

Starting the development server...

Error: server closed unexpectedly
    at ChildProcess.onClose (/root/repo/node_modules/start-server-and-test/src/index.js:65:14)
    at ChildProcess.emit (events.js:311:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
error Command failed with exit code 1.

If I ssh into the machine in CircleCI and then start the Cypress tests they run without issue. In this case there _is_ a tty because I'm connected via SSH.

Downgrading react-scripts to 3.4.0 works but that has security vulnerabilities in its dependencies (acorn, minimist).

This is a case where i very much wish i could do a sub-thread, but @varjmes and @oconnelc you can typically run a docker container with the option -it specified to achieve the desired results (see the documentation for docker run for more).

So for example if I've built a docker image tagged tic-tac-toe:latest with:

$ docker build -t tic-tac-toe:latest .

then I can run it with

$ docker run -p 3000:3000 -it --rm tic-tac-toe:latest

Note your use case may not enable that, I just came across this thread as I was working through the React tutorial and could not for the life of me containerize it. Also, just as a disclaimer, this does not actually solve the root problem.

I can't use stdin_open: true as i'm not using docker-compose,

I'm trying to run cypress tests in Circle CI and CI=true makes no difference either.

-t
https://docs.docker.com/engine/reference/run/#foreground

@linkerx I haven't found any way to configure CircleCI to run Docker with a tty. Do you have any insights?

I would think that most CI and production environment do not have a tty. It seems like this is a workaround. There's no reason that CRA _should_ require a tty.

Looking at 7e6d6cd as suggested above, it should be working for us; we configure CI=true just before we start the server, but we still have the problem (in CircleCI; I can't reproduce it locally):

  "scripts": {
    "start:ci": "CI=true BROWSER=none PORT=60009 react-scripts start",

Given all of these issues above, doesn't it seem that the isInteractive check in 7e6d6cd is incorrectly identifying a non-interactive docker container as being interactive? I think the problem is that line 52 checks if _stdout_ is a TTY which is not the same as _stdin_.

52 const isInteractive = process.stdout.isTTY;
...
168    if (isInteractive || process.env.CI !== 'true') {

It's very possible that stdout is a TTY but that there is no stdin connected.

Shouldn't this rather be:

168    if (process.stdin.isTTY || process.env.CI !== 'true') {

I created a branch with that change but I could use some help in how to test this. Given that CRA is a monorepo, I don't know that I can specify a subfolder of a git repository in package.json.

I was able to patch react-scripts in the codebase before running tests in CircleCI and that change didn't resolve it. In fact, when CircleCI runs I found the following:

  • isInteractive is true
  • process.env.CI !== 'true' is false
  • process.stdin.isTTY is true

However, if I hack react-scripts to remove the whole patch, then it completes the process without prematurely terminating the dev server. If anyone else wants to test this, I ran this in our CI suite just before running Cypress:

sed -i '/process.env.CI/,+7 d' node_modules/react-scripts/scripts/start.js

The more I think about this code change the more confused I become. The original goal of #7203 was to close the development server when stdin closed because otherwise it was left hanging open. But it seems that now it's closing prematurely in cases where it's used in docker.

According to the comment thread this hook crashed CI (which was fixed by checking if stdout was a TTY) and was still not working in Phoenix development watcher (which was fixed by checking that the CI variable is not set).

@ianschmitz Can you confirm that I understand your thinking there? Would your CI and other use cases work if we dropped the isInteractive part of the check? I've verified that removing that makes this work in CircleCI for us.

For anyone else, here's my hack to the code in CI to verify that change.

sed -i '/process.env.CI/ s/isInteractive [|]*//' node_modules/react-scripts/scripts/start.js

I've updated my branch to reflect that. Again, I'm still not sure how to integrate that into a project from a test perspective due to the monorepo nature.

Just to confirm my tests

  • Downgrading react-script to 3.4.0 (Work)
  • docker run with interaction mode. Ex, docker run -it .... (Work)

facing the same issue with setting up a mono repo with lerna

@codationio/acc-front: $ react-scripts start
@codationio/acc-front: ℹ 「wds」: Project is running at http://172.27.1.118/
@codationio/acc-front: ℹ 「wds」: webpack output is served from 
@codationio/acc-front: ℹ 「wds」: Content not from webpack is served from /home/rishabh/projects/monorepo/packages/acc-front/public
@codationio/acc-front: ℹ 「wds」: 404s will fallback to /
@codationio/acc-front: Starting the development server...
@codationio/acc-front: Done in 1.36s.

I was able to work around it by using CI=true for now, Any fix coming up in future?

Download speed of the JS chunks are extremely slow on a development docker environment, anyone having the same issue?

Adding stdin_open: true to the docker-compose file solved the issue for me

Adding stdin_open: true to the docker-compose file solved the issue for me

Thank you, you saved my day but please can you explain to me what stdin_open: true means , and what is the issur with this version of react-scripts ??

hey everyone, this issue is still happening running a react-script server on a circle ci VM:

I added the following before my cypress e2e command:

- run: sed -i '/process.env.CI/,+7 d' node_modules/react-scripts/scripts/start.js

ending up effectively with

- run: sed -i '/process.env.CI/,+7 d' node_modules/react-scripts/scripts/start.js
- run: yarn e2e

if cypress doesn't run, point it to localhost:3000 in the package.json

"baseUrl": "http://localhost:3000"

and to run it

"e2e:run": "cypress run --browser chrome",
"e2e": "start-server-and-test start http://localhost:3000 e2e:run",

Adding stdin_open: true to the docker-compose file solved the issue for me

Where does this go?

@nettelandways
in part where you running your cra image, for example:

version: "3.8"

frontend:
    stdin_open: true
    build:
      context: ./app/frontend

I currently have this docker-compose.yml

version: "3.8"

services:
  client:
    build: ./client
    volumes:
      - /app/node_modules
      - ./client/src:/app/src
    ports:
      - 3000:3000
    stdin_open: true
    tty: true
  backend:
    build: ./backend
    env_file: ./.env/backend
    ports:
      - 5000:5000
      - 5001:5001

And the error is still present.
I'm only spinning up client

I belive tty option is not required in order to make it work, anyway are you sure your container is not starting beacuse of this?

I belive tty option is not required in order to make it work, anyway are you sure your container is not starting beacuse of this?

As stated before, either stdin_open: true or tty: true are required in order to make [email protected] working under docker using docker-compose. And I confirm that this, indeed, fixed the issue for me too.

Adding stdin_open: true or tty: true to the docker-compose file works.

stdin_open stands for interactive and tty means terminal. If you do a quick google search you find this:
Screen Shot 2020-03-24 at 11 22 29

7e6d6cd clearly indicates a check for interactivity.

docker run by default allocates tty. So that's why that works.
https://docs.docker.com/compose/reference/run/

Docker's documentation says: "For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process."

https://docs.docker.com/engine/reference/run/#foreground

Yes, and that's what I meant, since @nettelandways had stdin_open: true option then tty: true isn't required.

This has stumped me for hours. Docker is huge - please document this somewhere. - a section here would be lovely - https://create-react-app.dev/docs/getting-started

I am still getting the same issue as highlighted by "nettelandways" 5 days ago.

same works fine if i use docker run -it -p....... command. Server comes up.

Please suggest what to change.

Configuring docker or docker-compose to run interactively is not a solution, it's a workaround and not how I understand docker containers are intended to be run. Introducing this to your Dockerfile or docker-compose.yml will introduce unnecessary changes and may have unforeseen consequences. The issue is in react-scripts and your best bet is to stay on 3.4.0 until 3.4.2 is released where this will hopefully be fixed. A minor tweak, which was accepted in #8845, should resolve this.

For me, deleting all images and containers (used and <none>) and removing node_modules (all of this about 3 times) made it work

Hello you should add those lines and it will work fine stdin_open: true tty: true

Based on this merged code, It turns out that we have these 3 options:

  • Add stdin_open: true on your docker-compose command
  • Add an CI=true as an environment variable
  • Downgrade your react-scripts to 3.4.0

Just remember that if you choose to downgrade your react-script version, you should verify if there's any dependency conflict because of that and you will lose any bugfix on that minor version bump

@pekosoG This should be resolved in master by #8845 without any of those workarounds. Are you able to verify that? That's been merged but not released yet and I don't know how to select one package from a monorepo like this directly from GitHub.

@pekosoG I cherry-picked #8845 and the process still exited with a 0.

Guys,
I had the same issue
client_1 | ℹ 「wds」: Project is running at http://172.28.0.3/
client_1 | ℹ 「wds」: webpack output is served from
client_1 | ℹ 「wds」: Content not from webpack is served from /usr/app/front/public
client_1 | ℹ 「wds」: 404s will fallback to /
client_1 | Starting the development server...
And adding to docker-compose.yml for frontend stdin_open: true helped me to solve it. Thanks!

I am using a fork of react-scripts so cannot downgrade. I cherry picked #8845 and the process still exited with a 0. Also removed that entire section that was added in 3.4.1 and still exiting with a 0.

if (isInteractive || process.env.CI !== 'true') {
  // Gracefully exit when stdin ends
  process.stdin.on('end', function() {
    devServer.close();
    process.exit();
  });
  process.stdin.resume();
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

onelson picture onelson  Â·  3Comments

stopachka picture stopachka  Â·  3Comments

dualcnhq picture dualcnhq  Â·  3Comments

barcher picture barcher  Â·  3Comments

fson picture fson  Â·  3Comments