How to get started with dockerode - docker

I am planning on running my app in docker. I want to dynamically start, stop, build, run commands, ... on docker container. I found a tool named dockerode. Here is the project repos. This project has doc, but I am not understanding very well. I would like to understand few thing. This is how to build an image
docker.createContainer({Image: 'ubuntu', Cmd: ['/bin/bash'], name: 'ubuntu-test'}, function (err, container) {
container.start(function (err, data) {
//...
});
});
It is possible to make RUN apt-get update like when we use Dockerfile, or RUN ADD /path/host /path/docker during build ? how to move my app into container after build ?
Let's see this code :
//tty:true
docker.createContainer({ /*...*/ Tty: true /*...*/ }, function(err, container) {
/* ... */
container.attach({stream: true, stdout: true, stderr: true}, function (err, stream) {
stream.pipe(process.stdout);
});
/* ... */
}
How can I know how many params I can put here { /*...*/ Tty: true /*...*/ } ?
Has someone tried this package too ? please help me to start with.

Dockerode is just a node wrapper for Docker API. You can find all params you can use for each command in api docs.
For example docker.createContainer will call POST /containers/create (docs are here: https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/create-a-container)
Check files in lib folder of dockerode repo to see what api command is wrapped for each dockerode method.

Related

Testcafe docker run shows error on specifying global request hook in .testcaferc.js file

I get an error The hook (object) is not of expected type (RequestHook subclass).
I notice this error when I run the test using the testcafe docker image.
I use the command:
docker run -v //c/testproject:/mytests -it testcafe/testcafe "chromium:headless:emulation:device=iPhone X" /mytests/testone.js --config-file /mytests/.testcaferc.js
I have the following code in my .testcaferc.js file
const { RequestMock} = require("testcafe");
const mock = RequestMock()
.onRequestTo('https://a360cdn.azureedge.net/javascript/a360.consent.default.js')
.respond(null, 200)
module.exports = {
hooks: {
request: [mock]
},
browsers: "chromium:headless:emulation:device=iPhone X",
skipJsErrors: true,
skipUncaughtErrors: true,
};
My test file has the following code:
import {Selector} from 'testcafe'
fixture `fixture 1`
test.page(`https://www.chileautos.cl/`)(`First test`, async t => {
await t.expect(Selector(`div.element-id`).exists).ok()
});
And my package.json is as below:
{
"scripts": {
"b": "testcafe ./testone.js"
},
"dependencies": {
"testcafe": "^2.0.1"
}
}
Note: When i run my test without testcafe docker image, the mock request works fine.
For example, I can see the test running good when I run the test using npm run b
But if I run the test using the following command:
docker run -v //c/testproject:/mytests -it testcafe/testcafe "chromium:headless:emulation:device=iPhone X" /mytests/testone.js --config-file /mytests/.testcaferc.js
I see the following error:
ERROR Cannot prepare tests due to the following error:
The hook (object) is not of expected type (RequestHook subclass).
Type "testcafe -h" for help.
You can use a mounted folder as a path only for tests. You need to move the configuration file to the root folder or create a custom Docker image that extends the basic TestCafe Docker image and allows specifying configuration file.

Cannot get webpack --watch or dev server to work using Lando to run a local Drupal environment

I've scoured the internet and have bits and pieces but nothing is coming together for me. I have a local Drupal environment running with Lando. I've successfully installed and configured webpack. Everything is working except when I try to watch or hot reload.
When I run lando npm run build-dev (that currently uses webpack --watch I can see my changes compiled successfully into the correct folder. However, when I refresh my Drupal site, I do not see that changes. The only time I see my updated JS changes are when I run lando drush cr to clear cache. Same things are happening when I try to configure the webpack-dev-server. I can get everything to watch for changes and compile correctly but I cannot get my browser to reload my files, they stay cached. I'm at a loss.
I've tried configuring a proxy in my .lando.yml , and have tried different things with the config options for devServer. I'm just not getting a concise answer, and I just don't have the knowledge to understand exactly what is happening. I believe it has to do with Docker containers not being exposed to webpack (??) but I don't understand how to configure this properly.
These are the scripts I have set up in my package.json , build outputs my production ready files into i_screamz/js/dist, build-dev starts a watch and compiles non-minified versions to i_screamz/js/dist-dev - start I have in here from trying to get the devServer to work. I'd like to get webpack-dev-server running as I'd love to have reloading working.
"scripts": {
"start": "npm run build:dev",
"build:dev": "webpack --watch --progress --config webpack.config.js",
"build": "NODE_ENV=production webpack --progress --config webpack.config.js"
},
This is my webpack.config.js - no sass yet, this is just a working modular js build at this point.
const path = require("path");
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const isDevMode = process.env.NODE_ENV !== 'production';
module.exports = {
mode: isDevMode ? 'development' : 'production',
devtool: isDevMode ? 'source-map' : false,
entry: {
main: ['./src/index.js']
},
output: {
filename: isDevMode ? 'main-dev.js' : 'main.js',
path: isDevMode ? path.resolve(__dirname, 'js/dist-dev') : path.resolve(__dirname, 'js/dist'),
publicPath: '/web/themes/custom/[MYSITE]/js/dist-dev'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
},
plugins: [
new BrowserSyncPlugin({
proxy: {
target: 'http://[MYSITE].lndo.site/',
proxyReq: [
function(proxyReq) {
proxyReq.setHeader('Cache-Control', 'no-cache, no-store');
}
]
},
open: false,
https: false,
files: [
{
match: ['**/*.css', '**/*.js'],
fn: (event, file) => {
if (event == 'change') {
const bs = require("browser-sync").get("bs-webpack-plugin");
if (file.split('.').pop()=='js') {
bs.reload();
} else {
bs.stream();
}
}
}
}
]
}, {
// prevent BrowserSync from reloading the page
// and let Webpack Dev Server take care of this
reload: false,
injectCss: true,
name: 'bs-webpack-plugin'
}),
],
watchOptions: {
aggregateTimeout: 300,
ignored: ['**/*.woff', '**/*.json', '**/*.woff2', '**/*.jpg', '**/*.png', '**/*.svg', 'node_modules'],
}
};
And here is the config I have setup in my .lando.yml - I did have the proxy key in here but it's been removed as I couldn't get it setup right.
name: [MYSITE]
recipe: pantheon
config:
framework: drupal8
site: [MYPANTHEONSITE]
services:
node:
type: node
build:
- npm install
tooling:
drush:
service: appserver
env:
DRUSH_OPTIONS_URI: "http://[MYSITE].lndo.site"
npm:
service: node
settings.local.php
<?php
/**
* Disable CSS and JS aggregation.
*/
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;
I've updated my code files above to reflect reflect a final working setup with webpack. The main answer was a setting in
/web/sites/default/settings.local.php
**Disable CSS & JS aggregation. **
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;
I found a working setup from saschaeggi and just tinkered around until I found this setting. So thank you! I also found more about what this means here. This issue took me way longer than I want to admit and it was so simple. I don't know why the 'Disabling Caching css/js aggregation' page never came up when I was furiously googling a caching issue. Hopefully this answer helps anyone else in this very edge case predicament.
I have webpack setup within my theme root folder with my Drupal theme files. I run everything with Lando, including NPM. I found a nifty trick to switch the dist-dev and dist libraries for development / production builds from thinkshout.
I should note my setup does not include hot-reloading but I can at least compile my files and refresh immediately and see my changes. The issue I was having before is that I would have to stop my watches to drush cr and that workflow was ridiculous. I've never gotten hot reloading to work with with either BrowserSync or Webpack Dev Server and I might try to again but I need to move on with my life at this point.
I've also note included sass yet, so these files paths will change to include compilation and output for both .scss and .js files but this is the basic bare min setup working.

Using docker buildkit's go client, how do I add an entrypoint?

For reasons of precise control of our builds we are using the new buildkit (moby/buildkit) directly. So without a Dockerfile.
We are creating a script like this example: https://github.com/moby/buildkit/blob/master/examples/buildkit0/buildkit.go
While it works (great), documentation is lacking.
How do I add an entrypoint? (i.e. default command to run)
and
How do I set the default workdir for when the container starts?
and
How do I set which ports to expose?
LLB layer in BuildKit does not deal with images. It's one specific exporter for the build result. If you use a frontend like Dockerfile, it will prepare an image config for the exporter as well as invoking the LLB build. If you are using LLB directly you need to create an image config yourself as well. If you use buildctl this would look something like buildctl build --output 'type=docker,name=test,"containerimage.config={""Config"":{""Cmd"":[""bash""]}}"'
In Go API you would pass this with ExportEntry https://godoc.org/github.com/moby/buildkit/client#ExportEntry attributes. The image format is documented at https://github.com/moby/moby/blob/master/image/spec/v1.2.md .
Note that you don't need to fill RootFS in the image config. BuildKit will fill this in automatically. More background info https://github.com/moby/buildkit/issues/1041
Tõnis answer actually helped me solve it. I'm also posting here for an example for how to do it.
config := Config{
Cmd: cmd,
WorkingDir: "/opt/company/bin",
ExposedPorts: map[string]struct{}{
"80/tcp": {},
"8232/tcp": {},
},
Env: []string{"PATH=/opt/company/bin:" + system.DefaultPathEnv},
}
imgConfig := ImgConfig{
Config: config,
}
configStr, _ := json.Marshal(imgConfig)
Exports: []client.ExportEntry{
{
Type: "image",
Attrs: map[string]string{
"name": manifest.Tag,
"push": "true",
"push-by-digest": "false",
"registry.insecure": strconv.FormatBool(insecureRegistry),
"containerimage.config": string(configStr),
},
},
},

how to catch the exit event of process in docker

I create a process with nodejs on docker container, but I don't catch the exit event of the process, the docker version is 1.0.1, but the same code is okay on the version 0.91 of docker.
var spawn = require('child_process').spawn;
var exec = spawn('docker', 'run busybox /etc/bin/bash each hello world');
exec.on('error', function(err){
console.log(err);
});
exec.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
exec.on('exit', function(err){
console.log('exit')
});
I think the problem is in the use of spawn. The second parameter should be an array according to the nodejs docs.
In a quick test, your code launches docker without any arguments, at least on node v0.10.28.

Clarification on grunt-protractor-coverage syntax for rails app backend?

Background
I'm trying to use the grunt-protractor-coverage in my grunt script to get code coverage for protractor functional e2e tests. To get started, I utilized this tutorial, with some minor modifications and it works perfectly. Using this as a guide, I created a new gruntfile, substituting the "express" app with a rails app backend.
The Problem
When running my gruntfile, I get the following stack trace:
../dummy/node_modules/grunt-protractor-coverage/node_modules/protractor/node_modules/glob/glob.js:130
throw new Error("must provide pattern")
^
Error: must provide pattern
at new Glob (../dummy/node_modules/grunt-protractor-coverage/node_modules/protractor/node_modules/glob/glob.js:130:11)
at glob ../dummy/node_modules/grunt-protractor-coverage/node_modules/protractor/node_modules/glob/glob.js:57:11)
at Function.globSync [as sync] (../dummy/node_modules/grunt-protractor-coverage/node_modules/protractor/node_modules/glob/glob.js:76:10)
at Function.ConfigParser.resolveFilePatterns (../dummy/node_modules/grunt-protractor-coverage/node_modules/protractor/lib/configParser.js:89:26)
at Runner.run (../dummy/node_modules/grunt-protractor-coverage/node_modules/protractor/lib/runner.js:323:24)
at process.<anonymous> (../dummy/node_modules/grunt-protractor-coverage/node_modules/protractor/lib/runFromLauncher.js:32:14)
at process.EventEmitter.emit (events.js:98:17)
at handleMessage (child_process.js:318:10)
at Pipe.channel.onread (child_process.js:345:11)
[launcher] Runner Process Exited With Error Code: 8
Tracing through the code in grunt's task.js file via [node-inspector] (https://github.com/node-inspector/node-inspector), it seems there are two possible issues:
I'm missing some parameter from my config file which would correctly retrieve the files needed
There is a syntax issue
Any idea why it's throwing this error?
My Config File
protractor_coverage: {
options: {
configFile: '/usr/local/lib/node_modules/protractor/referenceConf.js', // Default config file
keepAlive: true, // If false, the grunt process stops when the test fails.
noColor: false, // If true, protractor will not use colors in its output.
coverageDir: '<%= dirs.instrumentedE2E %>',
args: {}
},
phantom: {
options: {
args: {
baseUrl: 'http://localhost:3000/',
// Arguments passed to the command
'browser': 'phantomjs'
}
}
},
chrome: {
options: {
args: {
baseUrl: 'http://localhost:3000/',
// Arguments passed to the command
'browser': 'chrome'
}
}
}
},
This error means that the plugin was unable to locate your spec files. There were a couple of bugs related to this that have been fixed in recent releases.
You'll generally want your protractorConf.js to be part of your projects. I generally put it in a directory called 'tests'.
So your options would then look like:
options: {
configFile: 'tests/protractorConf.js',
keepAlive: true, // If false, the grunt process stops when the test fails.
noColor: false, // If true, protractor will not use colors in its output.
coverageDir: '<%= dirs.instrumentedE2E %>',
args: {}
},
You could then put your specs in a 'tests/specs' directory, and in this protractorConf.js, reference them as:
specs: [
'tests/specs/**/*.spec.js',
'!**/exclude.spec.js'
],
This would get any file that ends with .spec.js in /tests/specs and any subdirectories therein, unless the file is named exclude.spec.js.
I had this issue also, for me in my protractorConf file I had to change where my path was.
I originally had
specs: [
'./e2e/**/*.spec.js'
],
which worked fine with protractor, and grunt-protractor-runner
But for some reason, the protractor-coverage, this did not run. I changed it to
specs: [
'test/e2e/**/*.spec.js'
],
and this solved my issue. Basically protractor-coverage looks at the path from the base rather then from the config file.

Resources