shopify-app-template-node icon indicating copy to clipboard operation
shopify-app-template-node copied to clipboard

Default Docker configuration does not work

Open faves-pro opened this issue 3 years ago • 3 comments

Issue summary

Write a short description of the issue here ↓

The default node app template does not run in Docker container.

Expected behavior

What do you think should happen?

After installing the template using npm init @shopify/app@latest and successfully running it locally (including ngrok setup and connection to our development store), I built a Docker image to containerize the setup. Given that this app template includes a pre-built Dockerfile, expected behavior is that the app would run in a container without error.

Actual behavior

What actually happens?

Upon launching the container, it exits immediately with the following error:

file:///app/index.js:29
  SCOPES: process.env.SCOPES.split(","),
                             ^
TypeError: Cannot read properties of undefined (reading 'split')
    at file:///app/index.js:29:30
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
    at async loadESM (node:internal/process/esm_loader:91:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)
Node.js v18.12.1

The issue appears to be due to a missing file: process.env. I do not understand why the app runs locally without this file, or why it is not included if necessary for running in Docker. But after reading up on the issue, I used the command npm run shopify app env pull to get the environment variables:

SHOPIFY_API_KEY=00000000000000000000000000000000
SHOPIFY_API_SECRET=00000000000000000000000000000000
SCOPES=write_products

I saved this output in two files: process.env and .env because there seems to be confusion about which filename is required.

As a side note, I discovered that the env pull command does not generate all the necessary env values. I had to manually add HOST=<ngrok_address>.

After rebuilding my Docker image and running it, I still got the same TypeError. I then posted my question on StackOverflow, where I was advised to forget about the env files and just add ENV SCOPES=write_products to the Shopify-supplied default Dockerfile. So now my Dockerfile looks like this:

FROM node:18-alpine
ARG SHOPIFY_API_KEY
ENV SHOPIFY_API_KEY=$SHOPIFY_API_KEY
EXPOSE 8081
WORKDIR /app
COPY web .
RUN npm install
RUN cd frontend && npm install && npm run build
CMD ["npm", "run", "serve"]
ENV SCOPES=write_products
ENV HOST=https://a1b1-123-456-789-00.eu.ngrok.io

Again rebuilding and running the container, I got a new error:

/app/node_modules/@shopify/shopify-api/dist/context.js:37
        if (!params.API_SECRET_KEY.length) {
                                   ^
TypeError: Cannot read properties of undefined (reading 'length')
    at Object.initialize (/app/node_modules/@shopify/shopify-api/dist/context.js:37:36)
    at file:///app/index.js:26:17
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
    at async loadESM (node:internal/process/esm_loader:91:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)
Node.js v18.12.1

I then I tried adding ARG API_SECRET_KEY=<my_key> to the Dockerfile, but I still get the error.

I am unable to find any help regarding Docker configuration on the Shopify dev portal.

Steps to reproduce the problem

  1. Follow the documented process of creating a new app: https://shopify.dev/apps/getting-started/create
  2. docker build -t my-new-app .
  3. docker run -p 8081:8081 my-new-app

Reduced test case

It is easily replicated by the above three steps. Let me know if more info is needed.

Specifications

  • Browser: n/a
  • Device: macOS Montery (M1)
  • Operating System: 12.6.1

faves-pro avatar Nov 17 '22 13:11 faves-pro

Same for me!

knsakib avatar Nov 30 '22 23:11 knsakib

I had the same too. I think the Shopify documentation needs to be clearer for how to set up a generic Docker container, not just the specific Fly.io and Heroku examples.

I managed to get it working initially by hard-coding the required variables into the Docker file. I found that you need to supply all the environment variables BEFORE the CMD ["npm", "run", "serve"] command in the Dockerfile. My Dockerfile looked like this, with the parts in brackets obviously replaced with the app's values:

FROM node:18-alpine

ARG SHOPIFY_API_KEY
ENV SHOPIFY_API_KEY=$SHOPIFY_API_KEY

ENV SHOPIFY_API_KEY=<key value>
ENV SHOPIFY_API_SECRET=<secret value>
ENV SCOPES=<your app's scope>
ENV HOST=<https://11223344.au.ngrok.io>
ENV BACKEND_PORT=80

EXPOSE 80
WORKDIR /app
COPY web .
RUN npm install
RUN cd frontend && npm install && npm run build
CMD ["npm", "run", "serve"]

After I had my Docker container running I eventually moved the hard-coded variables out of the Docker file and into environment variables. In my case, they were environment variables set within the container definition of an ECS task definition on AWS. You will have to provide those environment variables somehow depending on how you are running your Docker container, otherwise the app won't work. You could do it through a .env file. I found this website helpful in understanding ARG and ENV in Docker files and places you can put environment variables: https://vsupalov.com/docker-arg-env-variable-guide/

Another thing I found is that you have to provide the SHOPIFY_API_KEY value during the Docker image build as well, or the app won't work. The initial Docker file handles that with the ARG and ENV line to set the API key during the build, but you have to provide that argument during the build with a command like this: docker build -t my-new-app --build-arg SHOPIFY_API_KEY=<API key here> .

james-theinsightlab avatar Dec 14 '22 00:12 james-theinsightlab

currently dealing with the same issue here. However, i'm trying to use docker-compose, and also experiencing issues.

I gave chatgpt the dockerfile to make me a docker-compose, but got these error:

app_1  | 
app_1  | > [email protected] serve
app_1  | > cross-env NODE_ENV=production node index.js
app_1  | 
app_1  | sh: cross-env: not found
  1. i then gave this to chatgpt and it suggested to refactor my dockerfile, which seems odd for shopify and led me here, to see if others had the same issue.
  2. the way you have to pass environment values like 'shopify api key' is a little annoying in and of itself, but also unclear since they don't really direct you to where you'd get it. On the partners page they provide a client secret and id but they don't explicitly state whether that's the appropriate 'shopify api key' leaving it sort of ambiguous.

ultimately, would be nice to see more clear instructions and docs on using docker and docker-compose.

Visualieyes avatar May 30 '23 20:05 Visualieyes