Docker file does not COPY files in subdirectories correctly when pushing to a local Balena device from Windows 10

I am writing a Typescript app that I want to run on several Raspberry Pis managed and deployed using Balena. My dev computer is running Windows 10. I am fairly new to Balena and Docker.

I am trying to compile my typescript in the Docker file, but the COPY command does not seem to copy files in subdirectories correctly when pushing to a Balena device running in local mode.

I have a very simple file structure as I have just initiated the project:

Dockerfile
start.sh
src/
- index.ts
- tsconfig.json

My Dockerfile looks as follows:

FROM resin/raspberrypi3-node:10.0.0
WORKDIR /usr/src/app
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm i -g typescript
RUN JOBS=MAX npm install --production --unsafe-perm && npm cache verify && rm -rf /tmp/*

COPY . ./
RUN tsc -p src
CMD ["bash", "start.sh"]

When building and pushing the image to the Balena device in local mode I get the following error when the execution of the Dockerfile reaches the ‘RUN tsc -p src’ command:

[Build]   [main] Step 8/11 : RUN tsc -p src
[Build]   [main]  ---> Running in b843b59050da
[Build]   [main] error TS5058: The specified path does not exist: 'src'.
Some services failed to build:
        main: The command '/bin/sh -c tsc -p src' returned a non-zero code: 1

Likewise I cannot cd to the subdirectory and just run the tsc command from there:

[Build]   [main] Step 8/11 : RUN cd src
[Build]   [main]  ---> Running in 7620e8a516f3
[Build]   [main] /bin/sh: 1: cd: can't cd to src

I inserted a ‘RUN ls’ command into my Dockerfile before ‘RUN tsc -p src’ to verify the files are being copied which prints out the following:

[Build]   [main] Step 8/11 : RUN ls
[Build]   [main]  ---> Running in bf8b3c63454e
[Build]   [main] CHANGELOG.md
[Build]   Dockerfile
[Build]   README.md
[Build]   node_modules
[Build]   package-lock.json
[Build]   package.json
[Build]   src\index.ts
[Build]   src\tsconfig.json
[Build]   start.sh
[Build]   [main] Removing intermediate container bf8b3c63454e
[Build]   [main]  ---> 27ed6ea5eb9b
[Build]   [main] Step 9/11 : RUN tsc -p src
[Build]   [main]  ---> Running in 6ac5f86b5637
[Build]   [main] error TS5058: The specified path does not exist: 'src'.

At first glance it seems like the subdirectory is copied correctly but - correct me if I am wrong - ls should not be able to list files from subdirectories and it seems like the COPY command has somehow flattened the subdirectory. Honestly I am quit uncertain what happened.

Worth noting: the project compiles the TS just fine when just running ‘tsc -p src’ from the terminal of my dev computer and the files are copied correctly when pushing the project to a Balene device NOT running in local mode. It is when I push the project to a Balena device running in local mode it fails to copy files correctly.

Is there anything obvious I am missing? Hope someone can help me out. I am a bit at a loss.

Hi there,

Sorry to hear you’re having problems. Unfortunately I don’t have a copy of Windows to test this with but a quick test under MacOS in local mode does work for me.

Would you mind pushing the code to our builders (with the device out of local mode) to make sure this is a local build issue?

Best regards, Heds

Hi
Thanks for your response!

Sure. It works just fine when pushed to a device out of local mode.
I do not fully understand the architectural differences in pushing to a device locally from pushing to one out of local mode other than the code does not get deployed to the whole fleet. Does it not get build on the Pi the same way?
Obviously it does not

These entries there when you did ls looks suspicious:

[Build]   src\index.ts
[Build]   src\tsconfig.json

ls shouldn’t list contents recursively, so it seems the CLI copied the two files flat into the parent directory, i.e. with filenames src\index.ts, etc.

This seems like an issue with the CLI command, could please open a ticket on https://github.com/balena-io/balena-cli/issues ?

You should be able to confirm this is the case by replacing the ls RUN step with RUN cat 'src\tsconfig.json'

1 Like

I am actual able to cat the config file:
[Build] [main] Step 8/11 : RUN cat ‘src\tsconfig.json’
[Build] [main] —> Running in 5244084a805f
[Build] [main] {
[Build] “compilerOptions”: {
[Build] “module”: “commonjs”,
[Build] “target”: “es5”,
[Build] “sourceMap”: true,
[Build] “removeComments”: true,
[Build] “noImplicitAny”: true,
[Build] “outDir”: “…/dist”
[Build] },
[Build] “include” : [
[Build] “**/*.ts”
[Build] ]
[Build] }

Whoever the tsc command does not seem to be able to find it:

[Build]   [main] Step 9/11 : RUN tsc -p 'src\tsconfig.json'                                  
[Build]   [main]  ---> Running in 819c970a0c46                                               
[Build]   [main] error TS5058: The specified path does not exist: 'src\tsconfig.json'.       
Some services failed to build:                                                               
        main: The command '/bin/sh -c tsc -p 'src\tsconfig.json'' returned a non-zero code: 1

I obviously still want to keep the directory structure any way :slight_smile:

Yeah, it seems there’s an issue with how paths are handled on Windows. It would be great if you filed an issue on the CLI repository and referenced this forum thread.

I will! Thanks

Link to issue: https://github.com/balena-io/balena-cli/issues/1133