├── .editorconfig ├── .eslintrc ├── .gitignore ├── .travis.yml ├── README.md ├── config ├── config.html └── config.js ├── lib ├── build.js └── push.js ├── package.json ├── static └── icon.png ├── webapp.js └── worker.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # Strider Editor/IDE Settings 2 | # This file is used to promote consistent source code standards 3 | # amongst all Strider-CD contributors. 4 | # More information can be found here: http://editorconfig.org/ 5 | 6 | # General Settings 7 | root = true 8 | 9 | # Settings for all files 10 | [*] 11 | indent_style = space 12 | indent_size = 2 13 | end_of_line = lf 14 | charset = utf-8 15 | trim_trailing_whitespace = true 16 | insert_final_newline = true 17 | 18 | [*.hbs] 19 | insert_final_newline = false 20 | 21 | [*.{diff,md}] 22 | trim_trailing_whitespace = false 23 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 6, 4 | "sourceType": "script" 5 | }, 6 | "env": { 7 | "node": true, 8 | "es6": true 9 | }, 10 | "extends": "eslint:recommended", 11 | "rules": { 12 | "indent": [2, 2], 13 | "brace-style": [2, "1tbs"], 14 | "quotes": [2, "single"], 15 | "semi": [2, "always"], 16 | "comma-style": [2, "last"], 17 | "one-var": [2, "never"], 18 | "strict": [2, "global"], 19 | "prefer-template": 2, 20 | "no-console": 0, 21 | "no-use-before-define": [2, "nofunc"], 22 | "no-underscore-dangle": 0, 23 | "no-constant-condition": 0, 24 | "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], 25 | "func-style": [2, "declaration"] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | node_modules/ 3 | *~ 4 | *# 5 | .#* 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4" 4 | - "node" 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Strider Docker Build 2 | 3 | Build Docker images with Strider. Uses the standard DOCKER_HOST environment variable. You can also use DOCKER_IP and DOCKER_PORT. 4 | 5 | ## Screenshots 6 | 7 | ![](https://i.imgur.com/Sq3UefD.png) 8 | 9 | ![](https://i.imgur.com/SMfT3p3.png) 10 | 11 | 12 | ## Rationale 13 | 14 | You may be producing docker images that are highly custom to your situation. 15 | 16 | You may see no value in uploading these images to the official registry. 17 | 18 | You may need your images to build quickly and cannot wait for the registry to process your automated build. 19 | 20 | You may depend on this image for other projects tested in Strider via [strider-docker-runner](https://github.com/Strider-CD/strider-docker-runner) 21 | -------------------------------------------------------------------------------- /config/config.html: -------------------------------------------------------------------------------- 1 |

Docker Build

2 |
3 |
4 |
5 | 6 | 12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /config/config.js: -------------------------------------------------------------------------------- 1 | app.controller('DockerBuildController', ['$scope', function ($scope) { 2 | $scope.$watch('configs[branch.name].docker_build.config', function (value) { 3 | $scope.config = value; 4 | }); 5 | $scope.saving = false; 6 | $scope.save = function () { 7 | $scope.saving = true; 8 | $scope.pluginConfig('docker_build', $scope.config, function () { 9 | $scope.saving = false; 10 | }); 11 | }; 12 | }]); 13 | -------------------------------------------------------------------------------- /lib/build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const debug = require('debug')('strider-docker-build:build'); 4 | const Docker = require('dockerode'); 5 | const JSONStream = require('json-stream'); 6 | const push = require('./push'); 7 | const tar = require('tar-fs'); 8 | 9 | module.exports = function (config) { 10 | return function (context, done) { 11 | const docker = new Docker(); 12 | 13 | context.comment(`Connecting to Docker: ${process.env.DOCKER_HOST}`); 14 | 15 | const tarStream = tar.pack(context.dataDir); 16 | docker.buildImage(tarStream, { 17 | t: config.tag, 18 | q: false 19 | }, function (err, ostream) { 20 | if (err) { 21 | return done(err); 22 | } 23 | 24 | var stream = new JSONStream(); 25 | let buildErr; 26 | 27 | stream.on('data', function (data) { 28 | if (data.stream) { 29 | context.out(data.stream); 30 | } else if (data.error) { 31 | context.out(data.errorDetail.message); 32 | err = new Error(data.error); 33 | } 34 | }); 35 | 36 | stream.on('error', function (err) { 37 | debug(err); 38 | buildErr = err; 39 | }); 40 | 41 | stream.on('end', function () { 42 | if (buildErr) { 43 | return done(buildErr); 44 | } 45 | 46 | if (config.push) { 47 | push(docker, config, context, done); 48 | } else { 49 | done(); 50 | } 51 | }); 52 | 53 | ostream.pipe(stream); 54 | 55 | ostream.on('end', function () { 56 | stream.end(); 57 | }); 58 | }); 59 | }; 60 | }; 61 | -------------------------------------------------------------------------------- /lib/push.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const debug = require('debug')('strider-docker-build:push'); 4 | const JSONStream = require('json-stream'); 5 | 6 | module.exports = function (docker, config, context, done) { 7 | const image = docker.getImage(config.tag); 8 | 9 | debug('pushing..'); 10 | 11 | if (image) { 12 | image.push({authconfig: {base64:process.env.REGISTRY_AUTH}}, function (err, pstream) { 13 | if (err) { 14 | return done(err); 15 | } 16 | 17 | const pushStream = new JSONStream(); 18 | let pushErr; 19 | 20 | pushStream.on('data', function (data) { 21 | if (data.stream) { 22 | context.out(data.stream); 23 | } else if (data.error) { 24 | context.out(data.errorDetail.message); 25 | pushErr = new Error(data.error); 26 | } 27 | }); 28 | 29 | pushStream.on('error', function (err) { 30 | pushErr = err; 31 | }); 32 | 33 | pushStream.on('end', function () { 34 | done(pushErr); 35 | }); 36 | 37 | pstream.pipe(pushStream); 38 | }); 39 | } else { 40 | done('Invalid docker image'); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strider-docker-build", 3 | "version": "1.1.4", 4 | "description": "Build Docker images in Strider", 5 | "main": "worker.js", 6 | "scripts": { 7 | "lint": "eslint *.js lib", 8 | "test": "npm run lint" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/Strider-CD/strider-docker-build.git" 13 | }, 14 | "keywords": [ 15 | "strider", 16 | "docker" 17 | ], 18 | "engines": { 19 | "node": ">=4.2" 20 | }, 21 | "author": "Keyvan Fatehi", 22 | "license": "MIT", 23 | "strider": { 24 | "id": "docker_build", 25 | "type": "job", 26 | "title": "Docker Build", 27 | "webapp": "webapp.js", 28 | "worker": "worker.js", 29 | "icon": "icon.png", 30 | "config": { 31 | "controller": "DockerBuildController" 32 | } 33 | }, 34 | "dependencies": { 35 | "debug": "^2.2.0", 36 | "dockerode": "^2.0.6", 37 | "json-stream": "^0.2.1", 38 | "tar-fs": "^1.4.1" 39 | }, 40 | "devDependencies": { 41 | "eslint": "^3.2.2" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Strider-CD/strider-docker-build/8fc058a8377d1cac6cfea25b5981a0fbd435abaa/static/icon.png -------------------------------------------------------------------------------- /webapp.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | // an object that defines the schema for configuration 5 | config: { 6 | runtime: { 7 | type: String, 8 | enum: ['0.6', '0.8', '0.10', '0.11', 'stable', 'latest', 'whatever'], 9 | default: 'whatever' 10 | }, 11 | caching: { 12 | type: String, 13 | enum: ['strict', 'loose', 'none'], 14 | default: 'none' 15 | }, 16 | test: {type: String, default: 'npm test'}, 17 | globals: [{ 18 | type: String 19 | }] 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const build = require('./lib/build'); 4 | 5 | // Export. 6 | module.exports = { 7 | // Initialize the plugin for a job 8 | // config: taken from DB config extended by flat file config 9 | // job & repo: see strider-runner-core 10 | // cb(err, initialized plugin) 11 | init: function (configuration, job, context, cb) { 12 | 13 | // Get the config (if any.) 14 | var config = configuration || {}; 15 | 16 | // The options to pass to the callback. 17 | var options = {}; 18 | 19 | // Add the build instructions here. 20 | options[config.buildPhase] = build(config); 21 | 22 | // Register the plugin and it's options. 23 | cb(null, options); 24 | }, 25 | 26 | // If provided, autodetect is run if the project has *no* plugin 27 | // configuration at all. 28 | autodetect: { 29 | filename: 'Dockerfile', 30 | exists: true, 31 | language: 'docker', 32 | framework: null 33 | } 34 | }; 35 | --------------------------------------------------------------------------------