Heroku makes it easy to deploy an app via Docker. On building a React app, the distribution folder has index.html
, bundle.js
, styles.css
and images folder. Utilities like serve
helps to serve static files from the distribution folder.
Building the Docker image
I am assuming that you are familiar with Docker: image, container and registry. Dockerfile builds a new image. We start with the official Node image tagged 8.4.0.
FROM node:8.4.0
Install serve.
RUN npm install -g serve
When we are building an image from the Dockerfile, every step creates a new container from the image generated in the previous step. The container is temporary and is saved as a layer in the final image. Docker container is composed of several read-only layers and one writable layer on the top.
We copy package.json from our working folder to the container. And install all the packages.
COPY package.json package.json RUN npm install
We copy the existing folder to the container. Then, build the React app.
COPY . . RUN npm run build
Some folders like node_modules
are not copied due to the .dockerignore
file.
.git dist node_modules
The final step is to issue a command to serve the static files generated in the dist
folder.
CMD serve -p $PORT -s dist
Heroku supplies the special $PORT variable in the previous step. The complete Dockerfile is available in the gist.
Deploy to Heroku
Heroku has a private docker registry at registry.heroku.com
. Build the image for the heroku registry.
docker build -t registry.heroku.com/myapp/web .
The name of the app in Heroku is myapp
. Create the app manually from the dashboard. It is free. The web
denotes the type of the dyno. There are two roles for dyno: web and worker. Since we are creating a web app, the dyno type is web
.
Issue the push command.
docker push registry.heroku.com/myapp/web
When the private Heroku registry gets the image, a new container is instantiated automatically. Go to the browser and visit the web page: https://myapp.herokuapp.com
.