Dockerizing a Shopify Node App
Tags: node, docker, shopify, react
Published: 2021-07-08 21:17:08

I am in the process of learning to develop apps for the Shopify platform. In doing so, I wanted to establish early on how I would be deploying and managing my apps. I recently earned my [GCP Professional Cloud Architect certification](https://www.credential.net/6554ea1d-24f7-4373-acf9-04cdc1504619#gs.5w943v) so I was pretty sure I would be using GCP in production. I decided that the easiest way to deploy and manage my apps in production would be to containerize them using [Docker](https://www.docker.com/). If your not familiar with what a container is I highly recommend reading [this overview](https://www.docker.com/resources/what-container) on the docker site. TLDR; a container packages a software application and its dependencies so that it can execute across different environments without the need to pre-configure those environments.

Let's get started!

## Pre-requisites:
1. [Node.js](https://nodejs.org/en/) v16.4.2
2. [Docker desktop](https://www.docker.com/products/docker-desktop) v3.5
3. [Shopify CLI](https://shopify.dev/apps/tools/cli/installation)

## Initial Steps
I started by following along the [Shopify quick start guide](https://shopify.dev/apps/getting-started/create) that shows you how to use the Shopify CLI tool to quickly create an app and install and run it on a Shopify development store. I won't go thru the steps here but I do recommend going thru them yourself.

Once you have followed the Shopify quick start guide as described above, you will have used the Shopify CLI tool to create an example app and then to also serve it up on your local development system. The commands that the quick start guide uses are as follows:

1. shopify node create
2. shopify node serve

The first command scaffolds a new Node.js app in a subdirectory and creates your app in the Shopify Partner Dashboard.

The second command starts an ngrok tunnel, updates the .env file in your app project, updates information about the app in the Shopify Partner dashboard and then actually starts the app locally.

Go ahead and issue these two commands per the guide and see that your app is running in your development store. Next, stop the app from executing locally once you have verified it working in your development store.

In our case we want to package our app into a docker container and then execute that container. 

## Docker
We first need to create a file called 'Dockerfile' in the root of our apps project directory. Here is a Dockerfile that I created that will work with the Shopify quickstart app:

```docker
FROM node:16.4
WORKDIR /app
COPY package.json /app
RUN npm install --production --legacy-peer-deps
COPY . /app
RUN npm run build
CMD npm run start
EXPOSE 8081
```

It is also good practice to create a .dockerignore file also in the app project root so unnecessary items don't end up in the docker image:

```
Dockerfile
.dockerignore
node_modules
npm-debug.log
```

Once we have these files in place, go ahead and issue the following command in the root of your project app directory. This will create the Docker image for the app:

`docker build -t <project_name> .`

Here is a screenshot of the command output:
![Docker build command output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gev3liezcisrwe4hop3u.png)

At this point the Docker image for the app has been created. We can now run the app in the container with the following command:

`docker run -p 8081:8081 <project_name>`

You should be able to go back to your Shopify development store and see the app running. Note that the '8081:8081' part of the command specifies the PORT that the Docker image will listen on. In the case of the Shopify quick-start example the PORT is defaulted to 8081.

We now have a Docker image of our Shopify app that we can either run locally using the Docker desktop tool or deploy to the cloud and execute there. This makes the job of deploying the app much easier as we won't have to worry about configuring a server. In my [next post](https://dev.to/deanandreakis/deploying-a-shopify-node-app-docker-image-to-gcp-417d) I will talk about using GCP Container Registry and GCP Cloud Run to manage and execute my app containers.

## Last Notes and Gotchas
It is important to note that because we worked-thru the Shopify quick-start example first, the details of creating an app locally, configuring the app in the Shopify Partner dashboard, starting ngrok, updating the .env file in the project etc. are taken care of behind the scenes by the two (2) shopify CLI commands I mentioned earlier:

1. shopify node create
2. shopify node serve

If we were starting a new app and wanted to create a Docker image for that app we could just issue the commands above first as in the guide and then go back and create the Dockerfile and build the image as defined above.

Alternatively, we may just want to issue the first command (shopify node create) and then take care of everything else ourselves instead of issuing the second command (shopify node serve). In that case we have a few things to take care of before building the Docker image:

1. Execute `ngrok http <PORT>` where PORT is the port your apps server is listening on.
2. Update the .env file in the app project: The 'HOST' variable needs to be updated with the URL that ngrok displayed above.
3. Update the .env file in the app project: The 'SHOPIFY_API_KEY' and 'SHOPIFY_API_SECRET' must match the values from the app information in the Shopify Partner dashboard.
4. Update the app information in the Shopify Partner dashboard. The app url and app redirect url(s) must be updated to match the ngrok url:
![App URls](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ajk5jhwankz7hruns0f7.png)
5. Install the app into your Shopify development store by visiting the following url in your browser:
`https://<ngrok_url>/auth?shop=<store_name>.myshopify.com`