diff --git a/lib/manager/npm/post-update/index.js b/lib/manager/npm/post-update/index.js
index 0932df833de73e28b5f1197cb495a73f7e03bea9..81e3d53c603fb90a203f972d88491ba1abb2233f 100644
--- a/lib/manager/npm/post-update/index.js
+++ b/lib/manager/npm/post-update/index.js
@@ -534,7 +534,7 @@ async function getAdditionalFiles(config, packageFiles) {
     const res = await pnpm.generateLockFile(
       upath.join(config.localDir, lockFileDir),
       env,
-      config.binarySource
+      config
     );
     if (res.error) {
       // istanbul ignore if
diff --git a/lib/manager/npm/post-update/pnpm.js b/lib/manager/npm/post-update/pnpm.js
index e5815ceba1d9cb9eac1bbdcacfbaacd021ad9cf1..ba999d95c6d55d3436ff23453ab8dbf1109f8014 100644
--- a/lib/manager/npm/post-update/pnpm.js
+++ b/lib/manager/npm/post-update/pnpm.js
@@ -8,7 +8,7 @@ module.exports = {
   generateLockFile,
 };
 
-async function generateLockFile(cwd, env, binarySource) {
+async function generateLockFile(cwd, env, config) {
   logger.debug(`Spawning pnpm install to create ${cwd}/pnpm-lock.yaml`);
   let lockFile = null;
   let stdout;
@@ -53,9 +53,22 @@ async function generateLockFile(cwd, env, binarySource) {
         }
       }
     }
-    if (binarySource === 'global') {
+    if (config.binarySource === 'global') {
       cmd = 'pnpm';
     }
+    if (config.binarySource === 'docker') {
+      logger.info('Running pnpm via docker');
+      cmd = `docker run --rm `;
+      const volumes = [cwd];
+      if (config.cacheDir) {
+        volumes.push(config.cacheDir);
+      }
+      cmd += volumes.map(v => `-v ${v}:${v} `).join('');
+      const envVars = ['NPM_CONFIG_CACHE', 'npm_config_store'];
+      cmd += envVars.map(e => `-e ${e} `).join('');
+      cmd += `-w ${cwd} `;
+      cmd += `renovate/pnpm pnpm`;
+    }
     logger.debug(`Using pnpm: ${cmd}`);
     cmd += ' install';
     cmd += ' --lockfile-only';
diff --git a/test/workers/branch/lock-files/pnpm.spec.js b/test/workers/branch/lock-files/pnpm.spec.js
index 75d6f4a4bbf04a02b0c56bfb06eb329d87e6a677..79b02dbdf825bfb62c4d1551dfb955e8e2cc8a01 100644
--- a/test/workers/branch/lock-files/pnpm.spec.js
+++ b/test/workers/branch/lock-files/pnpm.spec.js
@@ -12,6 +12,11 @@ const { exec } = require('child-process-promise');
 const pnpmHelper = require('../../../../lib/manager/npm/post-update/pnpm');
 
 describe('generateLockFile', () => {
+  let env;
+  let config;
+  beforeEach(() => {
+    config = { cacheDir: 'some-cache-dir' };
+  });
   it('generates lock files', async () => {
     getInstalledPath.mockReturnValueOnce('node_modules/pnpm');
     exec.mockReturnValueOnce({
@@ -19,7 +24,19 @@ describe('generateLockFile', () => {
       stderror: '',
     });
     fs.readFile = jest.fn(() => 'package-lock-contents');
-    const res = await pnpmHelper.generateLockFile('some-dir');
+    const res = await pnpmHelper.generateLockFile('some-dir', env, config);
+    expect(fs.readFile).toHaveBeenCalledTimes(1);
+    expect(res.lockFile).toEqual('package-lock-contents');
+  });
+  it('uses docker pnpm', async () => {
+    getInstalledPath.mockReturnValueOnce('node_modules/pnpm');
+    exec.mockReturnValueOnce({
+      stdout: '',
+      stderror: '',
+    });
+    fs.readFile = jest.fn(() => 'package-lock-contents');
+    config.binarySource = 'docker';
+    const res = await pnpmHelper.generateLockFile('some-dir', env, config);
     expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.lockFile).toEqual('package-lock-contents');
   });
@@ -32,7 +49,7 @@ describe('generateLockFile', () => {
     fs.readFile = jest.fn(() => {
       throw new Error('not found');
     });
-    const res = await pnpmHelper.generateLockFile('some-dir');
+    const res = await pnpmHelper.generateLockFile('some-dir', env, config);
     expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.error).toBe(true);
     expect(res.lockFile).not.toBeDefined();
@@ -50,7 +67,7 @@ describe('generateLockFile', () => {
       stderror: '',
     });
     fs.readFile = jest.fn(() => 'package-lock-contents');
-    const res = await pnpmHelper.generateLockFile('some-dir');
+    const res = await pnpmHelper.generateLockFile('some-dir', env, config);
     expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.lockFile).toEqual('package-lock-contents');
   });
@@ -68,7 +85,7 @@ describe('generateLockFile', () => {
       stderror: '',
     });
     fs.readFile = jest.fn(() => 'package-lock-contents');
-    const res = await pnpmHelper.generateLockFile('some-dir');
+    const res = await pnpmHelper.generateLockFile('some-dir', env, config);
     expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.lockFile).toEqual('package-lock-contents');
   });
@@ -88,11 +105,8 @@ describe('generateLockFile', () => {
       stderror: '',
     });
     fs.readFile = jest.fn(() => 'package-lock-contents');
-    const res = await pnpmHelper.generateLockFile(
-      'some-dir',
-      undefined,
-      'global'
-    );
+    config.binarySource = 'global';
+    const res = await pnpmHelper.generateLockFile('some-dir', env, config);
     expect(fs.readFile).toHaveBeenCalledTimes(1);
     expect(res.lockFile).toEqual('package-lock-contents');
   });