ctrlplusb / react-universally

A starter kit for universal react applications.
MIT License
1.7k stars 244 forks source link

[FAQ]: Deployment to Heroku #320

Open beckmeindia opened 7 years ago

beckmeindia commented 7 years ago

Hey, Could you please tell me the difference that needs during deployment to Heroku.

I am using the standard Node.js server with heroku git capability. I would love to use now, but I already have an existing setup with Heroku.

Please let me know how to build it and set NODE ENV etc. for deployment

Thanks

codepunkt commented 7 years ago

@beckmeindia Thanks for your issue. You seem to have some experience with Heroku, so it would be amazing if you could find out what needs to be changed to be able to deploy to it! :)

carsonxyz commented 7 years ago

I am currently using this stack in production, hosted on Heroku. The only thing I needed to make it work was adding the config var NPM_CONFIG_PRODUCTION to false on the heroku dashboard and add "postinstall": "npm run build", to package.json scripts.

ctrlplusb commented 7 years ago

Great candidate for FAQ!

kurtzilla commented 7 years ago

I am not having the luck that carsonperrotti had :(

Despite the warning posted during deploying to Heroku:

Building dependencies
remote:        Installing node modules (yarn)
remote:
remote:        Warning: when NODE_ENV=production, yarn will NOT install any devDependencies
remote:        (even if NPM_CONFIG_PRODUCTION is false)
remote:        https://yarnpkg.com/en/docs/cli/install#toc-yarn-install-production

I changed the NPM_CONFIG_PRODUCTION=false and moved cross-env to dependencies. Subsequently, I also removed the cross-env step from the build script. Now when I deploy to heroku, it still fails on the post-install build citing that the v8flags module cannot be found.

$ npm run build
remote:
remote:        > react-universally@12.0.0 build /tmp/build_e67f456082850a83ba496f51e9934a80
remote:        > NODE_ENV=production babel-node tools/scripts/build
remote:
remote:        module.js:471
remote:        throw err;
remote:        ^
remote:
remote:        Error: Cannot find module 'v8flags'
remote:        at Function.Module._resolveFilename (module.js:469:15)
remote:        at Function.Module._load (module.js:417:25)
remote:        at Module.require (module.js:497:17)
remote:        at require (internal/module.js:20:19)
remote:        at Object.<anonymous> (/app/.cache/yarn/npm-babel-cli-6.18.0-92117f341add9dead90f6fa7d0a97c0cc08ec186/lib/babel-node.js:3:18)
remote:        at Module._compile (module.js:570:32)
remote:        at Object.Module._extensions..js (module.js:579:10)
remote:        at Module.load (module.js:487:32)
remote:        at tryModuleLoad (module.js:446:12)
remote:        at Function.Module._load (module.js:438:3)
remote:
remote:        npm ERR! Linux 3.13.0-105-generic
...

I am a bit green on my knowledge of how this all works - but agree that a solution to this would be a great addition to the FAQ

carsonxyz commented 7 years ago

@kurtzilla I forgot to add that if you use Yarn, you'll have to create a new file in the root of your repo called .slugignore and it's contents should be yarn.lock. Heroku does not yet support Yarn. This makes it fall back to npm.

kurtzilla commented 7 years ago

@carsonperrotti - ok that got me to kick the can one step further down the road. Now it seems I need to configure the correct port. From Heroku logs...

Server listening on port 1337
2017-01-16T03:19:57.107070+00:00 app[web.1]: Error waiting for process to terminate: No child processes
2017-01-16T03:19:57.084865+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
beckmeindia commented 7 years ago

Great! I think the issue is resolved. Thanks everyone

carsonxyz commented 7 years ago

@kurtzilla Open the config, and change the environment variable SERVER_PORT to just PORT. Cheers!

ctrlplusb commented 7 years ago

Reopening this as an item to be added to FAQ.

ctrlplusb commented 7 years ago

Thanks for helping out here @carsonperrotti!

kurtzilla commented 7 years ago

@carsonperrotti Still no love - although I feel like I am pretty close. I have detailed my exact steps from start to finish here: https://gist.github.com/kurtzilla/d9393676c3c51ebdba947072d4ab4cd4

What am I missing?

carsonxyz commented 7 years ago

@kurtzilla Are you using a .env file? I would suggest not doing that and adding your environment variables to heroku config. They assign a PORT as an environment variable and if you set your own, it breaks. If you are still running into issues, feel free to post your heroku deploy log here after the npm install and I'll see what's going on.

kurtzilla commented 7 years ago

on a side note - I am able to deploy https://github.com/erikras/react-redux-universal-hot-example per instructions without issue

I am not using an .env file. The process I followed is exactly as outlined in the previous gist.

The full Heroku deploy log is here: https://gist.github.com/kurtzilla/64e9572bc3b6049b9c8b8a330baa114f

carsonxyz commented 7 years ago

I understand. How about the console after the deploy. I am assuming that you are seeing an issue of running into it not binding to a port.

Grab the output from here.

screen shot 2017-01-16 at 12 15 37 pm
kurtzilla commented 7 years ago

2017-01-16T17:27:54.678521+00:00 heroku[web.1]: State changed from crashed to starting 2017-01-16T17:28:00.420676+00:00 heroku[web.1]: Starting process with command npm start 2017-01-16T17:28:05.543954+00:00 app[web.1]: 2017-01-16T17:28:05.543978+00:00 app[web.1]: > react-universally@12.0.0 start /app 2017-01-16T17:28:05.543979+00:00 app[web.1]: > cross-env NODE_ENV=production node build/server 2017-01-16T17:28:05.543979+00:00 app[web.1]: 2017-01-16T17:28:08.624316+00:00 app[web.1]: Server listening on port 47810 2017-01-16T17:29:00.506378+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch 2017-01-16T17:29:00.506467+00:00 heroku[web.1]: Stopping process with SIGKILL 2017-01-16T17:29:00.674136+00:00 heroku[web.1]: Process exited with status 137 2017-01-16T17:29:00.688132+00:00 heroku[web.1]: State changed from starting to crashed

carsonxyz commented 7 years ago

Oh! In src/server/index.js find

const listener = app.listen(config.port, config.host, () =>
  console.log(`Server listening on port ${config.port}`),
);

and change it to

const listener = app.listen(config.port, () =>
  console.log(`Server listening on port ${config.port}`),
);

by removing config.host. That should do it.

@ctrlplusb Any idea why having config.host in that line would break the app on heroku?

kurtzilla commented 7 years ago

BAZINGA! Thank you so much for your attention

I have created a new gist with the necessary steps - hope it helps! https://gist.github.com/kurtzilla/c134c74142ce59d0bdf2d90db7321dcb

romanenko commented 7 years ago

As for now, 20 February 2017, if heroku sees yarn.lock file — yarn is used automatically. So, no need for .slugignore with yarn.lock. And "postinstall": "yarn run build" will do.

Thanks for the great gist, @kurtzilla. I've made my micro-fork: https://gist.github.com/romanenko/d2f9bc895ead9870f666fe7e9a67b47e

romanenko commented 7 years ago

Is there a reason why we are using SERVER_PORT instead of just PORT? I guess, PORT is more common-used default, and by using it we could eliminate the need of any FAQ's at all.

oyeanuj commented 6 years ago

@carsonperrotti @kurtzilla @romanenko So, to deploy to Heroku, did you only need to have a postbuild script?

If someone can confirm their Heroku setup with v13, I'd be happy to attempt a PR for the FAQs.