Error while deploying Node.js app

First Time deploying to fly.io

I tried to deploy using fly deploy but it failed so I followed this tutorial Build A MERN Finance Dashboard App | Machine Learning, Typescript, React, Node, MUI, Deployment - YouTube
I tried to deploy it using the command fly deploy --local-only using Docker locally and I got this error:

=> ERROR [build 3/5] RUN npm install --production=false                                   3.3s 
------
 > [build 3/5] RUN npm install --production=false:
#10 0.938 npm WARN config production Use `--omit=dev` instead.
#10 3.216 npm ERR! code ERESOLVE
#10 3.226 npm ERR! ERESOLVE could not resolve
#10 3.226 npm ERR!
#10 3.227 npm ERR! While resolving: mongoose-currency@0.2.0
#10 3.227 npm ERR! Found: mongoose@7.0.3
#10 3.228 npm ERR! node_modules/mongoose
#10 3.229 npm ERR!   mongoose@"^7.0.3" from the root project
#10 3.229 npm ERR!
#10 3.230 npm ERR! Could not resolve dependency:
#10 3.231 npm ERR! peer mongoose@"~> 4.x" from mongoose-currency@0.2.0
#10 3.231 npm ERR! node_modules/mongoose-currency
#10 3.232 npm ERR!   mongoose-currency@"^0.2.0" from the root project
#10 3.233 npm ERR!
#10 3.233 npm ERR! Conflicting peer dependency: mongoose@4.13.21
#10 3.233 npm ERR! node_modules/mongoose
#10 3.234 npm ERR!   peer mongoose@"~> 4.x" from mongoose-currency@0.2.0
#10 3.234 npm ERR!   node_modules/mongoose-currency
#10 3.235 npm ERR!     mongoose-currency@"^0.2.0" from the root project
#10 3.236 npm ERR!
#10 3.237 npm ERR! Fix the upstream dependency conflict, or retry
#10 3.238 npm ERR! this command with --force or --legacy-peer-deps
#10 3.238 npm ERR! to accept an incorrect (and potentially broken) dependency resolution.       
#10 3.238 npm ERR!
#10 3.238 npm ERR!
#10 3.238 npm ERR! For a full report see:
#10 3.238 npm ERR! /root/.npm/_logs/2023-04-28T09_06_28_271Z-eresolve-report.txt
#10 3.242
#10 3.242 npm ERR! A complete log of this run can be found in:
#10 3.242 npm ERR!     /root/.npm/_logs/2023-04-28T09_06_28_271Z-debug-0.log
------
Error: failed to fetch an image or build from source: error building: executor failed running [/bin/sh -c 
npm install --production=false]: exit code: 1

It seems that it has nothing to do with mongoose, but I’m not sure what is actually happening.

My guess is that the problem you are seeing is that at one point you installed mongoose globally (npm install -g), so that it isn’t included in your package.json. You are going to need to install it locally for this to work.

Next, you will need to modify your Dockerfile and package.json so that mongoose is actually installed and run, and that your database is on a volume. I’ve outlined this process here:

1 Like

Thank you for your answer. As I mentioned this my first time deploying to fly.io, and actually my first time using Docker but, I would like to highlight a couple of points regarding the two steps you mentioned:
Regarding the first step: I installed mongoose locally, and it exists in my package.json.
For the second step: I’m using a mongoDB Atlas which is a hosted MongoDB service option in the cloud that requires no installation. So I don’t see how this is relevant.

OK, so my guess was wrong. Digging deeper, it looks like mongoose-currency has an explicit dependency on mongoose 4:

And yet you are running mongoose 7.

Try adding --legacy-peer-deps to the RUN npm install --production=false line to see if this helps.

Even better! Running the database on a separate server from the application is always best.

1 Like

I was just editing my answer to update you with that I tried to use --legacy-peer-deps and --force in my docker file and it didn’t work either.

Here’s what I tried so far:

RUN npm install --legacy-peer-deps --production=false,
RUN npm install --force --production=false

I tried to remove mongoose from my package.json and then install it separately by chaining two commands in dockerfile like so:

RUN npm install --production=false
RUN npm install mongoose-currency --legacy-peer-deps --production=false

I also tried the following command:

RUN npm install mongoose-currency --legacy-peer-deps && npm install --legacy-peer-deps --production=false

Nothin of the above worked neither with legacy-peer or force

Can you post your package.json? I’ll try to reproduce the problem.

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "helmet": "^6.0.1",
    "mongoose": "^7.0.0",
    "mongoose-currency": "^0.2.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.21"
  }
}

To clarify also, when I tried to run the command npm install localy it fails as well, but when I run it locally with the flag --legacy-peer-deps it works fine. The problem will be solved if it works the same way on the dockerfile because downgrading to mongoose 4 will require me to change my code including the index.js file to be compatible with mongoose v-4

When I run that, I get:

npm ERR! code EINVALIDTAGNAME
npm ERR! Invalid tag name "false," of package "false,": Tags may not have any characters that encodeURIComponent encodes.

After removing the trailing comma, it works for me. I suspect that was just a copy/paste error and that you tried it without the comma.

It is working for me with npm version 9.6.4, both on my local machine and on fly. What does npm -v return on your local machine, and what is NODE_VERSION in your Dockerfile?

I suspect that adding the following prior to the first npm install will help:

RUN npm install -g npm@latest

You right I tried it without the comma. It’s just a typo that I made here while writing the comment. My npm version is 9.6.2 and the NODE_VERSION in Dockerfile is 18.15.0

I tried the command Run npm install -g npm@latest in my dockerfile, and also tried RUN npm install -g npm@latest && npm install --legacy-peer-deps --production=false and I got the same error.

The following Dockerfile builds for me, and I suspect it will build for you:

# syntax = docker/dockerfile:1

ARG NODE_VERSION=18.15.0
FROM node:$NODE_VERSION-slim

WORKDIR /node

COPY <<-"EOF" /node/package.json
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "helmet": "^6.0.1",
    "mongoose": "^7.0.0",
    "mongoose-currency": "^0.2.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.21"
  }
}
EOF

RUN npm install --production=false --legacy-peer-deps

Feel free to try it, copy or rename your Dockerfile so that you can restore it after you run this test, and then replace it with the Dockerfile above, and then run fly deploy --build-only.

Obviously it won’t deploy anything interesting as it doesn’t include your application.

With this new Dockerfile as a base, would it be possible for you to incrementally introduce portions of your existing Dockerfile until you reproduce the problem?

Okay, just one more question to clarify. By what you said here, “With this new Dockerfile as a base, would it be possible for you to incrementally introduce portions of your existing Dockerfile until you reproduce the problem?” you mean that I change my Dockerfile to start with the instance you provided and then incrementally add portion of my previous Dockerfile until I run into that same erorr?

Sorry if my question is stupid. It’s my first time both deploying to fly.io and using Docker.

Not stupid at all. In fact, you stated what I meant to say, but much more clearly.

I want to help you get past this problem, but I can’t help until I can reproduce it myself.

Meanwhile, one other thing to check: do you have a .dockerignore file and does it include the node_modules directory? Including (and by that I mean not ignoring) the node_modules directory may cause problems.

If you are new to Dockerfiles, Rails cookbooks may be helpful, starting with the minimal cookbook. That content is a bit Ruby/Rails specific, but the concepts are the same. Eventually I hope to have a similar set of pages for Node.

Thank you so much, I really appreciate your help. First of all, yes my .dockerignore did include node_modules and I removed it. The second thing, when introducing snippits from my previous dockerfile: should I replace the WORKDIR /node to WORKDIR /app ?

Sorry again for being unclear. Please ensure that dockerignore includes node_modules.

That’s unlikely to be the problem, but yes. At this point you have Dockerfile that will build and one that fails to build. Getting the one that does build to fail is the goal at this point.

Okay so far the following Dockerfile works and the build succeed:

# syntax = docker/dockerfile:1

ARG NODE_VERSION=18.15.0
FROM node:$NODE_VERSION-slim

LABEL fly_launch_runtime="NodeJS"

# NodeJS app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV=production

COPY <<-"EOF" /app/package.json
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "helmet": "^6.0.1",
    "mongoose": "^7.0.0",
    "mongoose-currency": "^0.2.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.21"
  }
}
EOF

RUN npm install --production=false --legacy-peer-deps

But once I add this snippet FROM base as build and update my Dockerfile to be the following:

# syntax = docker/dockerfile:1

ARG NODE_VERSION=18.15.0
FROM node:$NODE_VERSION-slim

LABEL fly_launch_runtime="NodeJS"

# NodeJS app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV=production

# Throw-away build stage to reduce size of final image
FROM base as build

COPY <<-"EOF" /app/package.json
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "helmet": "^6.0.1",
    "mongoose": "^7.0.0",
    "mongoose-currency": "^0.2.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.21"
  }
}
EOF

RUN npm install --production=false --legacy-peer-deps

It crashes and display this error:

 => ERROR [internal] load metadata for docker.io/library/base:latest                                 1.2s 
------
 > [internal] load metadata for docker.io/library/base:latest:
------
Error: failed to fetch an image or build from source: error building: failed to solve with frontend dockerfile.v0: failed to solve with frontend gateway.v0: rpc error: code = Unknown desc = base: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

I also tried to add all of my previous Dockerfile like so:

# syntax = docker/dockerfile:1

ARG NODE_VERSION=18.15.0
FROM node:$NODE_VERSION-slim

LABEL fly_launch_runtime="NodeJS"

# NodeJS app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV=production

# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build node modules
RUN apt-get update -qq && \
    apt-get install -y python-is-python3 pkg-config build-essential 

COPY <<-"EOF" /app/package.json
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "helmet": "^6.0.1",
    "mongoose": "^7.0.0",
    "mongoose-currency": "^0.2.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.21"
  }
}
EOF

RUN npm install --production=false --legacy-peer-deps

# Copy application code
COPY --link . .

# Remove development dependencies
RUN npm prune --production


# Final stage for app image
FROM base

# Copy built application
COPY --from=build /app /app

# Start the server by default, this can be overwritten at runtime
CMD [ "npm", "run", "start" ]

And it displays the same error:

 => ERROR [internal] load metadata for docker.io/library/base:latest                                 1.2s 
------
 > [internal] load metadata for docker.io/library/base:latest:
------
Error: failed to fetch an image or build from source: error building: failed to solve with frontend dockerfile.v0: failed to solve with frontend gateway.v0: rpc error: code = Unknown desc = base: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

Change this to read:

FROM node:$NODE_VERSION-slim as base

Okay, finally. Lol.

So far this my Dockerfile:

# syntax = docker/dockerfile:1

ARG NODE_VERSION=18.15.0
FROM node:$NODE_VERSION-slim as base

LABEL fly_launch_runtime="NodeJS"

# NodeJS app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV=production

# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build node modules
RUN apt-get update -qq && \
    apt-get install -y python-is-python3 pkg-config build-essential 

COPY <<-"EOF" /app/package.json
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "helmet": "^6.0.1",
    "mongoose": "^7.0.0",
    "mongoose-currency": "^0.2.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.21"
  }
}
EOF

RUN npm install --production=false --legacy-peer-deps

# Copy application code
COPY --link . .

# Remove development dependencies
RUN npm prune --production

It worked fine until I add the last snippet. This one RUN npm prune --production then it displayed the error we’re looking for. This error:

------
 > [build 5/5] RUN npm prune --production:
#13 0.980 npm WARN config production Use `--omit=dev` instead.
#13 1.221 npm ERR! code ERESOLVE
#13 1.227 npm ERR! ERESOLVE could not resolve
#13 1.227 npm ERR!
#13 1.229 npm ERR! While resolving: mongoose-currency@0.2.0
#13 1.229 npm ERR! Found: mongoose@7.1.0
#13 1.229 npm ERR! node_modules/mongoose
#13 1.230 npm ERR!   mongoose@"^7.0.0" from the root project
#13 1.231 npm ERR!
#13 1.232 npm ERR! Could not resolve dependency:
#13 1.232 npm ERR! peer mongoose@"~> 4.x" from mongoose-currency@0.2.0
#13 1.232 npm ERR! node_modules/mongoose-currency
#13 1.232 npm ERR!   mongoose-currency@"^0.2.0" from the root project
#13 1.233 npm ERR!
#13 1.233 npm ERR! Conflicting peer dependency: mongoose@4.13.21
#13 1.233 npm ERR! node_modules/mongoose
#13 1.233 npm ERR!   peer mongoose@"~> 4.x" from mongoose-currency@0.2.0
#13 1.233 npm ERR!   node_modules/mongoose-currency
#13 1.234 npm ERR!     mongoose-currency@"^0.2.0" from the root project
#13 1.234 npm ERR!
#13 1.234 npm ERR! Fix the upstream dependency conflict, or retry
#13 1.234 npm ERR! this command with --force or --legacy-peer-deps
#13 1.234 npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
#13 1.235 npm ERR!
#13 1.235 npm ERR!
#13 1.235 npm ERR! For a full report see:
#13 1.235 npm ERR! /root/.npm/_logs/2023-04-29T16_24_29_402Z-eresolve-report.txt
#13 1.239
#13 1.239 npm ERR! A complete log of this run can be found in:
#13 1.240 npm ERR!     /root/.npm/_logs/2023-04-29T16_24_29_402Z-debug-0.log
------
Error: failed to fetch an image or build from source: error building: executor failed running [/bin/sh -c 
npm prune --production]: exit code: 1

To avoid any confusion, this the snippet that caused the error we’re looking for RUN npm prune --production

Does it fail without these lines?

I ask because those lines copy your entire application into the image. If you have your application posted online, I’ll be glad to try it. Otherwise I need something smaller.

If it doesn’t fail with these lines, try copying less:

COPY --link package-lock.json .

If that causes it to fail, posting your package-lock.json will allow me to reproduce the problem.

Would it be more helpful if I shared a repo with you?