diff --git a/lib/workers/repository/apis.js b/lib/workers/repository/apis.js
index fca3ca157818b04df2bbf671626a6c9f6d52a408..327e00bb2c6cfe087b0f55baa18d3bbbc74b418f 100644
--- a/lib/workers/repository/apis.js
+++ b/lib/workers/repository/apis.js
@@ -322,6 +322,9 @@ async function resolvePackageFiles(inputConfig) {
   const { logger } = config;
   logger.trace({ config }, 'resolvePackageFiles()');
   const packageFiles = [];
+  const contentBranch = config.repoIsOnboarded
+    ? config.baseBranch
+    : config.onboardingBranch;
   for (let packageFile of config.packageFiles) {
     packageFile =
       typeof packageFile === 'string' ? { packageFile } : packageFile;
@@ -329,7 +332,7 @@ async function resolvePackageFiles(inputConfig) {
       logger.debug(`Resolving packageFile ${JSON.stringify(packageFile)}`);
       const pFileRaw = await config.api.getFileContent(
         packageFile.packageFile,
-        config.baseBranch
+        contentBranch
       );
       if (!pFileRaw) {
         logger.info(
@@ -357,7 +360,7 @@ async function resolvePackageFiles(inputConfig) {
       if (!inputConfig.ignoreNpmrcFile) {
         packageFile.npmrc = await config.api.getFileContent(
           path.join(path.dirname(packageFile.packageFile), '.npmrc'),
-          config.baseBranch
+          contentBranch
         );
       }
       if (!packageFile.npmrc) {
@@ -365,7 +368,7 @@ async function resolvePackageFiles(inputConfig) {
       }
       packageFile.yarnrc = await config.api.getFileContent(
         path.join(path.dirname(packageFile.packageFile), '.yarnrc'),
-        config.baseBranch
+        contentBranch
       );
       if (!packageFile.yarnrc) {
         delete packageFile.yarnrc;
@@ -412,7 +415,7 @@ async function resolvePackageFiles(inputConfig) {
         );
         packageFile.yarnLock = await config.api.getFileContent(
           yarnLockFileName,
-          config.baseBranch
+          contentBranch
         );
         if (packageFile.yarnLock) {
           logger.debug(
@@ -426,7 +429,7 @@ async function resolvePackageFiles(inputConfig) {
         );
         packageFile.packageLock = await config.api.getFileContent(
           packageLockFileName,
-          config.baseBranch
+          contentBranch
         );
         if (packageFile.packageLock) {
           logger.debug(
@@ -446,7 +449,7 @@ async function resolvePackageFiles(inputConfig) {
       logger.debug(`Resolving packageFile ${JSON.stringify(packageFile)}`);
       packageFile.content = await config.api.getFileContent(
         packageFile.packageFile,
-        config.baseBranch
+        contentBranch
       );
       const strippedComment = packageFile.content.replace(/^(#.*?\n)+/, '');
       const fromMatch = strippedComment.match(/^FROM (.*)\n/);
diff --git a/lib/workers/repository/index.js b/lib/workers/repository/index.js
index a1c840fe566c04880aa6ebf26a73643bf29e50e8..6dcd5efbfe4b7d9a1f4f8c012f115398aaf47b5e 100644
--- a/lib/workers/repository/index.js
+++ b/lib/workers/repository/index.js
@@ -1,6 +1,5 @@
 const convertHrTime = require('convert-hrtime');
 const tmp = require('tmp');
-const presets = require('../../config/presets');
 // Workers
 const branchWorker = require('../branch');
 // children
@@ -64,6 +63,7 @@ async function renovateRepository(repoConfig, token) {
           logger.warn(message);
         }
       }
+      config = await onboarding.getOnboardingStatus(config);
       // Detect package files in default branch if not manually provisioned
       if (config.packageFiles.length === 0) {
         logger.debug('Detecting package files');
@@ -84,37 +84,6 @@ async function renovateRepository(repoConfig, token) {
       logger.trace({ config }, 'post-packageFiles config');
       // TODO: why is this fix needed?!
       config.logger = logger;
-      config = await onboarding.getOnboardingStatus(config);
-      if (!config.repoIsOnboarded) {
-        config.contentBaseBranch = `${config.branchPrefix}configure`;
-        // Remove packageFile list in case they are provisioned in renovate.json
-        const packageFiles = config.packageFiles.map(
-          packageFile => packageFile.packageFile
-        );
-        config.packageFiles = [];
-        config = await apis.mergeRenovateJson(config, config.contentBaseBranch);
-        // Restore previous packageFile list if not provisioned manually
-        if (config.packageFiles.length === 0) {
-          config.packageFiles = packageFiles;
-        }
-        if (config.baseBranch) {
-          if (await config.api.branchExists(config.baseBranch)) {
-            config.contentBaseBranch = config.baseBranch;
-          } else {
-            const message = `The configured baseBranch "${config.baseBranch}" is not present. Ignoring`;
-            config.errors.push({
-              depName: 'baseBranch',
-              message,
-            });
-            logger.warn(message);
-          }
-        }
-        config = await apis.resolvePackageFiles(config);
-        config = await apis.checkMonorepos(config);
-        config = await presets.resolveConfigPresets(config);
-        config.logger = logger;
-        logger.trace({ config }, 'onboarding config');
-      }
       config = decryptConfig(config);
       logger.trace({ config }, 'post-decrypt config');
       const allUpgrades = await upgrades.determineRepoUpgrades(config);
@@ -168,6 +137,8 @@ async function renovateRepository(repoConfig, token) {
     // Swallow this error so that other repositories can be processed
     if (err.message === 'uninitiated') {
       logger.info('Repository is uninitiated - skipping');
+    } else if (err.message === 'no package files') {
+      logger.info('Repository has no package files - skipping');
     } else {
       logger.error(`Failed to process repository: ${err.message}`);
       logger.debug({ err });
diff --git a/lib/workers/repository/onboarding.js b/lib/workers/repository/onboarding.js
index 2d034e6d5ada686fab11ad1c2e87b5c7e8c3ef54..d44f00d46b51d4263f23d66c4a4a8c68d665493d 100644
--- a/lib/workers/repository/onboarding.js
+++ b/lib/workers/repository/onboarding.js
@@ -1,8 +1,10 @@
+const apis = require('./apis');
+
 const onboardPrTitle = 'Configure Renovate';
 
 module.exports = {
   isRepoPrivate,
-  createBranch,
+  createOnboardingBranch,
   ensurePr,
   getOnboardingStatus,
 };
@@ -20,45 +22,48 @@ async function isRepoPrivate(config) {
   return repoIsPrivate === true;
 }
 
-async function createBranch(config) {
+async function createOnboardingBranch(inputConfig) {
+  let config = { ...inputConfig };
   const { logger } = config;
-  const onboardBranchName = `${config.branchPrefix}configure`;
+  config.meteor.enabled = true;
+  config.docker.enabled = true;
+  config = await apis.detectPackageFiles(config);
+  if (config.packageFiles.length === 0) {
+    throw new Error('no package files');
+  }
   const repoIsPrivate = await module.exports.isRepoPrivate(config);
-  let onboardingConfigString;
-  if (repoIsPrivate) {
-    logger.debug('Repo is private - setting to app type');
-    onboardingConfigString = `{\n  "extends": ["config:js-app"]\n}\n`;
+  const renovateJson = {
+    extends: [],
+  };
+  if (config.types.npm) {
+    if (repoIsPrivate) {
+      logger.debug('Repo is private - setting to app type');
+      renovateJson.extends.push('config:js-app');
+    } else {
+      logger.debug('Repo is not private - setting to library');
+      renovateJson.extends.push('config:js-lib');
+    }
   } else {
-    logger.debug('Repo is not private - setting to library');
-    onboardingConfigString = `{\n  "extends": ["config:js-lib"]\n}\n`;
+    renovateJson.extends.push('config:base');
   }
-  const existingContent = await config.api.getFileContent(
-    'renovate.json',
-    onboardBranchName
-  );
-  if (existingContent === onboardingConfigString) {
-    logger.debug('Onboarding branch is already up-to-date');
-    return;
+  if (config.types.meteor) {
+    renovateJson.extends.push(':meteor');
   }
-  if (existingContent) {
-    logger.debug(
-      { existingContent, onboardingConfigString },
-      'Updating onboarding branch'
-    );
-  } else {
-    logger.debug('Creating onboarding branch');
+  if (config.types.docker) {
+    renovateJson.extends.push(':docker');
   }
-
+  logger.info({ renovateJson }, 'Creating onboarding branch');
   await config.api.commitFilesToBranch(
-    onboardBranchName,
+    config.onboardingBranch,
     [
       {
         name: 'renovate.json',
-        contents: onboardingConfigString,
+        contents: `${JSON.stringify(renovateJson, null, 2)}\n`,
       },
     ],
     'Add renovate.json'
   );
+  return config;
 }
 
 async function ensurePr(config, branchUpgrades) {
@@ -229,39 +234,33 @@ With your current configuration, renovate will initially create the following Pu
 }
 
 async function getOnboardingStatus(inputConfig) {
-  const config = { ...inputConfig };
+  let config = { ...inputConfig };
   const { logger } = config;
-  logger.debug('Checking if repo is configured');
+  logger.debug('Checking if repo is onboarded');
   // Check if repository is configured
   if (config.onboarding === false) {
     logger.debug('Repo onboarding is disabled');
     return { ...config, repoIsOnboarded: true };
   }
-  if (config.renovateJsonPresent || config.hasPackageJsonRenovateConfig) {
-    logger.debug('Repo has been configured');
+  if (config.renovateJsonPresent) {
+    logger.debug('Repo has renovate.json');
     return { ...config, repoIsOnboarded: true };
   }
+  config.onboardingBranch = `${config.branchPrefix}configure`;
   const pr = await config.api.findPr(
-    `${config.branchPrefix}configure`,
+    config.onboardingBranch,
     'Configure Renovate'
   );
+  if (pr && pr.isClosed) {
+    logger.debug('Found closed Configure Renovate PR');
+    return { ...config, repoIsOnboarded: true };
+  }
   if (pr) {
-    logger.debug(`Found existing onboarding PR#${pr.number}`);
-    if (pr.isClosed) {
-      logger.debug('Found closed Configure Renovate PR');
-      return { ...config, repoIsOnboarded: true };
-    }
-    // PR exists but hasn't been closed yet
-    logger.debug(
-      `PR #${pr.displayNumber} needs to be closed to enable renovate to continue`
-    );
-    const prDetails = await config.api.getPr(pr.number);
-    if (!prDetails.canRebase) {
-      // Cannot update files if rebasing not possible
-      return { ...config, repoIsOnboarded: false };
-    }
+    logger.debug(`Found existing onboarding PR #${pr.number}`);
+  } else {
+    config = await module.exports.createOnboardingBranch(config);
   }
-  // Create or update files, then return
-  await module.exports.createBranch(config);
+  logger.debug('Merging renovate.json from onboarding branch');
+  config = await apis.mergeRenovateJson(config, config.onboardingBranch);
   return { ...config, repoIsOnboarded: false };
 }
diff --git a/test/workers/repository/__snapshots__/apis.spec.js.snap b/test/workers/repository/__snapshots__/apis.spec.js.snap
index c3c5bfe3c7e9d64465303f568be35772e09b63a4..3e22cd325917f38026889b1247d209937a387058 100644
--- a/test/workers/repository/__snapshots__/apis.spec.js.snap
+++ b/test/workers/repository/__snapshots__/apis.spec.js.snap
@@ -115,11 +115,9 @@ Array [
     "content": Object {
       "workspaces": Array [],
     },
-    "errors": Array [],
     "npmrc": "npmrc-1",
     "packageFile": "package.json",
     "packageLock": "packageLock-1",
-    "warnings": Array [],
     "yarnLock": "yarnLock-1",
     "yarnrc": "yarnrc-1",
   },
diff --git a/test/workers/repository/__snapshots__/onboarding.spec.js.snap b/test/workers/repository/__snapshots__/onboarding.spec.js.snap
index 33e6062351fe7bca14feb3e3252e298e6c75ac14..3eff54e6c81d694920115f7affa416901d4b5e35 100644
--- a/test/workers/repository/__snapshots__/onboarding.spec.js.snap
+++ b/test/workers/repository/__snapshots__/onboarding.spec.js.snap
@@ -374,7 +374,9 @@ Array [
   Array [
     Object {
       "contents": "{
-  \\"extends\\": [\\"config:js-lib\\"]
+  \\"extends\\": [
+    \\"config:js-lib\\"
+  ]
 }
 ",
       "name": "renovate.json",
@@ -384,13 +386,15 @@ Array [
 ]
 `;
 
-exports[`lib/workers/repository/onboarding getOnboardingStatus(config) commits files if existing content does not match 1`] = `
+exports[`lib/workers/repository/onboarding getOnboardingStatus(config) pins private repos 1`] = `
 Array [
   "renovate/configure",
   Array [
     Object {
       "contents": "{
-  \\"extends\\": [\\"config:js-lib\\"]
+  \\"extends\\": [
+    \\"config:js-app\\"
+  ]
 }
 ",
       "name": "renovate.json",
@@ -400,13 +404,19 @@ Array [
 ]
 `;
 
-exports[`lib/workers/repository/onboarding getOnboardingStatus(config) pins private repos 1`] = `
+exports[`lib/workers/repository/onboarding getOnboardingStatus(config) throws if no packageFiles 1`] = `[Error: no package files]`;
+
+exports[`lib/workers/repository/onboarding getOnboardingStatus(config) uses base + docker + meteor 1`] = `
 Array [
   "renovate/configure",
   Array [
     Object {
       "contents": "{
-  \\"extends\\": [\\"config:js-app\\"]
+  \\"extends\\": [
+    \\"config:base\\",
+    \\":meteor\\",
+    \\":docker\\"
+  ]
 }
 ",
       "name": "renovate.json",
diff --git a/test/workers/repository/apis.spec.js b/test/workers/repository/apis.spec.js
index 0f574b4bc90c56b1a26f41191dbc25c86b425c52..b6b2173b9016d58af1ce1b2dcf44413f4a393c34 100644
--- a/test/workers/repository/apis.spec.js
+++ b/test/workers/repository/apis.spec.js
@@ -369,6 +369,7 @@ describe('workers/repository/apis', () => {
       expect(res.packageFiles).toEqual([]);
     });
     it('includes files with content', async () => {
+      config.repoIsOnboarded = true;
       config.api.getFileContent.mockReturnValueOnce(
         JSON.stringify({
           renovate: {},
diff --git a/test/workers/repository/index.spec.js b/test/workers/repository/index.spec.js
index 3edb86e43ffd4847889c81098153a94c1ca53a95..511c6eb95df882251921ae3c67f98a2023729f61 100644
--- a/test/workers/repository/index.spec.js
+++ b/test/workers/repository/index.spec.js
@@ -101,7 +101,7 @@ describe('workers/repository', () => {
         ...{ packageFiles: [] },
       }));
       await repositoryWorker.renovateRepository(config);
-      expect(onboarding.getOnboardingStatus.mock.calls.length).toBe(0);
+      expect(apis.resolvePackageFiles.mock.calls.length).toBe(0);
       expect(config.logger.error.mock.calls.length).toBe(0);
     });
     it('does not skip repository if package.json', async () => {
@@ -265,5 +265,18 @@ describe('workers/repository', () => {
       await repositoryWorker.renovateRepository(config);
       expect(config.logger.error.mock.calls.length).toBe(0);
     });
+    it('handles special no package files error', async () => {
+      apis.initApis.mockImplementationOnce(() => {
+        // Create a new object, that prototypically inherits from the Error constructor
+        function MyError() {
+          this.message = 'no package files';
+        }
+        MyError.prototype = Object.create(Error.prototype);
+        MyError.prototype.constructor = MyError;
+        throw new MyError();
+      });
+      await repositoryWorker.renovateRepository(config);
+      expect(config.logger.error.mock.calls.length).toBe(0);
+    });
   });
 });
diff --git a/test/workers/repository/onboarding.spec.js b/test/workers/repository/onboarding.spec.js
index 8b432bacf3ec5e6672cdc4173cd315d39a83a18b..8132c0151061c316ea795f90053eea7282e60d36 100644
--- a/test/workers/repository/onboarding.spec.js
+++ b/test/workers/repository/onboarding.spec.js
@@ -1,4 +1,5 @@
 const onboarding = require('../../../lib/workers/repository/onboarding');
+const apis = require('../../../lib/workers/repository/apis');
 const logger = require('../../_fixtures/logger');
 const defaultConfig = require('../../../lib/config/defaults').getConfig();
 
@@ -225,8 +226,10 @@ describe('lib/workers/repository/onboarding', () => {
       config.api = {
         commitFilesToBranch: jest.fn(),
         createPr: jest.fn(() => ({ displayNumber: 1 })),
+        findFilePaths: jest.fn(() => []),
         findPr: jest.fn(),
         getFileContent: jest.fn(),
+        getFileJson: jest.fn(() => ({})),
         getPr: jest.fn(() => {}),
         getCommitMessages: jest.fn(),
       };
@@ -256,17 +259,8 @@ describe('lib/workers/repository/onboarding', () => {
       expect(config.api.findPr.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
     });
-    it('commits files if pr is not closed and is rebaseable', async () => {
-      config.api.findPr.mockReturnValueOnce({});
-      config.api.getPr.mockReturnValueOnce({ canRebase: true });
-      const res = await onboarding.getOnboardingStatus(config);
-      expect(res.repoIsOnboarded).toEqual(false);
-      expect(config.api.findPr.mock.calls.length).toBe(1);
-      expect(config.api.commitFilesToBranch.mock.calls.length).toBe(1);
-    });
-    it('skips file update if existing pr is not rebaseable', async () => {
-      config.api.findPr.mockReturnValueOnce({});
-      config.api.getPr.mockReturnValueOnce({ canRebase: false });
+    it('skips commit files and returns false if open pr', async () => {
+      config.api.findPr.mockReturnValueOnce({ isClosed: false });
       const res = await onboarding.getOnboardingStatus(config);
       expect(res.repoIsOnboarded).toEqual(false);
       expect(config.api.findPr.mock.calls.length).toBe(1);
@@ -287,21 +281,32 @@ describe('lib/workers/repository/onboarding', () => {
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0]).toMatchSnapshot();
     });
-    it('commits files if existing content does not match', async () => {
-      config.api.getFileContent.mockReturnValueOnce('some-different-content');
+    it('uses base + docker + meteor', async () => {
+      apis.detectPackageFiles = jest.fn(input => ({
+        ...input,
+        packageFiles: [{}, {}],
+        types: {
+          meteor: true,
+          docker: true,
+        },
+      }));
       const res = await onboarding.getOnboardingStatus(config);
       expect(res.repoIsOnboarded).toEqual(false);
       expect(config.api.findPr.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls.length).toBe(1);
       expect(config.api.commitFilesToBranch.mock.calls[0]).toMatchSnapshot();
     });
-    it('skips commit files if existing content matches', async () => {
-      const existingContent = `{\n  "extends": ["config:js-lib"]\n}\n`;
-      config.api.getFileContent.mockReturnValueOnce(existingContent);
-      const res = await onboarding.getOnboardingStatus(config);
-      expect(res.repoIsOnboarded).toEqual(false);
-      expect(config.api.findPr.mock.calls.length).toBe(1);
-      expect(config.api.commitFilesToBranch.mock.calls.length).toBe(0);
+    it('throws if no packageFiles', async () => {
+      apis.detectPackageFiles = jest.fn(input => ({
+        ...input,
+      }));
+      let e;
+      try {
+        await onboarding.getOnboardingStatus(config);
+      } catch (err) {
+        e = err;
+      }
+      expect(e).toMatchSnapshot();
     });
   });
 });