apocas / dockerode-compose Goto Github PK
View Code? Open in Web Editor NEWdocker-compose in Node.js using dockerode
License: Apache License 2.0
docker-compose in Node.js using dockerode
License: Apache License 2.0
I'm using the following Dockerfile inside of a nodejs repository.
# Pull base image
FROM node:latest
# Set working directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm install
# Copy app files
COPY . .
# Start the app
EXPOSE 3000
# Run the app
CMD [ "npm", "start" ]
The COPY package*.json ./
command causes the compose.up() function to fail due to the way source files are configured in serviceTools.js
dockerode-compose/lib/servicesTools.js
Lines 650 to 658 in 7875946
According to the dockerode docs https://github.com/apocas/dockerode#building-an-image, the value of src must include ALL files that will be referenced in a command such as COPY. Is there a workaround or plan to include files other than Dockerfile in the source files array?
Coming from the TypeScript world and trying to consume dockerode-compose in a project that uses TypeScript, I see a lot of benefits on translating the code into TypeScript (e.g. catching ImplicitReturns and getting full support for function input, etc.)
If the owners find this is useful, I can take a stab at converting the project to TypeScript
Hi, first of all I want to say thanks for creating this awesome tool for dockerode which I think a lot of people will love!
I am having an issue with using dockerode-compose up() promise. Basically when creating the docker-compose instance seems to work fine but using .up() method causes promise rejection.
Upon doing. this:
var composer = new DockerodeCompose(docker, './docker-compose.yml', req.body.name);
(async () => {
console.log(composer.file, composer.projectName)
composer.up().catch(err => console.log("ERRROR", err))
})();
I would guess the docker api returns this from socket:
Error: (HTTP code 400) unexpected - No command specified
at /Users/ivan-pavao-lozancic/Desktop/git-repo/fuel-instance-creator/ic-backend/node_modules/docker-modem/lib/modem.js:315:17
at getCause (/Users/ivan-pavao-lozancic/Desktop/git-repo/fuel-instance-creator/ic-backend/node_modules/docker-modem/lib/modem.js:345:7)
at Modem.buildPayload (/Users/ivan-pavao-lozancic/Desktop/git-repo/fuel-instance-creator/ic-backend/node_modules/docker-modem/lib/modem.js:314:5)
at IncomingMessage.<anonymous> (/Users/ivan-pavao-lozancic/Desktop/git-repo/fuel-instance-creator/ic-backend/node_modules/docker-modem/lib/modem.js:286:14)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (internal/streams/readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
reason: undefined,
statusCode: 400,
json: { message: 'No command specified' }
}
Please keep in mind the docker-compose.yml file is present and working when executing from shell and project name also. I am really clueless about how to solve this. Please let me know if you need more details :)
Once again thank you so much for your commitment and great work! ๐
dockerode-compose will not work if docker-compose.yml
file have small section networks
:
version: "3"
services:
...
networks:
- any_net
networks:
any_net:
driver: "bridge"
ipam:
config:
- subnet: "172.143.0.0/16"
This configuration generates an error:
Error: (HTTP code 400) unexpected - invalid JSON: json: cannot unmarshal object into Go struct field IPAM.IPAM.Config of type []network.IPAMConfig
This is due to incorrect parameters being generated for docker.createNetwork()
in the lib/network.js
file
For example :
line 49:
var opts = {
Name: projectName + '_' + networkName,
Driver: network.driver,
DriverOpts: network.driver_opts, //unsetted in docker-compose.yml
Labels: {
...network.labels,
...{
'com.docker.compose.network': 'default',
'com.docker.compose.project': projectName,
},
},
Attachable: network.attachable, //may be unsetted in docker-compose.yml
EnableIPv6: network.enable_ipv6, //may be unsetted in docker-compose.yml
Internal: network.internal, //may be unsetted in docker-compose.yml
CheckDuplicate: true,
};
line 69
opts.IPAM = {
Driver: network.ipam.driver, //may be unsetted in docker-compose.yml
Options: network.ipam.options, //may be unsetted in docker-compose.yml
};
line 74
opts.IPAM['Config'] = {
Subnet: network.ipam.config.subnet, // network.ipam.config - its an array! .subnet may be unsetted
IPRange: network.ipam.config.ip_range, // network.ipam.config - its an array! .ip_range may be unsetted
Gateway: network.ipam.config.gateway, // network.ipam.config - its an array! .gateway may be unsetted
AuxAddress: network.ipam.config.aux_addresses, // network.ipam.config - its an array! .aux_addresses may be unsetted
};
For the correct parameters for creating a network with Dockerode, see the Docerode tests:
Hello everyone,
Is there a possibility to run docker-compose up method with detached mode ?
Thank you
currently if no network is specified each container automatically joins the default network.
it makes container isolation impossible!
https://github.com/apocas/dockerode-compose/blob/main/lib/services.js#L173-L182
if (service.networks !== undefined) {
servicesTools.buildNetworks(projectName, serviceName, service.networks, networksToAttach, opts, recipe.networks);
} else {
opts.HostConfig.NetworkMode = projectName + '_default';
opts.NetworkingConfig.EndpointsConfig[projectName + '_default'] = {
IPAMConfig: null,
Links: null,
Aliases: [serviceName],
};
}
on possible solution would be to:
services:
container1:
image: <some image>
networks:
default: {}
networks:
default:
external: true
name: none
we make sure "service.networks" is not undefined and to add some speacial rule to "buildNetworks()", so if we overwrite the default the container and it will join the "none" network and would be isolated!
unfortunately i dont know if "--icc=false" is accessible via the api!?
When I compose up, below error occur.
Error: (HTTP code 400) unexpected - create wordpress_./myTheme: "wordpress_./myTheme" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path
Perhaps, "/" can't be used in local volume string.
docker-compose.yml
version: "3.9"
services:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
volumes_from:
- db:ro
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DEBUG: 1
WP_ENVIRONMENT_TYPE: local
volumes:
- ./myTheme:/var/www/html/wp-content/themes/myTheme
volumes:
db_data: {}
wordpress_data: {}
When using the below compose file, the service is not reachable on the defined port. However when I use docker-compose the service is reachable.
version: '3'
services:
wiremock:
image: 'holomekc/wiremock-gui:latest'
container_name: my_wiremock
ports:
- '8088:8080'
volumes:
- 'wmdata:/home/wiremock/storage'
environment:
WIREMOCK_OPTIONS: '--max-request-journal=1000,--local-response-templating,--root-dir=/home/wiremock/storage'
Any thoughts, to why.
I am trying to run this code but it's not working,
I can run docker-compose.yml with docker cli without any problem.
var Dockerode = require('dockerode');
var DockerodeCompose = require('dockerode-compose');
var docker = new Dockerode();
var compose = new DockerodeCompose(docker, 'docker-compose.yml', 'test_hello');
(async () => {
await compose.pull();
var state = await compose.up();
console.log(state);
})();
if I do like that
await compose.pull(null, { verbose: true });
it's working.
what is the problem ??
I see the docker-compose down
functionality was added back in February, but doesn't seem to be in the latest release in NPM (1.2.2
). Would it be possible to have to latest version of this fantastic library released?
Would be great to have TypeScript types similar to the other dockerode projects (@types/dockerode & @types/docker-modem).
Pretty minor, so just a heads up.
Services just assumes the volume is described with short syntax and tries to split a string by ':'
If the dockerfile defines the container name, then the calling services.down() fails as the down method looks for a container named with the following pattern:
projectName + '_' + serviceName + '_1'
In such case, the down method() should use the container_name defined in the dockerfile instead of its own naming format.
Hello!
The idea of implementing the docker-compose spec via the Docker API, instead of wrapping the execution of a binary and parsing text output sounds excellent!
However I notice the last commit was ~1 year ago, is this project still being worked on?
Hello,
It seems that if we need an auth to pull the image in the compose file in compose.js, we need to have possibility to pass options.
So my fix proposal is simple :
async pull(serviceN, options) {
// ...
var streami = await this.docker.pull(service.image, options);
// ...
}
(i'm not familiar with fork system but i mean it's just an add of 8 chars)
Regards,
Cannot read properties of undefined (reading 'indexOf')
Here's my docker-compose file:
version: '3'
services:
lucidlink:
container_name: lucidlink
build:
context: ../../
dockerfile: Dockerfile
target: lucidlink
ports:
- "7778:7778"
Init code:
const dockerCompose = new DockerodeCompose(this.docker, this.options.dockerComposePath, 'wats-test');
await dockerCompose.pull();
await dockerCompose.up({
verbose: true
});
Just wondering about the status of this project to evaluate it for use in my project. I love the dockerode
project for its large feature set, but the features of dockerode-compose
lack a wide range of commands to interact with docker-compose.
What are the plans for this project? Will it remain a less relevant side project of dockerode
or are there plans to push progress forward in the near future?
Thanks
I have the following compose file:
services:
web:
build: .
ports:
- "8000:8000"
environment:
DB_HOST: db
db:
image: "postgres"
environment:
POSTGRES_PASSWORD: postgres
Running compose.pull()
triggers the following error:
node_modules/dockerode/lib/util.js:48
var digestPos = input.indexOf('@');
^
TypeError: Cannot read properties of undefined (reading 'indexOf')
at module.exports.parseRepositoryTag (node_modules/dockerode/lib/util.js:48:25)
at Docker.pull (node_modules/dockerode/lib/docker.js:1457:23)
at Compose.pull (node_modules/dockerode-compose/compose.js:69:41)
I suspect this is related to this piece of code:
Lines 62 to 69 in 7875946
At line 69, the code assumes there's always an image
property in the service. However, as shown in my compose file, there's no such property in the web
service.
This should be easily fixable by skipping services that don't provide an image.
The buildNetworks
function in the latest release of dockerode-compose
(v1.3.1) is broken.
It seems there was a refactoring in commit dea731526da26549562c242a8724692eb7a89144
back in May 2021 that broke buildNetworks
in serviceTools.js.
In the first conditional (if serviceNetworks
is an array):
projectName
is not available/in scope anymore in this new location at line 416serviceName
on line 425opts
object at line 427So calling Compose#up
on a docker-compose.yml
that has services with networks defined causes the operation to fail, when it gets to services.js line 168.
Hey,
i am starting two compose-files with dockerode-compose which behave not the same way like if i started them from commandline.
version: '3'
services:
container1:
hostname: container1
image: nodered/node-red:latest
environment:
- TZ=Europe/Amsterdam
ports:
- "8081:1880"
networks:
net1: {}
networks:
net1:
external: true
name: transfer
version: '3'
services:
container2:
hostname: container2
image: nodered/node-red:latest
environment:
- TZ=Europe/Amsterdam
ports:
- "8082:1880"
networks:
net1: {}
networks:
net1:
external: true
name: transfer
const Docker = require('dockerode')
const DockerodeCompose = require('dockerode-compose');
const socketPath = '/var/run/docker.sock'
const docker = new Docker({socketPath: socketPath})
const service1 = new DockerodeCompose(docker, "./service1/docker-compose.yaml", "service1")
const service2 = new DockerodeCompose(docker, "./service2/docker-compose.yaml", "service2")
;(async () => {
await docker.createNetwork({
"Name": "transfer"
})
await Promise.all([
service1.up(),
service2.up()
])
})()
;
[
"uncaughtException",
"unhandledRejection"
].forEach(event => {
process.on(event, (...args: any[]) => {
console.error(`Something went wrong fix your application :P \n`, args)
process.exit(1)
})
})
Something went wrong fix your application :P
[
Error: (HTTP code 404) no such container - network service1_net1 not found
at /home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:343:17
at getCause (/home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:373:7)
at Modem.buildPayload (/home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:342:5)
at IncomingMessage.<anonymous> (/home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:310:16)
at IncomingMessage.emit (node:events:526:35)
at IncomingMessage.emit (node:domain:489:12)
at endReadableNT (node:internal/streams/readable:1359:12)
at processTicksAndRejections (node:internal/process/task_queues:82:21) {
reason: 'no such container',
statusCode: 404,
json: { message: 'network service1_net1 not found' }
},
Promise {
<rejected> Error: (HTTP code 404) no such container - network service1_net1 not found
at /home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:343:17
at getCause (/home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:373:7)
at Modem.buildPayload (/home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:342:5)
at IncomingMessage.<anonymous> (/home/andreas/Playground/dockerode_compose_test/node_modules/docker-modem/lib/modem.js:310:16)
at IncomingMessage.emit (node:events:526:35)
at IncomingMessage.emit (node:domain:489:12)
at endReadableNT (node:internal/streams/readable:1359:12)
at processTicksAndRejections (node:internal/process/task_queues:82:21) {
reason: 'no such container',
statusCode: 404,
json: [Object]
}
}
]
@types/dockerode-compose library please :)
I want to use process.env for port mapping.
version: '3.9'
services:
wordpress_with_theme_db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress_with_theme_wordpress:
depends_on:
- wordpress_with_theme_db
image: wordpress:latest
ports:
- '${HOST_PORT_FOR_COMPOSE}:80'
restart: always
volumes_from:
- wordpress_with_theme_db:ro
environment:
WORDPRESS_DB_HOST: wordpress_with_theme_db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
below error occur when compose up.
Error: (HTTP code 400) unexpected - invalid port specification: "${HOST_PORT_FOR_COMPOSE}"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.