Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing platform to createContainer #721

Open
themightychris opened this issue Mar 21, 2023 · 1 comment
Open

Passing platform to createContainer #721

themightychris opened this issue Mar 21, 2023 · 1 comment

Comments

@themightychris
Copy link

themightychris commented Mar 21, 2023

I need to set platform: 'linux/amd64' when calling createContainer

The latest ContainerCreate API documents platform as a lowercase query parameter option alongside name

Screen Shot 2023-03-20 at 10 52 32 PM

I found one example in the readme of name: being mixed in with the uppercased API options when calling createContainer but I can't see in the code how that gets pulled out and passed as a query param to the underlying Docker API call like it and platform would need to

@MasterOdin
Copy link

I needed this functionality, and looking into it, when using createContainer, the function call lives at:

dockerode/lib/docker.js

Lines 43 to 77 in bb88194

Docker.prototype.createContainer = function(opts, callback) {
var self = this;
var optsf = {
path: '/containers/create?',
method: 'POST',
options: opts,
authconfig: opts.authconfig,
abortSignal: opts.abortSignal,
statusCodes: {
200: true, // unofficial, but proxies may return it
201: true,
404: 'no such container',
406: 'impossible to attach',
500: 'server error'
}
};
delete opts.authconfig;
if (callback === undefined) {
return new this.modem.Promise(function(resolve, reject) {
self.modem.dial(optsf, function(err, data) {
if (err) {
return reject(err);
}
resolve(self.getContainer(data.Id));
});
});
} else {
this.modem.dial(optsf, function(err, data) {
if (err) return callback(err, data);
callback(err, self.getContainer(data.Id));
});
}
};

where it constructs an object that is then passed to docker-modem that handles the actual communication to the docker process. The relevant code is then:

https://github.com/apocas/docker-modem/blob/e55461b7e821c49661e8410532bb46fc6d7fd212/lib/modem.js#L149-L155

In that code, if the path key in the passed options contains a ?, then it uses either opts._query || opts where for this case, the first doesn't exist, so it just uses the entire opts and appends that as a query string. So for the following example:

await docker.createContainer({
  Image: 'busybox',
  AttachStdin: false,
  AttachStdout: true,
  AttachStderr: true,
  Tty: true,
  Cmd: ['/bin/bash', '-c', 'tail -f /var/log/dmesg'],
  OpenStdin: false,
  StdinOnce: false,
  HostConfig: {
    AutoRemove: true,
  },
  name: 'foo',
  platform: 'linux/amd64',
});

Then the full path address that's called for docker ends up being:

/containers/create?Image=busybox&AttachStdin=false&AttachStdout=true&AttachStderr=true&Tty=true&Cmd=%5B%22%2Fbin%2Fbash%22%2C%22-c%22%2C%22tail%20-f%20%2Fvar%2Flog%2Fdmesg%22%5D&OpenStdin=false&StdinOnce=false&HostConfig=%7B%22AutoRemove%22%3Atrue%7D&name=foo&platform=linux%2Famd64

which we see contains the name and platform fields and are used, with the rest of the stuff being ignored by Docker itself. This does mean that the createContainer endpoint is forward facing to any new additions that get added, at the expense of sending a lot of junk on the path. An optimization might be to only include keys that start with a lowercase character, though it's possible (albeit feels unlikely) that Docker starts using query params that start with uppercase characters and now the API would need to be adjusted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants