0

I'm trying to deploy a pretty standard TypeScript Node container to Heroku. Here is the Dockerfile, that works just fine for local build.

FROM node:14-alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm ci --only=production

COPY ./compiled .
COPY ./public ./public

EXPOSE 4040
CMD [ "node", "index.js" ]
// heroku.yml
build:
  docker:
    web: Dockerfile

Now, I know that on Heroku, the port will be provided by the platform, but I didn't make it far enough to have that problem. I'm stuck before that in the Activity log:

Step 4/7 : RUN npm ci --only=production
 ---> Running in 61cf46d0be1f
npm WARN lifecycle myapp_backend@1.0.0~postinstall: cannot run in wd myapp_backend@1.0.0 tsc (wd=/usr/src/app)
added 60 packages in 1.075s
Removing intermediate container 61cf46d0be1f
 ---> 8cce5940d0f5
Step 5/7 : COPY ./compiled .
COPY failed: stat /var/lib/docker/tmp/docker-builder777398979/compiled: no such file or directory

So I went on to fix the '...cannot run wd...' error, using this post: Npm install failed with "cannot run in wd"

// package.json
  "scripts": {
    "build": "tsc",
    "start": "node .",
  },
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "helmet": "^4.4.1",
    "node-fetch": "^2.6.1"
  },
  "devDependencies": {
    "@types/cors": "^2.8.10",
    "@types/express": "^4.17.11",
    "@types/node": "^14.14.35",
    "@types/node-fetch": "^2.5.8",
    "typescript": "^4.2.3"
  },
  "config": {
    "unsafe-perm":true
  }
// Dockerfile
RUN npm ci --only=production --unsafe-perm
Step 4/7 : RUN npm ci --only=production --unsafe-perm
 ---> Running in 0555a5061172
added 60 packages in 1.087s
Removing intermediate container 0555a5061172
 ---> a9ed9b662358
Step 5/7 : COPY ./compiled .
COPY failed: stat /var/lib/docker/tmp/docker-builder271351523/compiled: no such file or directory

Ok, so I figured tsc is missing because I only install production dependencies. But if this is the case, how come it was alright with the local build? Anyway, I removed the --only=production flag, and got this:

Step 4/7 : RUN npm ci --unsafe-perm
 ---> Running in f3ab9181ff90
> nodemon@2.0.7 postinstall /usr/src/app/node_modules/nodemon
> node bin/postinstall || exit 0
Love nodemon? You can now support the project via the open collective:
 > https://opencollective.com/nodemon/donate
added 904 packages in 9.533s
Removing intermediate container f3ab9181ff90
 ---> 81bcb481c282
Step 5/7 : COPY ./compiled .
COPY failed: stat /var/lib/docker/tmp/docker-builder740874603/compiled: no such file or directory

UPDATE

As jonrsharpe pointed out, the Dockerfile was indeed missing the build sript, so I added it. RUN npm run build This is how it looks like:

Step 5/8 : RUN npm run build
 ---> Running in b2dc7db58473
> myapp_backend@1.0.0 build /usr/src/app
> tsc
Version 4.2.3
Syntax:   tsc [options] [file...]
.
.
.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! myapp_backend@1.0.0 build: `tsc`
npm ERR! Exit status 1
DBencz
  • 849
  • 1
  • 9
  • 15
  • 1
    Please give a [mre], what are you actually running here? Why are you trying to build in a postinstall instead of just having a build script? Why isn't this a multi-stage build? – jonrsharpe Jun 14 '21 at 21:19
  • Thank you @jonrsharpe, the postinstall script was left in there accidentaly. I removed it, and updated the post with the new results, and included the package.json. – DBencz Jun 15 '21 at 07:36
  • 1
    Where exactly do you think build gets run in that Dockerfile? Step 4 is installing the dependencies, prior to which it couldn't be run because the compiler isn't installed, step 5 is trying to copy the outputs. – jonrsharpe Jun 15 '21 at 07:38
  • If postinstall script is present, it gets called, so if it has the same commands as the build script, the Dockerfile doesn't actually need a new layer to run the build. Either way should be fine. However, now tsc does get called, but it exits out anyway. – DBencz Jun 15 '21 at 21:07
  • 1
    And does npm run build work _outside_ the container? Note you've so far only copied in the package and lock files, not the **whole rest of your app**. – jonrsharpe Jun 15 '21 at 21:17
  • This has been the missing clue, now the pipeline succeeds! Thank you very much! Should you answer the question, I would accept the answer, you absolutely earned it :) Thanks again a lot! – DBencz Jun 16 '21 at 15:07
  • I can't see "you need to have files to compile to compile your files" having durable value - I'm glad you solved the problem but I think the question can just be deleted. – jonrsharpe Jun 16 '21 at 15:10

0 Answers0