Table of Contents

About

App hosting on Heroku with dynos

where:

  • An application is a collection of source code written in one language.
  • A dyno is a lightweight Linux container that runs a single user-specified command. It has the same concept than a single process on a local computer. You increase the number of dynos when you need to scale up your concurrency.

Other hosting Provider:

Deployment Steps

Install the Heroku client

  • Install the Heroku client

Get the git code

  • Get a git project
  • Go to the git root

Create and/or associate an existing Heorku app

  • If you don't have an heroku app to host your application, you need to create one. See create
  • Otherwise you need to Associate the Heroku app with your code repository by creating a remote to your git local repository. See associate

Create

Create an heroku app (Heroku will generates a random name for your app if not passed)

heroku create [name]
Creating app... done, polar-everglades-86549
https://polar-everglades-86549.herokuapp.com/ | https://git.heroku.com/polar-everglades-86549.git
# The random name is polar-everglades-86549

Heroku Random App

  • When you create an app, a git remote (called heroku) is also created and associated with your local git repository.
git remote -v
heroku  https://git.heroku.com/polar-everglades-86549.git (fetch)
heroku  https://git.heroku.com/polar-everglades-86549.git (push)
origin  https://github.com/yourname/yourproject.git (fetch)
origin  https://github.com/yourname/yourproject.git (push)

Associate

Associate the Heroku app with the repository by creating a git remote

heroku git:remote -a <your-app-name> 

Language recognition

Heroku recognizes an app as:

  • Node.js by the existence of a package.json file in the root directory.

Declare the process (Main, background) in a procfile

Procfile is a process configuration file located in the root directory of your application that to explicitly declare what command should be executed to start your app.

Example:

web: node index.js

where:

  • web is the process type.
    • web declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic
    • worker: for a background worker process that processes items off of a queue.
    • … See process Model
  • node index.js is the start command for a node environment

Declare the build pack

The build pack is the build of your application. There is one by technology.

heroku buildpacks:set heroku/nodejs
# or
heroku buildpacks:set https://github.com/mars/create-react-app-buildpack.git
heroku buildpacks:set https://github.com/heroku/heroku-buildpack-go.git
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-nodejs

Environment variable

If NODE_ENV is set to production, the dev_dependencies of npm are not taken into account. It doesn't work with react for instance.

heroku config:set NODE_ENV=development

Push and build the code

Push your code. A server hook will build it.

git push heroku master
Counting objects: 461, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (354/354), done.
Writing objects: 100% (461/461), 226.37 KiB | 0 bytes/s, done.
Total 461 (delta 73), reused 461 (delta 73)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
remote:
remote: -----> Creating runtime environment
remote:
remote:        NPM_CONFIG_LOGLEVEL=error
remote:        NPM_CONFIG_PRODUCTION=true
remote:        NODE_VERBOSE=false
remote:        NODE_ENV=production
remote:        NODE_MODULES_CACHE=true
remote:
remote: -----> Installing binaries
remote:        engines.node (package.json):  6.10.2
remote:        engines.npm (package.json):   unspecified (use default)
remote:
remote:        Downloading and installing node 6.10.2...
remote:        Using default npm version: 3.10.10
remote:
remote: -----> Restoring cache
remote:        Skipping cache restore (new runtime signature)
remote:
remote: -----> Building dependencies
remote:        Installing node modules (package.json)
remote:        [email protected] /tmp/build_79a51eb9530595e21a4cba13968c1787
remote:        ├── [email protected]
remote:        └─┬ [email protected]
remote:        ├─┬ [email protected]
remote:        │ ├─┬ [email protected]
remote:        │ │ └── [email protected]
remote:        │ └── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├─┬ [email protected]
remote:        │ └── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├─┬ [email protected]
remote:        │ ├─┬ [email protected]
remote:        │ │ └── [email protected]
remote:        │ └── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├─┬ [email protected]
remote:        │ └── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├─┬ [email protected]
remote:        │ ├── [email protected]
remote:        │ └── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├─┬ [email protected]
remote:        │ ├── [email protected]
remote:        │ ├─┬ [email protected]
remote:        │ │ └── [email protected]
remote:        │ └── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├── [email protected]
remote:        ├─┬ [email protected]
remote:        │ └── [email protected]
remote:        ├── [email protected]
remote:        └── [email protected]
remote:
remote:
remote: -----> Caching build
remote:        Clearing previous node cache
remote:        Saving 2 cacheDirectories (default):
remote:        - node_modules
remote:        - bower_components (nothing to cache)
remote:
remote: -----> Build succeeded!
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 13.8M
remote: -----> Launching...
remote:        Released v3
remote:        https://polar-everglades-86549.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/polar-everglades-86549.git
 * [new branch]      master -> master

Administration

Scaling to one

Scaling to one dynamo, ensure that the service is running

heroku ps:scale web=1
Scaling dynos... done, now running web at 1:Free

Visiting the web App

heroku open

Logs

heroku logs --tail
2017-05-10T11:24:16.584039+00:00 app[api]: Initial release by user [email protected]
2017-05-10T11:24:16.584039+00:00 app[api]: Release v1 created by user [email protected]
2017-05-10T11:24:16.700241+00:00 app[api]: Enable Logplex by user [email protected]
2017-05-10T11:24:16.700241+00:00 app[api]: Release v2 created by user [email protected]
2017-05-10T11:28:50.776771+00:00 heroku[router]: at=info code=H81 desc="Blank app" method=GET path="/" host=polar-everglades-86549.herokuapp.com request_id=04fa5f79-8c7f-4722-97a5-cdd1d095e712 fwd="85.148.5.86" dyno= connect= service= status=502 bytes= protocol=https
2017-05-10T11:28:51.205038+00:00 heroku[router]: at=info code=H81 desc="Blank app" method=GET path="/favicon.ico" host=polar-everglades-86549.herokuapp.com request_id=10a0d8e4-79aa-44cf-bda2-218072d18f7f fwd="85.148.5.86" dyno= connect= service= status=502 bytes= protocol=https
2017-05-10T11:29:11.915892+00:00 heroku[router]: at=info code=H81 desc="Blank app" method=GET path="/" host=polar-everglades-86549.herokuapp.com request_id=ef438d45-d8a1-4200-84a2-ad9ade6d432b fwd="85.148.5.86" dyno= connect= service= status=502 bytes= protocol=https
2017-05-10T11:29:12.305410+00:00 heroku[router]: at=info code=H81 desc="Blank app" method=GET path="/favicon.ico" host=polar-everglades-86549.herokuapp.com request_id=1a94c2e7-4a91-49ca-b2a0-eedfe4d5afde fwd="85.148.5.86" dyno= connect= service= status=502 bytes= protocol=https
2017-05-10T11:31:41.000000+00:00 app[api]: Build started by user [email protected]
2017-05-10T11:31:57.394298+00:00 app[api]: Release v3 created by user [email protected]
2017-05-10T11:31:57.416174+00:00 app[api]: Scaled to web@1:Free by user [email protected]
2017-05-10T11:31:57.394298+00:00 app[api]: Deploy 428f826 by user [email protected]
2017-05-10T11:31:41.000000+00:00 app[api]: Build succeeded
2017-05-10T11:31:59.101876+00:00 heroku[web.1]: Starting process with command `node index.js`
2017-05-10T11:32:01.238800+00:00 app[web.1]: Node app is running on port 45560
2017-05-10T11:32:02.739781+00:00 heroku[web.1]: State changed from starting to up
2017-05-10T11:32:58.600129+00:00 heroku[router]: at=info method=GET path="/" host=polar-everglades-86549.herokuapp.com request_id=8a920ec1-c2c2-46b6-93d4-3b479b7796b6 fwd="85.148.5.86" dyno=web.1 connect=1ms service=36ms status=200 bytes=7049 protocol=https
2017-05-10T11:32:58.773287+00:00 heroku[router]: at=info method=GET path="/stylesheets/main.css" host=polar-everglades-86549.herokuapp.com request_id=9fb963b8-402f-4653-9cde-85494eb8c403 fwd="85.148.5.86" dyno=web.1 connect=1ms service=11ms status=200 bytes=908 protocol=https
2017-05-10T11:32:58.901898+00:00 heroku[router]: at=info method=GET path="/lang-logo.png" host=polar-everglades-86549.herokuapp.com request_id=0c89bf4d-ba66-41be-96bd-49faa6e7ff4a fwd="85.148.5.86" dyno=web.1 connect=1ms service=5ms status=200 bytes=2567 protocol=https
2017-05-10T11:32:59.208398+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=polar-everglades-86549.herokuapp.com request_id=185cd31b-8cc1-4dac-812c-0192bf539b93 fwd="85.148.5.86" dyno=web.1 connect=1ms service=7ms status=404 bytes=394 protocol=https
2017-05-10T11:44:14.292488+00:00 heroku[router]: at=info method=GET path="/" host=polar-everglades-86549.herokuapp.com request_id=b95adbf7-9270-4a4a-8a63-d1ec023c099d fwd="85.148.5.86" dyno=web.1 connect=1ms service=3ms status=200 bytes=7049 protocol=https
2017-05-10T11:44:14.484144+00:00 heroku[router]: at=info method=GET path="/stylesheets/main.css" host=polar-everglades-86549.herokuapp.com request_id=feacdca6-0a1f-4d10-b762-8d7820300767 fwd="85.148.5.86" dyno=web.1 connect=1ms service=3ms status=200 bytes=908 protocol=https
2017-05-10T11:44:14.721101+00:00 heroku[router]: at=info method=GET path="/lang-logo.png" host=polar-everglades-86549.herokuapp.com request_id=2f6d83a2-0e42-41f0-88d0-260d313718b6 fwd="85.148.5.86" dyno=web.1 connect=1ms service=5ms status=200 bytes=2567 protocol=https
2017-05-10T11:44:14.974834+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=polar-everglades-86549.herokuapp.com request_id=1ff050ac-a540-40d6-aa3a-451704bee524 fwd="85.148.5.86" dyno=web.1 connect=1ms service=8ms status=404 bytes=394 protocol=https
2017-05-10T11:44:15.102391+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=polar-everglades-86549.herokuapp.com request_id=240daaa8-9bf5-428f-8cdb-d749440fe7b8 fwd="85.148.5.86" dyno=web.1 connect=1ms service=2ms status=404 bytes=394 protocol=https