Skip to content

Instantly share code, notes, and snippets.

@johnnyeric
Last active September 19, 2018 08:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnnyeric/7bfc3a484fce64dae3e8bc2461ab2699 to your computer and use it in GitHub Desktop.
Save johnnyeric/7bfc3a484fce64dae3e8bc2461ab2699 to your computer and use it in GitHub Desktop.
Reproduce `docker run` via Node.js - Execute one-off commands based on stdin.
/*
* To keep this code short I am not dealing with error handling, security details, etc.
*/
const run = require('./run');
(async () => {
const stdin = 'hello world';
const stdout = await run(stdin);
console.log(stdout);
})();
/*
* To keep this code short I am not dealing with error handling, security details, etc.
*/
const Dockerode = require('dockerode');
module.exports = async (stdin) => {
const docker = new Dockerode({ socketPath: '/var/run/docker.sock' });
// Create the container.
const container = await docker.createContainer({
AttachStderr: true,
AttachStdin: true,
AttachStdout: true,
Cmd: ['tr', '[a-z]', '[A-z]'],
Image: 'alpine:latest',
OpenStdin: true,
StdinOnce: true,
Tty: false,
});
// Attach the container.
const stream = await container.attach({
hijack: true,
stderr: true,
stdin: true,
stdout: true,
stream: true,
});
// Promisify stream callback response to be able to return its value.
const stdout = new Promise((resolve) => {
stream.on('data', (data) => {
// The first 8 bytes are used to define the response header.
// Please refer to https://docs.docker.com/engine/api/v1.37/#operation/ContainerAttach
const response = data && data.slice(8).toString();
resolve(response);
});
});
stream.write(stdin);
// Start the container.
await container.start();
// We need this and the hijack flag so we can signal the end of the stdin input for the container
// while still being able to receive the stdout response.
stream.end();
// We wait for container response.
await container.wait();
// We remove the container after its execution. This is the same as `--rm`.
container.remove();
return stdout;
};
@johnnyeric
Copy link
Author

It is an alternative to:

echo "hello world" | docker run -i alpine tr [a-z] [A-Z]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment