Skip to content

Commit

Permalink
fix(lambda-nodejs): permission denied on npm cache (aws#9167)
Browse files Browse the repository at this point in the history
The npm cache was owned by the user 1000 so if the image was run by
a user other than 1000 installing via npm (when using the `nodeModules`
prop) resulted in a `EACCES` error on the cache folder. Yarn automatically
falls back to `/tmp` in this case.

Move npm cache folder creation to the end of the Dockerfile so that no
root content has been created in it when the image starts. Set cache
folder permission to 777.

Also disable npm update notification and add tests for the Dockerfile.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
jogold authored and Chriscbr committed Jul 23, 2020
1 parent 0987b6a commit 76773b3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
14 changes: 8 additions & 6 deletions packages/@aws-cdk/aws-lambda-nodejs/parcel/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@
ARG IMAGE=lambci/lambda:build-nodejs12.x
FROM $IMAGE

# Ensure npm cache is not owned by root because the image will not run
# as root and can potentially run `npm install`.
RUN mkdir /npm-cache && \
chown -R 1000:1000 /npm-cache && \
npm config --global set cache /npm-cache

# Install yarn
RUN npm install --global yarn

Expand All @@ -17,4 +11,12 @@ RUN npm install --global yarn
ARG PARCEL_VERSION=2.0.0-beta.1
RUN cd / && npm install parcel@$PARCEL_VERSION

# Ensure all users can write to npm cache
RUN mkdir /tmp/npm-cache && \
chmod -R 777 /tmp/npm-cache && \
npm config --global set cache /tmp/npm-cache

# Disable npm update notifications
RUN npm config --global set update-notifier false

CMD [ "parcel" ]
39 changes: 39 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/test/docker.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { spawnSync } from 'child_process';
import * as path from 'path';

beforeAll(() => {
spawnSync('docker', ['build', '-t', 'parcel', path.join(__dirname, '../parcel')]);
});

test('parcel is available', async () => {
const proc = spawnSync('docker', [
'run', 'parcel',
'sh', '-c',
'$(node -p "require.resolve(\'parcel\')") --version',
]);
expect(proc.status).toEqual(0);
});

test('can npm install with non root user', async () => {
const proc = spawnSync('docker', [
'run', '-u', '1000:1000',
'parcel',
'sh', '-c', [
'mkdir /tmp/test',
'cd /tmp/test',
'npm i constructs',
].join(' && ')]);
expect(proc.status).toEqual(0);
});

test('can yarn install with non root user', async () => {
const proc = spawnSync('docker', [
'run', '-u', '500:500',
'parcel',
'sh', '-c', [
'mkdir /tmp/test',
'cd /tmp/test',
'yarn add constructs',
].join(' && ')]);
expect(proc.status).toEqual(0);
});

0 comments on commit 76773b3

Please sign in to comment.