diff --git a/lib/manager/dockerfile/__fixtures__/Dockerfile2 b/lib/manager/dockerfile/__fixtures__/Dockerfile2
new file mode 100644
index 0000000000000000000000000000000000000000..2c2320d27793d5a52dda80f2bfcbc510dc721934
--- /dev/null
+++ b/lib/manager/dockerfile/__fixtures__/Dockerfile2
@@ -0,0 +1,49 @@
+# different FROM syntaxes
+ FROM  image1 as		name1
+
+FROM image2:1.0.0@sha256:abcdef \
+	as name2
+
+# FROM image3
+
+FROM\
+    --platform=linux \
+	# comment1
+	 image4
+
+	FROM 	\
+ 	  \
+   image5 \
+	#comment5
+	as name3
+
+# different COPY --from syntaxes
+COPY --from=image6 /path/1 /path/2
+
+ COPY \
+	--from=image7:1.0.0@sha256:abcdef \
+	/path/1 \
+	/path/2
+
+# COPY --from=image8
+
+COPY   --from=image9
+
+COPY\
+    --chown=root \
+	# comment1
+#
+ #comment2
+ --from=image10
+	# comment2
+    path1 path2
+
+COPY --chown=root --from=image11 / ./
+
+	COPY 	\
+ 	  \
+   --from=image12 a \
+	#comment5
+	b
+
+COPY	--from=image13 --chown=root: a b
diff --git a/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap b/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap
index 19960ee8cc275f3983b805ff326a9ebd9d29d71f..7c0f2969618d241186a335be729f9497ef19e121 100644
--- a/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap
+++ b/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap
@@ -33,6 +33,110 @@ Array [
 ]
 `;
 
+exports[`lib/manager/dockerfile/extract extractPackageFile() extracts images from all sorts of (maybe multiline) FROM and COPY --from statements 1`] = `
+Array [
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image1",
+    "depType": "stage",
+    "replaceString": "image1",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": "sha256:abcdef",
+    "currentValue": "1.0.0",
+    "datasource": "docker",
+    "depName": "image2",
+    "depType": "stage",
+    "replaceString": "image2:1.0.0@sha256:abcdef",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image4",
+    "depType": "stage",
+    "replaceString": "image4",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image5",
+    "depType": "stage",
+    "replaceString": "image5",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image6",
+    "depType": "stage",
+    "replaceString": "image6",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": "sha256:abcdef",
+    "currentValue": "1.0.0",
+    "datasource": "docker",
+    "depName": "image7",
+    "depType": "stage",
+    "replaceString": "image7:1.0.0@sha256:abcdef",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image9",
+    "depType": "stage",
+    "replaceString": "image9",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image10",
+    "depType": "stage",
+    "replaceString": "image10",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image11",
+    "depType": "stage",
+    "replaceString": "image11",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image12",
+    "depType": "stage",
+    "replaceString": "image12",
+  },
+  Object {
+    "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
+    "currentDigest": undefined,
+    "currentValue": undefined,
+    "datasource": "docker",
+    "depName": "image13",
+    "depType": "final",
+    "replaceString": "image13",
+  },
+]
+`;
+
 exports[`lib/manager/dockerfile/extract extractPackageFile() extracts images on adjacent lines 1`] = `
 Array [
   Object {
diff --git a/lib/manager/dockerfile/extract.spec.ts b/lib/manager/dockerfile/extract.spec.ts
index 93d0af0dacf2aca7207ab0e6c344083173ff60ec..347664ebde61e6fedadf1a483964a382cfcb1c84 100644
--- a/lib/manager/dockerfile/extract.spec.ts
+++ b/lib/manager/dockerfile/extract.spec.ts
@@ -6,6 +6,11 @@ const d1 = readFileSync(
   'utf8'
 );
 
+const d2 = readFileSync(
+  'lib/manager/dockerfile/__fixtures__/Dockerfile2',
+  'utf8'
+);
+
 describe('lib/manager/dockerfile/extract', () => {
   describe('extractPackageFile()', () => {
     it('handles no FROM', () => {
@@ -142,6 +147,11 @@ describe('lib/manager/dockerfile/extract', () => {
       expect(res).toMatchSnapshot();
       expect(res).toHaveLength(2);
     });
+    it('extracts images from all sorts of (maybe multiline) FROM and COPY --from statements', () => {
+      const res = extractPackageFile(d2).deps;
+      expect(res).toMatchSnapshot();
+      expect(res).toHaveLength(11);
+    });
     it('handles calico/node', () => {
       const res = extractPackageFile('FROM calico/node\n').deps;
       expect(res).toMatchSnapshot();
diff --git a/lib/manager/dockerfile/extract.ts b/lib/manager/dockerfile/extract.ts
index aaba5097229e5d09b53dba6edb84a2cf2d986aad..6705b9ea2aed8d3d9d55106c6ee821577b527146 100644
--- a/lib/manager/dockerfile/extract.ts
+++ b/lib/manager/dockerfile/extract.ts
@@ -65,56 +65,61 @@ export function getDep(
 export function extractPackageFile(content: string): PackageFile | null {
   const deps: PackageDependency[] = [];
   const stageNames: string[] = [];
-  let lineNumber = 0;
-  for (const fromLine of content.split('\n')) {
-    const fromMatch = /^FROM /i.test(fromLine);
-    if (fromMatch) {
-      logger.trace({ lineNumber, fromLine }, 'FROM line');
-      const [, currentFrom, ...fromRest] = fromLine.match(/\S+/g);
-      if (fromRest.length === 2 && fromRest[0].toLowerCase() === 'as') {
-        logger.debug('Found a multistage build stage name');
-        stageNames.push(fromRest[1]);
-      }
-      if (currentFrom === 'scratch') {
-        logger.debug('Skipping scratch');
-      } else if (stageNames.includes(currentFrom)) {
-        logger.debug({ currentFrom }, 'Skipping alias FROM');
-      } else {
-        const dep = getDep(currentFrom);
-        logger.trace(
-          {
-            depName: dep.depName,
-            currentValue: dep.currentValue,
-            currentDigest: dep.currentDigest,
-          },
-          'Dockerfile FROM'
-        );
-        deps.push(dep);
-      }
+
+  const fromMatches = content.matchAll(
+    /^[ \t]*FROM(?:\\\r?\n| |\t|#.*\r?\n|-\S+)+(?<image>\S+)(?:(?:\\\r?\n| |\t|#.*\r?\n)+as[ \t]+(?<name>\S+))?/gim
+  );
+
+  for (const fromMatch of fromMatches) {
+    if (fromMatch.groups.name) {
+      logger.debug('Found a multistage build stage name');
+      stageNames.push(fromMatch.groups.name);
+    }
+    if (fromMatch.groups.image === 'scratch') {
+      logger.debug('Skipping scratch');
+    } else if (stageNames.includes(fromMatch.groups.image)) {
+      logger.debug({ image: fromMatch.groups.image }, 'Skipping alias FROM');
+    } else {
+      const dep = getDep(fromMatch.groups.image);
+      logger.trace(
+        {
+          depName: dep.depName,
+          currentValue: dep.currentValue,
+          currentDigest: dep.currentDigest,
+        },
+        'Dockerfile FROM'
+      );
+      deps.push(dep);
     }
+  }
+
+  const copyFromMatches = content.matchAll(
+    /^[ \t]*COPY(?:\\\r?\n| |\t|#.*\r?\n|-\S+)+--from=(?<image>\S+)/gim
+  );
 
-    const copyFromMatch = /^(COPY --from=)([^\s]+)\s+(.*)$/i.exec(fromLine);
-    if (copyFromMatch) {
-      const [, , currentFrom] = copyFromMatch;
-      logger.trace({ lineNumber, fromLine }, 'COPY --from line');
-      if (stageNames.includes(currentFrom)) {
-        logger.debug({ currentFrom }, 'Skipping alias COPY --from');
-      } else if (!Number.isNaN(Number(currentFrom))) {
-        logger.debug({ currentFrom }, 'Skipping index reference COPY --from');
-      } else {
-        const dep = getDep(currentFrom);
-        logger.debug(
-          {
-            depName: dep.depName,
-            currentValue: dep.currentValue,
-            currentDigest: dep.currentDigest,
-          },
-          'Dockerfile COPY --from'
-        );
-        deps.push(dep);
-      }
+  for (const copyFromMatch of copyFromMatches) {
+    if (stageNames.includes(copyFromMatch.groups.image)) {
+      logger.debug(
+        { image: copyFromMatch.groups.image },
+        'Skipping alias COPY --from'
+      );
+    } else if (!Number.isNaN(Number(copyFromMatch.groups.image))) {
+      logger.debug(
+        { image: copyFromMatch.groups.image },
+        'Skipping index reference COPY --from'
+      );
+    } else {
+      const dep = getDep(copyFromMatch.groups.image);
+      logger.debug(
+        {
+          depName: dep.depName,
+          currentValue: dep.currentValue,
+          currentDigest: dep.currentDigest,
+        },
+        'Dockerfile COPY --from'
+      );
+      deps.push(dep);
     }
-    lineNumber += 1;
   }
   if (!deps.length) {
     return null;