I am attempting to compile & execute a java program within a dockerode container in my node app. I am able to do this by first writing to a tmp.java
file using basic javascript and then running the following shell commands:
docker run --rm -v $PWD:/app -w /app java:8 javac tmp.java
docker run --rm -v $PWD:/app -w /app java:8 java tmp
However, I am now trying to transition to using the dockerode module and am attempting to replicate this functionality as follows (based on the example on the dockerode github):
docker.run(
'java:8',
['javac', 'tmp.java'],
{
Volumes: {
'/': {}
},
WorkingDir: '/'
},
process.stdout
)
.then(data => {
var output = data[0]
console.log('OUTPUT: ', output)
var container = data[1]
console.log(output.StatusCode)
return container.remove()
})
However, this produces no output and does not generate tmp.class
as expected when I specify Volumes
and WorkingDir
options, and when I leave out those options, I get the error: javac: file not found: tmp.java
which I assume means my volume is not mounting correctly.
Essentially, I am trying to create a temporary microcontainer, compile & run my java program in the container, and then destroy the container. Thus, I am unable to install a JDK and compile the program locally on my host system and have to essentially work exclusively within the container.
I am currently trying to use imperative Docker commands to achieve this use-case and am able to accomplish this using the cli commands above, however, I am unable to do the same thing using dockerode
for node (whether through imperative commands or using a dockerfile).
I would really appreciate any help with this!
The problem is that your directory is not mapped.
This options object is the equivalent of the options --rm -v $PWD:/app -w /app
{
HostConfig: {
AutoRemove: true,
Binds: [
`${process.cwd()}:/app`
]
},
WorkingDir: '/app'
}
AutoRemove: true
is --rm
Binds: [ `${process.cwd()}:/app` ]
is -v $PWD:/app
, with process.cwd()
as $PWD
WorkingDir: '/app'
is -w /app
I also had to change the order of the arguments, as I was getting TypeError: dest.on is not a function
. Running dockerode@3.1.0
I had to set the output stream as the 3rd argument and the option object as the 4th argument.
So the full command looked like this:
docker.run(
'java:8',
['javac', 'tmp.java'],
process.stdout,
{
HostConfig: {
AutoRemove: true,
Binds: [
`${process.cwd()}:/app`
]
},
WorkingDir: '/app'
}
)