I'm deploying the create-react-app using docker on AWS ECS. I'm testing using dockerhub image that's pretty much the stock version of create-react-app. When launch the task, it's able to pull the container image, launch the docker container, however it hangs on running react-scripts start. All I can see in the container logs are:
01:51:38 npm info it worked if it ends with ok
01:51:38 npm info using npm#2.15.11
01:51:38 npm info using node#v4.7.3
01:51:42 npm info prestart test-react#0.1.0
01:51:42 npm info start test-react#0.1.0
01:51:42 > test-react#0.1.0 start /usr/src/app
01:51:42 > react-scripts start
01:52:06 Starting the development server...
It just hangs there and never finishes. However, when I manually run the docker container, everything works fine:
Starting the development server...
Compiled successfully!
The app is running at:
http://localhost:3000/
My Dockerfile is:
FROM node:4-onbuild
# Prepare app directory
RUN mkdir -p /usr/src/app
ADD . /usr/src/app
# Install dependencies
WORKDIR /usr/src/app
RUN npm install
# Build the app
RUN npm build
# Expose the app port
EXPOSE 3000
# Start the app
CMD npm start --loglevel debug
My package.json:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Looking for advice on how to debug or if there's additional logging I can do, thanks!
I figured it out - when I created defined the container in the ECS task, I didn't allocate enough memory to the docker container so when it was starting the server it ran out of memory and froze up. I changed the settings to allocate more memory to the docker container and now everything works.
Related
I'm trying to deploy a React app as part of a docker compose. It works fine if I deploy on port 3000, but when I use port 80, I cannot connect. If I run npm start manually, either config works fine, but I cannot access the port 80 version when running as a docker image.
I've tried adding EXPOSE 80 to the dockerfile, but it did not seem to have any effect. Can someone point out the error in my config?
Dockerfile:
FROM node:17-alpine
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install
RUN npm install react-scripts#5.0.0 -g
COPY . .
CMD ["npm", "start"]
docker-compose.yaml
version: "3.8"
services:
solvle:
build: ./
container_name: solvle_c
ports:
- '8081:8081'
solvle_front:
build: ./solvle-front
container_name: solvle_front_c
ports:
- '80:80'
stdin_open: true
tty: true
package.json fragment
"scripts": {
"start": "set PORT=80 && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
For linux you should set port in this way:
"start": "export PORT=80 && react-scripts start"
Another solution is create a file with name .env (documentation) in the main directory and set PORT variable to desired port number:
PORT=80
One more solution.
You could use cross-env to set the port:
npm install cross-env -D
and then modify start script package.json:
"start": "cross-env PORT=80 react-scripts start",
p.s.
But for deploy react app with docker I woud recomend you to use nginx.
p.p.s.
The EXPOSE instruction in dockerfile does not actually publish the port. It functions as a type of documentation. expose documentation
Working on an Electron app with React. Right now, to get things started, I run the typical npm start command which runs the react-scripts start script.
This starts the dev server. Once the dev server is started, I open a second terminal window and run a script to start electron npm run start-electron which opens my React app in the Electron window.
This works as expected, but I was curious if there was a way to create a script that would:
Start the dev server
Wait for dev server to be started
Then start electron
I tried setting up a sequential script in package.json but it only starts up the dev server. For example npm run start && npm run start-electron.
This isn't make or break. The two terminal option works fine, just didn't know if this was possible.
Yes it is possible, I use concurrently to do it within my projects
npm i concurrently
and add a new script, let's call it dev for example, then in your scripts:
"dev": "concurrently \"npm run start\" \"npm run start-electron\""
All that remains to do now is npm run dev
I have the exact same situation, and below script work for me (remember to install wait-on)
"scripts": {
"start-reactjs": "PORT=25610 react-scripts start",
"start-electron": "wait-on http://localhost:25610 && electron .",
"start": "npm run start-electron & npm run start-reactjs"
}
you can create a script in the root directory with extension .sh
it could contain all operations for you
npm start
npm run start-electron
The second approach you could create a custom script in package.json
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"customStart":"npm run start && npm run start-electron"
},
to run this script
npm run customStart
You could try start-server-and-test npm module. It has different purpose, but it could work for your scenario.
From documentation:
This command is meant to be used with NPM script commands. If you have
a "start server", and "test" script names for example, you can start
the server, wait for a url to respond, then run tests. When the test
process exits, the server is shut down.
"scripts": {
"start-server": "npm start",
"test": "mocha e2e-spec.js",
"ci": "start-server-and-test start-server http://localhost:8080 test"
}
}
To execute all tests simply run npm run ci.
Another alternative could be concurrently combined with wait-on as #Slim said
From documentation:
wait-on will wait for period of time for a file to stop growing before
triggering availability which is good for monitoring files that are
being built. Likewise wait-on will wait for period of time for other
resources to remain available before triggering success.
I solved it by using concurrently
npm i concurrently
In my package.json
"build": "concurrently \"npm run build-react\" && npm run build-jsx",
I'm using it to build an Adobe extension using react, and I need to bundle my extendscript after the react-scripts build, which would otherwise delete my .jsxbin
npm run build creates production build of the project. How do I create development build? I'm using gradle-node-plugin to build the artifact. The project has standard create-react-app configuration.
This is not really doable with just create-react-app, there is an open issue Here and it doesn't look like it will be added anytime soon.
However, you can use a package called dotenv for that, following are the steps you should take:
Install dotenv (make sure to add save dev) npm install dotenv-cli --save-dev
In package.json scripts section add new script: "build:dev": "dotenv -e .env.development react-scripts build",
And you can build for development with npm run build:dev
PS: if you want to avoid mistakenly deploying dev builds to production (as mentioned here) you can add build:prod to package.json and disable the regular build command, see code:
"build:dev": "dotenv -e .env.development react-scripts build",
"build:prod": "dotenv -e .env.production react-scripts build",
"build": "echo \"Please use build:dev or build:prod \" && exit 1",
Also note that process.env.NODE_ENV will still be production but it'll load your .env.development file
Thanks, #Moses. This is an extension to the answer posted by Moses Schwartz. You can also make the build pick the environment files dynamically by exporting the value of the environment(development, test, production) in the bash shell. And then you don't have to have different build commands for different environments.
You can use this in your package.json
"start": "dotenv -e .env react-scripts start",
"build": "dotenv -e .env.${REACT_APP_ENVIRONMENT} react-scripts build",
So when your run npm start, it will pick the environment values from .env
and when you run npm run build, it will pick the environment values from .env.{REACT_APP_ENVIRONMENT}
To define the REACT_APP_ENVIRONMENT, you can do:
export REACT_APP_ENVIRONMENT="development" or
export REACT_APP_ENVIRONMENT="test" or
export REACT_APP_ENVIRONMENT="production"
Hope this helps. This will help in staging the react application for multiple environments.
Thanks to #Tx_monster comment
github.com/Nargonath/cra-build-watch
A script for create-react-app that writes development builds to the disk
npm install -D cra-build-watch
package.json:
{
"scripts": {
"watch": "cra-build-watch"
}
}
npm run watch
I have a create-react-app bootstrapped project i want to deploy on an instance. Right now there are two ways that I have tried to set up the deployment which only ends up setting the port and not the host.
My project architecture is as below
Project
- Frontend
- Backend
My main issue is that although I am able to set the port on create-react-app build I cannot set the hostname to 0.0.0.0 instead of localhost.
In create-react app i hardcoded HOST=0.0.0.0 and PORT=443 in the start script.
Other thing i tried is have a script the serves the pages on port 443. Build serves on port 443 but not on 0.0.0.0.
Create-react-app scripts
"scripts": {
"start": "HOST=0.0.0.0 PORT=443 react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
Basic script at the root of the project
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"client": "cd frontend && npm start",
"client-prod": "cd frontend/build && npm install -g serve && serve -s build -l 443",
"server": "cd backend && npm start",
"sass": "node-sass -w frontend/source/styles/ -o frontend/source/styles/ --recursive",
"dev": "concurrently \"npm run server\" \"npm run client\" ",
"prod": "concurrently \"npm run server\" \"npm run client-prod\" "
},
The development on localhost works fine but i need to able to serve my build pages on 0.0.0.0:443 instead of localhost
env file instead in the root of your project and set HOST=0.0.0.0 and if you also want to disable the automatic browser opening when you type yarn or npm start, you can also set BROWSER=none. Check this link for more info https://create-react-app.dev/docs/advanced-configuration/
As per the advanced configuration page for React, the HOST environment variable does not apply when you deploy (in the table, see column Production, it says Ignored).
This means that HOST is not the way to set up your deployment. HOST is only functional when doing npm start in your development PC.
When you do npm run build, you get a /build folder with all the contents of the compiled application, and you get NO HTTP server. The HTTP server for deployment you select, configure and deploy on your own. See the deployment page to understand this fully.
So, in short: HOST is only for local development & testing. In deployment, you set up your NGINX, Apache or any other server in the way that server is configured.
More or less only applicable to beginners...
First time deployment of application on Heroku and received the following errors after using the standard Heroku Deploy instructions in the Heroku Dashboard:
2017-05-10T21:43:59.732215+00:00 heroku[web.1]: Process running mem=543M(106.1%)
2017-05-10T21:43:59.732277+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
Heroku Deploy Instructions:
$ git add .
$ git commit -am "make it better"
$ git push heroku master
Turns out that I was deploying the application as it is in the dev environment, which WOULD cause a significantly larger memory use. My thinking is that it would be running the entire dev environment on Heroku...
Instead, you need to build the application and deploy that (static) version of the application. This is done using the following!
Create-React-App Deployment
And adding this buildpack to the Heroku. Instructions on site:
create-react-app buildpack
I have no idea how this actually works.
I had the same issue. I figured out the app on Heroku was running in the development environment.
Fixed it by:
Installing the serve package (Run npm install serve -g)
Changing the start script to "start": "serve -s build"
You also need to add the script to use for dev environment, just a normal tract script start ("dev": "react-scripts start")
So, my scripts look like this:
...
"start": "serve -s build",
"dev": "react-scripts start",
"build": "react-scripts build"
...
In my case I'm using Express and React in the same application, so I have to build react and then start the express server. I was not aware that heroku runs the build script before running the start script, so I initially put my build script in my start script which caused the out of memory issue.
The problem:
"start": "npm run build && npm run start:server"