diff --git a/lib/manager/bundler/artifacts.spec.ts b/lib/manager/bundler/artifacts.spec.ts
index 8ebcfacbfd4d9da5cf92c6aa5d9df830bbc31aff..5d0a07c27fa72e61b7775f19a1d66610b160eb1c 100644
--- a/lib/manager/bundler/artifacts.spec.ts
+++ b/lib/manager/bundler/artifacts.spec.ts
@@ -3,7 +3,7 @@ import Git from 'simple-git/promise';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../test/execUtil';
 import { mocked, platform } from '../../../test/util';
-import * as _datasource from '../../datasource/docker';
+import * as _datasource from '../../datasource';
 import { setUtilConfig } from '../../util';
 import { BinarySource } from '../../util/exec/common';
 import * as docker from '../../util/exec/docker';
@@ -21,7 +21,7 @@ const bundlerHostRules = mocked(_bundlerHostRules);
 jest.mock('fs-extra');
 jest.mock('child_process');
 jest.mock('../../../lib/util/exec/env');
-jest.mock('../../../lib/datasource/docker');
+jest.mock('../../../lib/datasource');
 jest.mock('../../../lib/util/fs');
 jest.mock('../../../lib/util/host-rules');
 jest.mock('./host-rules');
@@ -126,7 +126,7 @@ describe('bundler.updateArtifacts()', () => {
       fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
       fs.writeLocalFile.mockResolvedValueOnce(null as never);
       fs.readLocalFile.mockResolvedValueOnce('1.2.0');
-      datasource.getReleases.mockResolvedValueOnce({
+      datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
           { version: '1.2.0' },
@@ -154,7 +154,7 @@ describe('bundler.updateArtifacts()', () => {
     it('compatibility options', async () => {
       fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
       fs.writeLocalFile.mockResolvedValueOnce(null as never);
-      datasource.getReleases.mockResolvedValueOnce({
+      datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
           { version: '1.2.0' },
@@ -187,7 +187,7 @@ describe('bundler.updateArtifacts()', () => {
     it('invalid compatibility options', async () => {
       fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
       fs.writeLocalFile.mockResolvedValueOnce(null as never);
-      datasource.getReleases.mockResolvedValueOnce({
+      datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
           { version: '1.2.0' },
@@ -222,7 +222,7 @@ describe('bundler.updateArtifacts()', () => {
       fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
       fs.writeLocalFile.mockResolvedValueOnce(null as never);
       fs.readLocalFile.mockResolvedValueOnce('1.2.0');
-      datasource.getReleases.mockResolvedValueOnce({
+      datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
           { version: '1.2.0' },
diff --git a/lib/manager/cocoapods/artifacts.spec.ts b/lib/manager/cocoapods/artifacts.spec.ts
index 97571ffd70bff9ef950d5df31761228f361d6aea..0b47245645d292660b164ce78b00f99d1c41f102 100644
--- a/lib/manager/cocoapods/artifacts.spec.ts
+++ b/lib/manager/cocoapods/artifacts.spec.ts
@@ -4,7 +4,7 @@ import Git from 'simple-git/promise';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../test/execUtil';
 import { mocked } from '../../../test/util';
-import * as _datasource from '../../datasource/docker';
+import * as _datasource from '../../datasource';
 import { platform as _platform } from '../../platform';
 import { setExecConfig } from '../../util/exec';
 import { BinarySource } from '../../util/exec/common';
@@ -15,7 +15,7 @@ jest.mock('fs-extra');
 jest.mock('child_process');
 jest.mock('../../util/exec/env');
 jest.mock('../../platform');
-jest.mock('../../datasource/docker');
+jest.mock('../../datasource');
 
 const fs: jest.Mocked<typeof _fs> = _fs as any;
 const exec: jest.Mock<typeof _exec> = _exec as any;
@@ -36,7 +36,7 @@ describe('.updateArtifacts()', () => {
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     await setExecConfig(config);
 
-    datasource.getReleases.mockResolvedValue({
+    datasource.getPkgReleases.mockResolvedValue({
       releases: [
         { version: '1.2.0' },
         { version: '1.2.1' },
@@ -220,7 +220,7 @@ describe('.updateArtifacts()', () => {
     });
 
     fs.readFile.mockResolvedValueOnce('COCOAPODS: 1.2.4' as any);
-    datasource.getReleases.mockResolvedValueOnce({
+    datasource.getPkgReleases.mockResolvedValueOnce({
       releases: [],
     });
 
diff --git a/lib/manager/poetry/artifacts.spec.ts b/lib/manager/poetry/artifacts.spec.ts
index f231068d3e428351f9e6fc6c0dbba5a89d7f8e0c..686598d6a872ab813f34e6e970f1a5ae69d7485c 100644
--- a/lib/manager/poetry/artifacts.spec.ts
+++ b/lib/manager/poetry/artifacts.spec.ts
@@ -3,7 +3,7 @@ import _fs from 'fs-extra';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../test/execUtil';
 import { mocked } from '../../../test/util';
-import * as _datasource from '../../datasource/docker';
+import * as _datasource from '../../datasource';
 import { setExecConfig } from '../../util/exec';
 import { BinarySource } from '../../util/exec/common';
 import * as docker from '../../util/exec/docker';
@@ -13,7 +13,7 @@ import { updateArtifacts } from './artifacts';
 jest.mock('fs-extra');
 jest.mock('child_process');
 jest.mock('../../util/exec/env');
-jest.mock('../../datasource/docker');
+jest.mock('../../datasource');
 
 const fs: jest.Mocked<typeof _fs> = _fs as any;
 const exec: jest.Mock<typeof _exec> = _exec as any;
@@ -109,7 +109,7 @@ describe('.updateArtifacts()', () => {
     fs.readFile.mockResolvedValueOnce('[metadata]\n' as any);
     const execSnapshots = mockExecAll(exec);
     fs.readFile.mockReturnValueOnce('New poetry.lock' as any);
-    datasource.getReleases.mockResolvedValueOnce({
+    datasource.getPkgReleases.mockResolvedValueOnce({
       releases: [{ version: '2.7.5' }, { version: '3.4.2' }],
     });
     const updatedDeps = ['dep1'];
@@ -138,7 +138,7 @@ describe('.updateArtifacts()', () => {
     );
     const execSnapshots = mockExecAll(exec);
     fs.readFile.mockReturnValueOnce('New poetry.lock' as any);
-    datasource.getReleases.mockResolvedValueOnce({
+    datasource.getPkgReleases.mockResolvedValueOnce({
       releases: [{ version: '2.7.5' }, { version: '3.3.2' }],
     });
     const updatedDeps = ['dep1'];
diff --git a/lib/util/exec/docker/index.ts b/lib/util/exec/docker/index.ts
index 54f624117760ae9e64b22e70e36ebc8da8d21b63..df9ee26269392a935694e0328164f8b887cdb625 100644
--- a/lib/util/exec/docker/index.ts
+++ b/lib/util/exec/docker/index.ts
@@ -1,5 +1,5 @@
 import { SYSTEM_INSUFFICIENT_MEMORY } from '../../../constants/error-messages';
-import { getReleases } from '../../../datasource/docker';
+import { getPkgReleases } from '../../../datasource';
 import { logger } from '../../../logger';
 import * as versioning from '../../../versioning';
 import {
@@ -68,7 +68,7 @@ function prepareCommands(commands: Opt<string>[]): string[] {
 }
 
 async function getDockerTag(
-  lookupName: string,
+  depName: string,
   constraint: string,
   scheme: string
 ): Promise<string> {
@@ -81,9 +81,9 @@ async function getDockerTag(
 
   logger.debug(
     { constraint },
-    `Found ${scheme} version constraint - checking for a compatible ${lookupName} image to use`
+    `Found ${scheme} version constraint - checking for a compatible ${depName} image to use`
   );
-  const imageReleases = await getReleases({ lookupName });
+  const imageReleases = await getPkgReleases({ datasource: 'docker', depName });
   if (imageReleases && imageReleases.releases) {
     let versions = imageReleases.releases.map((release) => release.version);
     versions = versions.filter(
@@ -99,7 +99,7 @@ async function getDockerTag(
       return version;
     }
   } /* istanbul ignore next */ else {
-    logger.error(`No ${lookupName} releases found`);
+    logger.error(`No ${depName} releases found`);
     return 'latest';
   }
   logger.warn(