Sagar Medtiya
Sagar Medtiya

Sagar Medtiya

🎉Deploy MERN app to ⚛️ Heroku with 🐳 Docker🚀🚀

Sagar Medtiya's photo
Sagar Medtiya
·Jul 30, 2022·

5 min read

🎉Deploy MERN app to ⚛️ Heroku with 🐳 Docker🚀🚀

Subscribe to my newsletter and never miss my upcoming articles

Play this article

Table of contents

📦 A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. Containerizing with Docker is now common part of app deployment. This approach eliminates missing dependencies and aids in maintenance especially when an app consists of many microservices.

We will create a 🐳 Docker image of React + expressJs then deploy it to heroku.

🪜 Create the basic React + expressJs app

The 📂folder structure is as follows.

Screenshot 2022-07-27 185423.png This is the folder structure which we will deploy it on heroku using Docker. Copy the frontend folder and paste it to backend folder.

🪜 Proxy

Remove the proxy from /backend/frontend/package.json file, if you have any.

🪜 PORT 🔢number

We need to change the PORT number from Static to Dynamic for Heroku in server.js file of backend. So, heroku can sets its own PORT number through dotenv file.

Screenshot 2022-07-30 204516.png

🪜 Script section of package.js

Next, we need to add few 📜scripts on package.js file of backend folder to tell ⚛️ heroku what to do.

“scripts”: {
    “start”: “node server.js”,
    "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix frontend && npm run build --prefix frontend",
    “test”: “echo \”Error: no test specified\” && exit 1"
},

🪜 Serve the static files

We need to go to the frontend 📂folder and run npm build. It will create a build folder and that is the folder which we want to serve on Heroku as a frontend. Now we need to tell backend which files to serve. So, go to the server.js and add few lines above the app.listen() method.

if(process.env.NODE_ENV==="production"){
    app.use(express.static("frontend/build"))
}

🪜 Create a new ⚛️Heroku app

Screenshot 2022-07-30 211225.png

Log in to your ⚛️Heroku account. From the Dashboard, go to “New > Create new app”.

After choosing an App Name and Region, click “Create app”. Once the app is created, move to the “Settings” tab and note the Heroku git URL. This will be used later to deploy the Docker container.

Screenshot 2022-07-30 211541.png

🪜 Docker Image deploy to heroku

Heroku supports 2 methods for deployment using Docker (list in Heroku docs):

a) Using 📦Container Registry

This method pushes Docker images built on your local machine to Heroku. To see the exact steps, go to your Heroku app’s page. Under “Deploy > Deployment” , click on “Container Registry”. The steps will appear below:

Screenshot 2022-07-30 220016.png

Create a Procfile in the root directory. Copy the following line in Procfile

web: npm start

In the backend folder, create a "DockerFile.web" file. “web” is the name of the process. This is the example code here. The resulting image runs on an official Nodejs image (Check Docker Hub for versions).

#Start from the pre-existing official Node image
FROM node:14

# Working directory. "/usr/local/bin/" is what Heroku takes as the "root" folder. Files MUST be added here or they cannot be found!
WORKDIR /usr/local/bin/backend

#Copy the app's source code into the image's filesystem
COPY . /usr/local/bin/backend/

#Install the required dependency of expressJs. Runs in container root directory.
RUN npm install

#Install the required files for the react-app in the frontend folder
RUN npm install --prefix frontend

#Build React app
RUN npm run --prefix frontend build

#Run the app when container launches.
CMD ["npm", "start"]

In the same backend folder create .dockerignore file then insert the 👩‍💻code below. The Dockerfile has instructions to install the dependencies listed in backend/package.json and backend/frontend/package.json so there is no need to package the large node_modules folders.

node_modules
client/node_modules

Now, git add . and git commit -a these new files to your local Git repo.

It is now time to upload to Heroku. Open a console in the root directory then run the following:

1. $ heroku git:remote -a <herokuAppName> Adds the Heroku Git URL to your repo’s remote.

2. $ heroku login Starts a prompt to enter your Heroku credentials to log into the CLI.

3. heroku container:login Logs you into the Container Registry.

4. heroku container:push --recursive -a <herokuAppName> Starts the image build process. “ — recursive” looks in every subfolder of root to find a Dockerfile.xxx. “-a” specifies the name of the Heroku app in your account.

5. heroku container:release -a <herokuAppName> web Releases the completed image to your Heroku app.

Congrats your app is successfully hosted. 🎉🎉

b) Deploying using heroku.yml🎈

Let, move to the second method. create a “heroku.yml” file in the root directory and paste the following code:

build:
  docker:
    web: backend/Dockerfile

There is no need to create Procfile here. Create a 🐳 Dockerfile then insert the code below. Note, the name of the file is "DockerFile" not "DockerFile.web". This is because the path to the Dockerfile is specified in heroku.yml.

#Start from the pre-existing official Node image
FROM node:14

# Working directory. "/usr/local/bin/" is what Heroku takes as the "root" folder. Files MUST be added here or they cannot be found!
WORKDIR /usr/local/bin/backend

#Copy the app's source code into the image's filesystem
COPY . /usr/local/bin/backend/

#Install the required dependency of expressJs. Runs in container root directory.
RUN npm install

#Install the required files for the react-app in the frontend folder
RUN npm install --prefix frontend

#Build React app
RUN npm run --prefix frontend build

#Run the app when container launches.
CMD ["npm", "start"]

Again, in the same backend folder create .dockerignore file then insert the 👩‍💻code below. The Dockerfile has instructions to install the dependencies listed in backend/package.json and backend/frontend/package.json so there is no need to package the large node_modules folders.

node_modules
client/node_modules

Now, git add . and git commit -a these new files to your local Git repo.

It is now time to upload to Heroku. Open a console in the root directory then run the following:

1. $ heroku git:remote -a <herokuAppName> Adds the Heroku Git URL to your repo’s remote.

2. $ heroku login Starts a prompt to enter your Heroku credentials to log into the CLI.

3. heroku container:login Logs you into the Container Registry.

4. heroku container:push --recursive -a <herokuAppName> Starts the image build process. “ — recursive” looks in every subfolder of root to find a Dockerfile.xxx. “-a” specifies the name of the Heroku app in your account.

5. heroku container:release -a <herokuAppName> web Releases the completed image to your Heroku app.

Congrats your app is successfully hosted. 🎉🎉

Thanks for reading!

Did you find this article valuable?

Support Sagar Medtiya by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this