Search code examples
dockerdockerfileazure-pipelinesnpm-installdocker-for-windows

EPERM error building Windows node.js Docker image on Azure Pipeline


I'm trying to run a node.js app in a Docker container on Windows Server. I have limited control over the server. Most notably, the server doesn't have Hyper-V available, so (I believe) I need a Windows-based Docker image. I have a Dockerfile that I can successfully build locally, but I'm getting an error when I try to build everything in an Azure Pipeline:

Error: EPERM: operation not permitted, open 'C:\app\package-lock.json'

I have verified (with RUN dir) that the file is successfully copied.

Edit The pipeline works, on Azure as well as locally, if I don't copy over package-lock.json

Also of note (maybe), there's another error at the very beginning of the pipeline output:

"C:\Program Files\Docker\docker.exe" pull "=installer c:\node\nodejs\ ."
invalid reference format
"C:\Program Files\Docker\docker.exe" inspect "=installer c:\node\nodejs\ ."
Error: No such object: =installer c:\node\nodejs\ .

Though that might not be related as it appears to commence with building the image.

Dockerfile

# escape=`

FROM mcr.microsoft.com/powershell:lts-nanoserver-1809 as installer

ARG NODE=16.3.0

RUN mkdir -p C:\node
WORKDIR C:\node

SHELL ["pwsh.exe", "-command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]

RUN Invoke-WebRequest -Uri https://nodejs.org/dist/v$env:NODE/node-v$env:NODE-win-x64.zip -OutFile nodejsZip.zip -UseBasicParsing `
    && Expand-Archive nodejsZip.zip -DestinationPath .`
    && Rename-Item node-v$env:NODE-win-x64 nodejs

FROM mcr.microsoft.com/windows/nanoserver:1809

WORKDIR C:\nodejs
COPY --from=installer C:\node\nodejs\ .
ENV PATH="$WindowsPATH;C:/nodejs"
RUN npm config set registry https://registry.npmjs.org/

ENV NODE_ENV=production

WORKDIR /app

# install and cache app dependencies
COPY package.json package-lock.json* npm-shrinkwrap.json* .npmrc .\

RUN dir

RUN npm install --production && move node_modules ..\

COPY . .

EXPOSE 8080

CMD ["npm", "start"]

Pipeline step

  - task: Docker@2
    displayName: Build and push Docker image
    inputs:
      command: buildAndPush
      repository: ***
      dockerfile: $(appDirectory)Dockerfile
      containerRegistry: $(dockerRegistryServiceConnection)
      tags: |
        $(Build.BuildId)

Pipeline output

Starting: Build and push Docker image
==============================================================================
Task         : Docker
Description  : Build or push Docker images, login or logout, start or stop containers, or run a Docker command
Version      : 2.187.0
Author       : Microsoft Corporation
Help         : https://aka.ms/azpipes-docker-tsg
==============================================================================
"C:\Program Files\Docker\docker.exe" pull "=installer c:\node\nodejs\ ."
invalid reference format
"C:\Program Files\Docker\docker.exe" inspect "=installer c:\node\nodejs\ ."
Error: No such object: =installer c:\node\nodejs\ .
[]
"C:\Program Files\Docker\docker.exe" build -f D:\a\1\s\App\Dockerfile [bunch of labels with revealing names] -t ***/[appName]:1610 -t ***/[appName]:latest -t ***/[appName]:1.1.0 D:\a\1\s\App
Sending build context to Docker daemon  156.5MB

Step 1/30 : FROM mcr.microsoft.com/powershell:lts-nanoserver-1809 as installer
lts-nanoserver-1809: Pulling from powershell
b9043d31610e: Already exists
9385842e37a1: Pulling fs layer
1785b1708bde: Pulling fs layer
8bbda5f0e88c: Pulling fs layer
69aef7d2d307: Pulling fs layer
ce716bfd5dfd: Pulling fs layer
01ded93fffb2: Pulling fs layer
54121c5fa6ac: Pulling fs layer
3f8033467b82: Pulling fs layer
9e9e60715d2d: Pulling fs layer
69aef7d2d307: Waiting
ce716bfd5dfd: Waiting
01ded93fffb2: Waiting
54121c5fa6ac: Waiting
3f8033467b82: Waiting
9e9e60715d2d: Waiting
8bbda5f0e88c: Verifying Checksum
8bbda5f0e88c: Download complete
1785b1708bde: Verifying Checksum
1785b1708bde: Download complete
9385842e37a1: Verifying Checksum
ce716bfd5dfd: Verifying Checksum
ce716bfd5dfd: Download complete
69aef7d2d307: Verifying Checksum
69aef7d2d307: Download complete
54121c5fa6ac: Verifying Checksum
54121c5fa6ac: Download complete
3f8033467b82: Verifying Checksum
3f8033467b82: Download complete
9385842e37a1: Pull complete
9e9e60715d2d: Verifying Checksum
9e9e60715d2d: Download complete
1785b1708bde: Pull complete
8bbda5f0e88c: Pull complete
69aef7d2d307: Pull complete
ce716bfd5dfd: Pull complete
01ded93fffb2: Verifying Checksum
01ded93fffb2: Download complete
01ded93fffb2: Pull complete
54121c5fa6ac: Pull complete
3f8033467b82: Pull complete
9e9e60715d2d: Pull complete
Digest: sha256:2742181d6096061fa10b0b0ef34a00a634e7361f4948f4d71d99df052a08da64
Status: Downloaded newer image for mcr.microsoft.com/powershell:lts-nanoserver-1809
 ---> 4375ea1bb0a3
Step 2/30 : ARG NODE=16.3.0
 ---> Running in a129a7c48527
Removing intermediate container a129a7c48527
 ---> 6b07c85950b7
Step 3/30 : RUN mkdir -p C:\node
 ---> Running in 09f84ee6dbc8
Removing intermediate container 09f84ee6dbc8
 ---> 3400da58010d
Step 4/30 : WORKDIR C:\node
 ---> Running in 3406bcfdbc3e
Removing intermediate container 3406bcfdbc3e
 ---> 1957d042581a
Step 5/30 : SHELL ["pwsh.exe", "-command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]
 ---> Running in cb32ef99f0ec
Removing intermediate container cb32ef99f0ec
 ---> a39d5e0ae00e
Step 6/30 : RUN Invoke-WebRequest -Uri https://nodejs.org/dist/v$env:NODE/node-v$env:NODE-win-x64.zip -OutFile nodejsZip.zip -UseBasicParsing     && Expand-Archive nodejsZip.zip -DestinationPath .    && Rename-Item node-v$env:NODE-win-x64 nodejs
 ---> Running in f693e5889205
Removing intermediate container f693e5889205
 ---> 88ac85fc56b9
Step 7/30 : FROM mcr.microsoft.com/windows/nanoserver:1809
 ---> ad675c9cb2d5
Step 8/30 : WORKDIR C:\nodejs
 ---> Running in 07e5c75044bb
Removing intermediate container 07e5c75044bb
 ---> 985de76e022c
Step 9/30 : COPY --from=installer C:\node\nodejs\ .
 ---> 614424adca70
Step 10/30 : ENV PATH="$WindowsPATH;C:/nodejs"
 ---> Running in 54c7d7063723
Removing intermediate container 54c7d7063723
 ---> 06f449a12162
Step 11/30 : RUN npm config set registry https://registry.npmjs.org/
 ---> Running in 88e0f906a572
npm notice 
npm notice New minor version of npm available! 7.15.1 -> 7.16.0
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v7.16.0>
npm notice Run `npm install -g [email protected]` to update!
npm notice 
npm notice 
npm notice New minor version of npm available! 7.15.1 -> 7.16.0
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v7.16.0>
npm notice Run `npm install -g [email protected]` to update!
npm notice 
Removing intermediate container 88e0f906a572
 ---> 37b0211fe99a
Step 12/30 : ENV NODE_ENV=production
 ---> Running in db15abf42b2e
Removing intermediate container db15abf42b2e
 ---> 1e1b5bfc11bf
Step 13/30 : WORKDIR /app
 ---> Running in db460e099de7
Removing intermediate container db460e099de7
 ---> 5bcaea65c911
Step 14/30 : COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", ".npmrc", ".\\"]
 ---> 6f1ebb928f0d
Step 15/30 : RUN dir
 ---> Running in 117829a3f0f5
 Volume in drive C has no label.
 Volume Serial Number is 1A2C-F251
 Directory of C:\app

06/04/2021  04:44 PM    <DIR>          .
06/04/2021  04:44 PM    <DIR>          ..
06/04/2021  04:42 PM             2,645 .npmrc
06/04/2021  04:42 PM         1,720,232 package-lock.json
06/04/2021  04:42 PM             3,101 package.json
               3 File(s)      1,725,978 bytes
               2 Dir(s)  21,299,695,616 bytes free
Removing intermediate container 117829a3f0f5
 ---> b51123956a61
Step 16/30 : RUN npm install --production && move node_modules ..\
 ---> Running in 8e47b2ad349e
npm ERR! code EPERM
npm ERR! syscall open
npm ERR! path C:\app\package-lock.json
npm ERR! errno -4048
npm ERR! Error: EPERM: operation not permitted, open 'C:\app\package-lock.json'
npm ERR!  [Error: EPERM: operation not permitted, open 'C:\app\package-lock.json'] {
npm ERR!   errno: -4048,
npm ERR!   code: 'EPERM',
npm ERR!   syscall: 'open',
npm ERR!   path: 'C:\\app\\package-lock.json'
npm ERR! }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
npm ERR! or that you lack permissions to access it.
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\ContainerUser\AppData\Local\npm-cache\_logs\2021-06-04T16_45_21_968Z-debug.log
The command 'cmd /S /C npm install --production && move node_modules ..\' returned a non-zero code: 4294963248
##[error]The process 'C:\Program Files\Docker\docker.exe' failed with exit code 4294963248
Finishing: Build and push Docker image

Solution

  • It turns out that the default user in mcr.microsoft.com/windows/nanoserver:1809 is ContainerUser, a non-administrator account. I'm not sure the exact permissions Docker's COPY command uses on Windows containers. On Linux it creates files owned by root though, so something similar in Windows. Switching to the ContainerAdministrator user (USER ContainerAdministrator) for the npm install process fixed my permissions problems.