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

Describe the bug

I updated from react-scripts@3.3.0 to react-scripts@3.4.1 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        | > core-ui@0.1.0 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 RS@3.4.1
  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

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 139
  • Comments: 45 (4 by maintainers)

Commits related to this issue

Most upvoted comments

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

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+.

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

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.

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?

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.

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.

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

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.

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.

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",

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?

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.

Adding stdin_open: true worked for me too.

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

@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.

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.

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 to the docker-compose file solved the issue for me

It’s working for me thanks!!

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.

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?

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

version: "3.8"

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

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).

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?

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.