{"id":16005,"library":"dockerode","title":"Dockerode: Node.js Docker Remote API Client","description":"Dockerode is a comprehensive Node.js module designed for programmatically interacting with the Docker Remote API. It provides a robust, feature-rich interface for managing Docker containers, images, networks, and other Docker entities, aiming to implement all features exposed by the Docker Remote API. Key differentiators include its strong emphasis on native Node.js streams for operations like logs and execs, allowing for flexible stream manipulation and demultiplexing. It treats Docker entities (containers, images, execs) as distinct objects, and offers both callback and Promise-based interfaces, catering to various asynchronous programming styles. The package maintains a steady release cadence with frequent patch updates for dependencies and minor bug fixes, with the current stable version being 4.0.10. It is built to be highly testable and closely track changes in the official Docker API, acting as a direct wrapper that passes options to Docker and returns its responses largely unchanged.","status":"active","version":"4.0.10","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/apocas/dockerode","tags":["javascript","docker","docker.io"],"install":[{"cmd":"npm install dockerode","lang":"bash","label":"npm"},{"cmd":"yarn add dockerode","lang":"bash","label":"yarn"},{"cmd":"pnpm add dockerode","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core networking and API communication layer for Dockerode.","package":"docker-modem","optional":false}],"imports":[{"note":"While CommonJS usage (`const Docker = require('dockerode');`) is common in older projects, modern TypeScript and ESM environments should use a default import for the main `Docker` class, as it's the primary export.","wrong":"import { Docker } from 'dockerode';","symbol":"Docker","correct":"import Docker from 'dockerode';"},{"note":"This is the traditional and fully supported way to import Dockerode in CommonJS environments, aligning with many examples in the official documentation.","symbol":"Docker (CommonJS)","correct":"const Docker = require('dockerode');"},{"note":"Specific TypeScript types for Docker entities (like `Container`, `Image`) and API response structures (e.g., `ImageInfo`, `ContainerInfo`) are exported directly. Consult the `index.d.ts` file for a comprehensive list of available types.","symbol":"Container/Image types","correct":"import type { Container, Image, ImageInfo, ContainerInfo } from 'dockerode';"}],"quickstart":{"code":"import Docker from 'dockerode';\nimport process from 'process';\nimport stream from 'stream';\n\nconst docker = new Docker({\n  socketPath: process.env.DOCKER_SOCKET_PATH || '/var/run/docker.sock', // Default for Linux\n  host: process.env.DOCKER_HOST || undefined, // e.g., 'http://192.168.1.10'\n  port: process.env.DOCKER_PORT || undefined, // e.g., 2375\n  version: 'v1.41' // It's recommended to specify your Docker daemon's API version\n});\n\nasync function runDockerLifecycleExample() {\n  let auxContainer: Docker.Container | undefined;\n  const imageName = 'ubuntu:latest';\n\n  try {\n    console.log(`Checking if image '${imageName}' exists...`);\n    const images = await docker.listImages({ filters: { reference: [imageName] } });\n    if (images.length === 0) {\n      console.log(`Image '${imageName}' not found locally. Pulling...`);\n      await docker.pull(imageName, {});\n      console.log(`Image '${imageName}' pulled.`);\n    }\n\n    console.log('Creating a new Ubuntu container...');\n    auxContainer = await docker.createContainer({\n      Image: imageName,\n      AttachStdin: false,\n      AttachStdout: true,\n      AttachStderr: true,\n      Tty: true,\n      Cmd: ['/bin/bash', '-c', 'echo \"Hello from Dockerode inside container!\"; sleep 3; echo \"Exiting.\"; exit 0;'],\n      OpenStdin: false,\n      StdinOnce: false\n    });\n    console.log(`Container created with ID: ${auxContainer.id}`);\n\n    console.log('Starting container...');\n    await auxContainer.start();\n    console.log('Container started. Attaching to logs...');\n\n    const logStream = await auxContainer.logs({ follow: true, stdout: true, stderr: true });\n    const outputStream = new stream.PassThrough();\n    logStream.pipe(outputStream);\n    outputStream.on('data', (chunk) => console.log(`[LOG]: ${chunk.toString('utf8').trim()}`));\n    outputStream.on('end', () => console.log('Log stream ended.'));\n\n    console.log('Waiting for container to exit...');\n    const exitResult = await auxContainer.wait();\n    console.log(`Container exited with status code: ${exitResult.StatusCode}`);\n\n    console.log('Removing container...');\n    await auxContainer.remove();\n    console.log('Container removed successfully.');\n\n  } catch (err) {\n    console.error('An error occurred during Docker operation:', err);\n    if (auxContainer) {\n      try {\n        console.error('Attempting to force-remove container due to error...');\n        await auxContainer.remove({ force: true });\n        console.error('Container force-removed.');\n      } catch (removeErr) {\n        console.error('Failed to force-remove container:', removeErr);\n      }\n    }\n    process.exit(1);\n  }\n}\n\nrunDockerLifecycleExample();","lang":"typescript","description":"This example demonstrates a full container lifecycle: pulling an image, creating, starting, attaching to logs, waiting for exit, and removing a Docker container using the Promise-based API."},"warnings":[{"fix":"Review your code for compatibility with the latest Docker API and dockerode's internal updates. Check the `docker-modem` changelog for more details on underlying network stack changes if issues arise.","message":"Major version 4.0.0 potentially introduces breaking changes due to significant dependency updates (e.g., `docker-modem`) and internal refactors. While specific API changes aren't detailed in the changelog, users upgrading from v3.x should thoroughly test their integrations. Changes might include updated types, refined method signatures, or altered default behaviors.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Upgrade `dockerode` to version 4.0.2 or later to mitigate CVE-2023-48795.","message":"Version 4.0.2 included an important security update for the underlying `SSH2` dependency (via `docker-modem`) to address CVE-2023-48795. This is a critical security fix for users connecting to Docker daemons via SSH. Ensure you are on at least v4.0.2 or a higher patched version.","severity":"breaking","affected_versions":"<4.0.2"},{"fix":"Always explicitly set the `version` option in the `Docker` constructor, e.g., `'version: 'v1.41''. Match this version to your Docker daemon's API version for optimal compatibility. You can retrieve it via `docker version --format '{{.Server.APIVersion}}'`.","message":"Incorrect Docker API versioning can lead to unexpected errors or unsupported operations. Dockerode explicitly recommends specifying the API version for Docker versions >= v1.13. Failing to set the 'version' option or setting an incompatible version will result in API errors directly from the Docker daemon.","severity":"gotcha","affected_versions":"all"},{"fix":"Implement robust stream handling, including error listeners and 'end' event listeners. Use utility functions like `demuxStream` when dealing with multiplexed Docker streams. Ensure backpressure is managed if processing large amounts of data to prevent memory issues.","message":"Dockerode leverages Node.js streams extensively for operations like container logs, exec streams, and build streams. Improperly handling or not consuming these streams can lead to resource leaks, process hangs, or unexpected behavior due to unread data or unclosed connections. Always ensure streams are properly piped, consumed, or closed.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Verify your Docker daemon is running (`sudo systemctl start docker` or `docker start`). Check your Dockerode connection configuration (e.g., `socketPath`, `host`, `port`, or the `DOCKER_HOST` environment variable) and ensure it matches your Docker setup.","cause":"The Docker daemon is not running, or `dockerode` is configured to connect to an incorrect host, port, or socket path.","error":"connect ECONNREFUSED [host]:[port]"},{"fix":"Double-check the container ID or name you are using. Ensure the container exists on the Docker daemon you are connected to by listing all containers (`docker ps -a`).","cause":"Attempting to interact with a Docker container that does not exist or whose ID/name is incorrect for the connected Docker daemon.","error":"(HTTP code 404) no such container - No such container: [container_id_or_name]"},{"fix":"Update the `version` option in your `new Docker()` constructor to match your Docker daemon's API version (e.g., 'v1.41'). You can find your daemon's API version with `docker version --format '{{.Server.APIVersion}}'`.","cause":"The Docker API version specified in dockerode's configuration (`version` option) is incompatible with the Docker daemon's API version.","error":"(HTTP code 400) bad parameter - API version is too old. Minimum is vX.Y, got vA.B"},{"fix":"Ensure all asynchronous Dockerode operations are `await`ed or chained with `.then().catch()` appropriately. Always check that the resulting entity objects are valid before attempting subsequent operations on them to prevent `undefined` references.","cause":"An operation on a Docker entity (like `container.start()`) is being called on an `undefined` object. This typically happens when a preceding asynchronous operation (e.g., `docker.createContainer()`) failed or returned `null`/`undefined` without proper error handling.","error":"Cannot read properties of undefined (reading 'start')"}],"ecosystem":"npm"}