2

I'm trying to create a production build for a node typescript project using a Dockerfile.

Though, at the step of converting the TS files into Javascript, I get the following error:

error TS5057: Cannot find a tsconfig.json file at the specified directory: '.'.
error Command failed with exit code 1.

Can someone help me getting this right, please?

Below are the pieces of information about the main files used:

  • Dockerfile
FROM node:lts-stretch-slim

# Create app directory to hold the application code inside the image
WORKDIR /usr/src/app

# Install app dependencies
COPY package*.json yarn.lock ./

RUN yarn

RUN yarn build

COPY ./dist .

EXPOSE 3333

COPY entrypoint.sh /
ENTRYPOINT [ "/bin/bash", "/entrypoint.sh" ]
  • Error
[4/4] Building fresh packages...
Done in 13.99s.
Removing intermediate container 44a52bf048a4
 ---> 39b5fc8dc705
Step 5/9 : RUN yarn build
 ---> Running in 04bb0ea984e3
yarn run v1.22.4
$ tsc -p .
error TS5057: Cannot find a tsconfig.json file at the specified directory: '.'.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: Service 'node-app' failed to build: The command '/bin/sh -c yarn build' returned a non-zero code: 1
  • Package.json
"scripts": {
    "dev": "ts-node-dev --transpileOnly --ignore-watch node_modules src/server.ts",
    "start": "node dist/src/server.js",
    "build": "tsc -p ."
  },
  • tsconfig.json
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Basic Options */
    // "incremental": true,                   /* Enable incremental compilation */
    "target": "es6",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    // "lib": [],                             /* Specify library files to be included in the compilation. */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    "outDir": "./dist",                        /* Redirect output structure to the directory. */
    "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "composite": true,                     /* Enable project compilation */
    // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
    // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */

    /* Source Map Options */
    // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */

    /* Advanced Options */
    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  }
}

PS: Both the Dockerfile and the tsconfig.json are at the root directory of the project (same level I mean). And I can successfully run the yarn build script locally (outside of the Dockerfile), which in turn generates the dist folder with only JS code.

PS2: I followed this tutorial in order to build a similar Dockerfile for me.

3
  • 2
    you have to either copy that file into your container image or mount a volume with it. Commented Jun 17, 2020 at 23:47
  • Yeah, thanks @DanielA.White That did solve the error I was gettting. But now, I'm getting another one regarding the build step: error TS18003: No inputs were found in config file '/usr/src/app/tsconfig.json'. Specified 'include' paths were '["**/*"]' and 'exclude' paths were '["./dist"]'. error Command failed with exit code 2. Do you know what might be the reason for this one? Thanks again for the response. Commented Jun 18, 2020 at 15:03
  • Well, I did solve the problem from my last comment by following this answer. Commented Jun 18, 2020 at 16:58

2 Answers 2

2

You are not copying all the files to the container. You are only copying what is in the dist folder with COPY ./dist .

My question to you is, is this for development or for production? If its for development you can just copy the while root directory of the project with

COPY . .

Now if this is for a production build you definitely want an intermediate build step so you only have to copy the compiled JS code to the container and run that.

Sign up to request clarification or add additional context in comments.

1 Comment

Hey @German Gamboa , thanks for the reply. Yeah, this is for a production build. I did what @Daniel A. White mentioned above in the comment's section of the question, adding a COPY step for the tsconfig, and the error I was having was gone. Though, as also mentioned in the response of his comment, I'm facing another error now regarding the intermediate build step tsc -p . . Do you have any ideas on what could be the reason for this error? And thanks again!
1

Thanks to the folks that have helped, I was able to adjust the Dockerfile accordingly to my needs here.

I had to create an empty TS file next to my tsconfig.json file to get rid of the error mentioned at my comment above. I also had to remove the dist in front of the path in the script section, otherwise I would get a module not found error.

The Dockerfile ended up being like this for now:

FROM node:lts-stretch-slim
# FROM node:10

# Create app directory to hold the application code inside the image
WORKDIR /usr/src/app

# Install app dependencies
COPY package*.json yarn.lock ./
COPY tsconfig.json ./
COPY .env ./

COPY emptyTs.ts ./

RUN yarn


RUN yarn build

COPY ./dist .
# COPY . .

EXPOSE 3333

COPY entrypoint.sh /
ENTRYPOINT [ "/bin/bash", "/entrypoint.sh" ]
  • package.json
  "scripts": {
    "dev": "ts-node-dev --transpileOnly --ignore-watch node_modules src/server.ts",
    "start": "node src/server.js",
    "build": "tsc -p ."
  },

Updated answer (November 28th, 2020)

I ended up using a multi-stage build for this. Below you can find the Dockerfile script I wrote:

FROM node:lts-stretch-slim AS build
WORKDIR /usr/src/app
COPY package*.json yarn.lock ./
COPY tsconfig.json ./
COPY .env ./
RUN yarn
COPY . .
RUN yarn build


FROM node:lts-stretch-slim
WORKDIR /usr/src/app
COPY package*.json yarn.lock ./
COPY .env ./
RUN yarn
COPY --from=build /usr/src/app/dist ./
EXPOSE 3333
COPY entrypoint.sh /
ENTRYPOINT [ "/bin/bash", "/entrypoint.sh" ]

3 Comments

Why are you coping the dist folder from host machine ideally we should assume that it is not created right? Isn't yarn build doing that for you?
I don't remember exactly why I did that at that time, but I believe I was getting typescript errors which wasn't allowing me to get the code compiled in the container. Though, I ended up creating a multi-stage build for that sometime afterwards.
I updated the answer with my final solution @Vallie Hope it helps!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.