diff --git a/lib/manager/jenkins/__fixtures__/empty.txt b/lib/manager/jenkins/__fixtures__/empty.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lib/manager/jenkins/__fixtures__/plugins.txt b/lib/manager/jenkins/__fixtures__/plugins.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a2a8b2f1b4fe16fc7866496fafab2eadae4384ef
--- /dev/null
+++ b/lib/manager/jenkins/__fixtures__/plugins.txt
@@ -0,0 +1,8 @@
+email-ext:1.2.3
+
+apache-httpcomponents-client-4-api:4.4.10-2.0 # comment
+authentication-tokens:1.2
+blueocean:1.21.0 # another comment
+#blueocean:1.22.0
+
+# this line is completely ignored
diff --git a/lib/manager/jenkins/__snapshots__/extract.spec.ts.snap b/lib/manager/jenkins/__snapshots__/extract.spec.ts.snap
new file mode 100644
index 0000000000000000000000000000000000000000..c2b0d7e64200970c0fa95b67b578e4df881411bf
--- /dev/null
+++ b/lib/manager/jenkins/__snapshots__/extract.spec.ts.snap
@@ -0,0 +1,30 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`manager/jenkins/extract extractPackageFile() extracts multiple image lines 1`] = `
+Array [
+  Object {
+    "currentValue": "1.2.3",
+    "datasource": "jenkins-plugins",
+    "depName": "email-ext",
+    "versioning": "docker",
+  },
+  Object {
+    "currentValue": "4.4.10-2.0",
+    "datasource": "jenkins-plugins",
+    "depName": "apache-httpcomponents-client-4-api",
+    "versioning": "docker",
+  },
+  Object {
+    "currentValue": "1.2",
+    "datasource": "jenkins-plugins",
+    "depName": "authentication-tokens",
+    "versioning": "docker",
+  },
+  Object {
+    "currentValue": "1.21.0",
+    "datasource": "jenkins-plugins",
+    "depName": "blueocean",
+    "versioning": "docker",
+  },
+]
+`;
diff --git a/lib/manager/jenkins/extract.spec.ts b/lib/manager/jenkins/extract.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..348e5a60c703bd43706dfb02ff9dce0db8525302
--- /dev/null
+++ b/lib/manager/jenkins/extract.spec.ts
@@ -0,0 +1,28 @@
+import { readFileSync } from 'fs';
+import { getName } from '../../../test/util';
+import { extractPackageFile } from './extract';
+
+const pluginsFile = readFileSync(
+  'lib/manager/jenkins/__fixtures__/plugins.txt',
+  'utf8'
+);
+
+const pluginsEmptyFile = readFileSync(
+  'lib/manager/jenkins/__fixtures__/empty.txt',
+  'utf8'
+);
+
+describe(getName(__filename), () => {
+  describe('extractPackageFile()', () => {
+    it('returns empty list for an empty file', () => {
+      const res = extractPackageFile(pluginsEmptyFile);
+      expect(res.deps).toHaveLength(0);
+    });
+
+    it('extracts multiple image lines', () => {
+      const res = extractPackageFile(pluginsFile);
+      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toHaveLength(4);
+    });
+  });
+});
diff --git a/lib/manager/jenkins/extract.ts b/lib/manager/jenkins/extract.ts
new file mode 100644
index 0000000000000000000000000000000000000000..90206ebe7f349d30f3421131d32d67b1491e7c76
--- /dev/null
+++ b/lib/manager/jenkins/extract.ts
@@ -0,0 +1,28 @@
+import * as datasourceJenkins from '../../datasource/jenkins-plugins';
+import { logger } from '../../logger';
+import * as dockerVersioning from '../../versioning/docker';
+import { PackageDependency, PackageFile } from '../common';
+
+export function extractPackageFile(content: string): PackageFile | null {
+  logger.trace('jenkins.extractPackageFile()');
+  const deps: PackageDependency[] = [];
+  const regex = /^\s*(?<depName>[\d\w-]+):(?<currentValue>[^#\s]+).*$/;
+
+  for (const line of content.split('\n')) {
+    const match = regex.exec(line);
+
+    if (match) {
+      const { depName, currentValue } = match.groups;
+      const dep: PackageDependency = {
+        datasource: datasourceJenkins.id,
+        versioning: dockerVersioning.id,
+        depName,
+        currentValue,
+      };
+
+      deps.push(dep);
+    }
+  }
+
+  return { deps };
+}
diff --git a/lib/manager/jenkins/index.ts b/lib/manager/jenkins/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c33e432967973dbe7130fe39633d02cd0d5eb986
--- /dev/null
+++ b/lib/manager/jenkins/index.ts
@@ -0,0 +1,5 @@
+export { extractPackageFile } from './extract';
+
+export const defaultConfig = {
+  fileMatch: ['(^|/)plugins\\.txt'],
+};
diff --git a/lib/manager/jenkins/readme.md b/lib/manager/jenkins/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..6c500dde4089acbe3c13cfcc3a065f0c6b36286d
--- /dev/null
+++ b/lib/manager/jenkins/readme.md
@@ -0,0 +1,10 @@
+The Jenkins manager suppports the following format of the plugin list:
+
+```text
+plugin1:1.2.3
+plugin2:4.5 # this is a comment
+
+# this line is ignored
+```
+
+There's no strict specification on the name of the files, but usually it's `plugins.txt`